Browse Source

AppImage: Fix webbrowser.open not opening links

There was an issue where webbrowser.open would invoke a program like
kde-open5 that loaded the systems libQt5DBus, which was not satisfied
with the AppImage's libdbus. To fix this we fork the process, unset
LD_LIBRARY_PATH and then open the URL.

fixes #5425

-----

taken from Electron-Cash/Electron-Cash@00939aafd1c8e9c1cbf56615bcf9a18db1ff15c2
dependabot/pip/contrib/deterministic-build/ecdsa-0.13.3
Axel Gembe 6 years ago
committed by SomberNight
parent
commit
fc65cdaa8a
No known key found for this signature in database GPG Key ID: B33B5F232C6271E9
  1. 5
      electrum/gui/qt/address_list.py
  2. 5
      electrum/gui/qt/contact_list.py
  3. 5
      electrum/gui/qt/history_list.py
  4. 7
      electrum/gui/qt/main_window.py
  5. 15
      electrum/gui/qt/util.py

5
electrum/gui/qt/address_list.py

@ -23,7 +23,6 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import webbrowser
from enum import IntEnum
from PyQt5.QtCore import Qt, QPersistentModelIndex, QModelIndex
@ -36,7 +35,7 @@ from electrum.plugin import run_hook
from electrum.bitcoin import is_address
from electrum.wallet import InternalAddressCorruption
from .util import MyTreeView, MONOSPACE_FONT, ColorScheme
from .util import MyTreeView, MONOSPACE_FONT, ColorScheme, webopen
class AddressList(MyTreeView):
@ -217,7 +216,7 @@ class AddressList(MyTreeView):
menu.addAction(_("Remove from wallet"), lambda: self.parent.remove_address(addr))
addr_URL = block_explorer_URL(self.config, 'addr', addr)
if addr_URL:
menu.addAction(_("View on block explorer"), lambda: webbrowser.open(addr_URL))
menu.addAction(_("View on block explorer"), lambda: webopen(addr_URL))
if not self.wallet.is_frozen_address(addr):
menu.addAction(_("Freeze"), lambda: self.parent.set_frozen_state_of_addresses([addr], True))

5
electrum/gui/qt/contact_list.py

@ -23,7 +23,6 @@
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import webbrowser
from enum import IntEnum
from PyQt5.QtGui import QStandardItemModel, QStandardItem
@ -35,7 +34,7 @@ from electrum.bitcoin import is_address
from electrum.util import block_explorer_URL
from electrum.plugin import run_hook
from .util import MyTreeView, import_meta_gui, export_meta_gui
from .util import MyTreeView, import_meta_gui, export_meta_gui, webopen
class ContactList(MyTreeView):
@ -97,7 +96,7 @@ class ContactList(MyTreeView):
menu.addAction(_("Delete"), lambda: self.parent.delete_contacts(selected_keys))
URLs = [block_explorer_URL(self.config, 'addr', key) for key in filter(is_address, selected_keys)]
if URLs:
menu.addAction(_("View on block explorer"), lambda: [webbrowser.open(u) for u in URLs])
menu.addAction(_("View on block explorer"), lambda: [webopen(u) for u in URLs])
run_hook('create_contact_menu', menu, selected_keys)
menu.exec_(self.viewport().mapToGlobal(position))

5
electrum/gui/qt/history_list.py

@ -24,7 +24,6 @@
# SOFTWARE.
import os
import webbrowser
import datetime
from datetime import date
from typing import TYPE_CHECKING, Tuple, Dict
@ -47,7 +46,7 @@ from electrum.logging import get_logger, Logger
from .util import (read_QIcon, MONOSPACE_FONT, Buttons, CancelButton, OkButton,
filename_field, MyTreeView, AcceptFileDragDrop, WindowModalDialog,
CloseButton)
CloseButton, webopen)
if TYPE_CHECKING:
from electrum.wallet import Abstract_Wallet
@ -608,7 +607,7 @@ class HistoryList(MyTreeView, AcceptFileDragDrop):
if pr_key:
menu.addAction(read_QIcon("seal"), _("View invoice"), lambda: self.parent.show_invoice(pr_key))
if tx_URL:
menu.addAction(_("View on block explorer"), lambda: webbrowser.open(tx_URL))
menu.addAction(_("View on block explorer"), lambda: webopen(tx_URL))
menu.exec_(self.viewport().mapToGlobal(position))
def remove_local_tx(self, delete_tx):

7
electrum/gui/qt/main_window.py

@ -30,7 +30,6 @@ import traceback
import json
import shutil
import weakref
import webbrowser
import csv
from decimal import Decimal
import base64
@ -85,7 +84,7 @@ from .util import (read_QIcon, ColorScheme, text_dialog, icon_path, WaitingDialo
OkButton, InfoButton, WWLabel, TaskThread, CancelButton,
CloseButton, HelpButton, MessageBoxMixin, EnterButton, expiration_values,
ButtonsLineEdit, CopyCloseButton, import_meta_gui, export_meta_gui,
filename_field, address_field, char_width_in_lineedit)
filename_field, address_field, char_width_in_lineedit, webopen)
from .installwizard import WIF_HELP_TEXT
from .history_list import HistoryList, HistoryModel
from .update_checker import UpdateCheck, UpdateCheckThread
@ -633,9 +632,9 @@ class ElectrumWindow(QMainWindow, MessageBoxMixin, Logger):
help_menu = menubar.addMenu(_("&Help"))
help_menu.addAction(_("&About"), self.show_about)
help_menu.addAction(_("&Check for updates"), self.show_update_check)
help_menu.addAction(_("&Official website"), lambda: webbrowser.open("https://electrum.org"))
help_menu.addAction(_("&Official website"), lambda: webopen("https://electrum.org"))
help_menu.addSeparator()
help_menu.addAction(_("&Documentation"), lambda: webbrowser.open("http://docs.electrum.org/")).setShortcut(QKeySequence.HelpContents)
help_menu.addAction(_("&Documentation"), lambda: webopen("http://docs.electrum.org/")).setShortcut(QKeySequence.HelpContents)
help_menu.addAction(_("&Report Bug"), self.show_report_bug)
help_menu.addSeparator()
help_menu.addAction(_("&Donate to server"), self.donate_to_server)

15
electrum/gui/qt/util.py

@ -5,6 +5,8 @@ import sys
import platform
import queue
import traceback
import os
import webbrowser
from functools import partial, lru_cache
from typing import NamedTuple, Callable, Optional, TYPE_CHECKING, Union, List, Dict
@ -878,6 +880,19 @@ def char_width_in_lineedit() -> int:
return max(9, char_width)
def webopen(url: str):
if sys.platform == 'linux' and os.environ.get('APPIMAGE'):
# When on Linux webbrowser.open can fail in AppImage because it can't find the correct libdbus.
# We just fork the process and unset LD_LIBRARY_PATH before opening the URL.
# See #5425
if os.fork() == 0:
del os.environ['LD_LIBRARY_PATH']
webbrowser.open(url)
sys.exit(0)
else:
webbrowser.open(url)
if __name__ == "__main__":
app = QApplication([])
t = WaitingDialog(None, 'testing ...', lambda: [time.sleep(1)], lambda x: QMessageBox.information(None, 'done', "done"))

Loading…
Cancel
Save