commit fc65cdaa8afb2304f2bf54a79c4a0af3d263baf4
parent 69b673b8a102d0907f96745254d659b711dab952
Author: Axel Gembe <derago@gmail.com>
Date: Fri, 5 Jul 2019 00:02:26 +0200
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
Diffstat:
5 files changed, 24 insertions(+), 13 deletions(-)
diff --git a/electrum/gui/qt/address_list.py b/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))
diff --git a/electrum/gui/qt/contact_list.py b/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))
diff --git a/electrum/gui/qt/history_list.py b/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):
diff --git a/electrum/gui/qt/main_window.py b/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)
diff --git a/electrum/gui/qt/util.py b/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"))