summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/changelog.rst1
-rw-r--r--docs/hacking/devenv.rst2
-rw-r--r--src/leap/bitmask/gui/app.py69
-rw-r--r--src/leap/bitmask/gui/app2.py7
-rw-r--r--src/leap/bitmask/gui/housekeeping.py8
-rw-r--r--ui/app/index.html12
6 files changed, 53 insertions, 46 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst
index e2067a21..aa7ac132 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -15,6 +15,7 @@ Features
Bugfixes
~~~~~~~~
- `#9171 <https://0xacab.org/leap/bitmask-dev/issues/9171>`_: fix a bug in bootstrap that avoided more than one user to login.
+- `#9165 <https://0xacab.org/leap/bitmask-dev/issues/9165>`_: deprecate pyqt5-webkit, use qtwebengine instead.
Misc
~~~~
diff --git a/docs/hacking/devenv.rst b/docs/hacking/devenv.rst
index 029d7a3a..5f7341d9 100644
--- a/docs/hacking/devenv.rst
+++ b/docs/hacking/devenv.rst
@@ -31,7 +31,7 @@ Install the system-wide dependencies. For debian-based systems::
sudo apt install build-essential python-dev python-virtualenv \
libsqlcipher-dev libssl-dev libffi-dev \
- python-pyqt5 python-pyqt5.qtwebkit
+ python-pyqt5 python-pyqt5.qtwebengine/
If you are going to be running tests that involve creating a lot of OpenPGP
keys, and specially in vms, the following is also recommended to speed up
diff --git a/src/leap/bitmask/gui/app.py b/src/leap/bitmask/gui/app.py
index a616dc3b..2033fc6d 100644
--- a/src/leap/bitmask/gui/app.py
+++ b/src/leap/bitmask/gui/app.py
@@ -25,7 +25,6 @@ import os
import platform
import signal
import sys
-import time
import webbrowser
from functools import partial
@@ -33,12 +32,12 @@ from multiprocessing import Process
from leap.bitmask.core.launcher import run_bitmaskd, pid
from leap.bitmask.gui import app_rc
+from leap.bitmask.gui.systray import WithTrayIcon
+from leap.bitmask.gui.housekeeping import cleanup, terminate, reset_authtoken
+from leap.bitmask.gui.housekeeping import get_authenticated_url
+from leap.bitmask.gui.housekeeping import NoAuthTokenError
from leap.common.config import get_path_prefix
-from .housekeeping import cleanup, terminate, reset_authtoken
-from .housekeeping import get_authenticated_url
-
-from .systray import WithTrayIcon
if platform.system() == 'Windows':
from multiprocessing import freeze_support
@@ -57,12 +56,9 @@ else:
from PyQt5.QtWidgets import QDialog
from PyQt5.QtWidgets import QMessageBox
- try:
- from PyQt5.QtWebKitWidgets import QWebView
- from PyQt5.QtWebKit import QWebSettings
- except ImportError:
- from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
- from PyQt5.QtWebEngineWidgets import QWebEngineSettings as QWebSettings
+ from PyQt5.QtWebEngineWidgets import QWebEngineView as QWebView
+ from PyQt5.QtWebEngineWidgets import QWebEngineSettings as QWebSettings
+ from PyQt5.QtWebChannel import QWebChannel
IS_WIN = platform.system() == "Windows"
DEBUG = os.environ.get("DEBUG", False)
@@ -90,8 +86,10 @@ class BrowserWindow(QWebView, WithTrayIcon):
def __init__(self, *args, **kw):
url = kw.pop('url', None)
+ first = False
if not url:
url = get_authenticated_url()
+ first = True
self.url = url
self.closing = False
@@ -100,9 +98,13 @@ class BrowserWindow(QWebView, WithTrayIcon):
self.bitmask_browser = NewPageConnector(self) if first else None
self.loadPage(self.url)
- self.proxy = AppProxy(self) if first else None
- self.frame.addToJavaScriptWindowObject(
- "bitmaskApp", self.proxy)
+ self.bridge = AppBridge(self) if first else None
+
+ if self.bridge is not None:
+ print "[+] registering python<->js bridge"
+ channel = QWebChannel(self)
+ channel.registerObject("bitmaskApp", self.bridge)
+ self.page().setWebChannel(channel)
icon = QtGui.QIcon()
icon.addPixmap(
@@ -111,26 +113,10 @@ class BrowserWindow(QWebView, WithTrayIcon):
self.setWindowIcon(icon)
def loadPage(self, web_page):
- try:
- if os.environ.get('DEBUG'):
- self.settings().setAttribute(
- QWebSettings.DeveloperExtrasEnabled, True)
- except Exception:
- pass
-
- if os.environ.get('DEBUG'):
- self.inspector = QWebInspector(self)
- self.inspector.setPage(self.page())
- self.inspector.show()
-
if os.path.isabs(web_page):
web_page = os.path.relpath(web_page)
url = QtCore.QUrl(web_page)
- # TODO -- port this to QWebEngine
- self.frame = self.page().mainFrame()
- self.frame.addToJavaScriptWindowObject(
- "bitmaskBrowser", self.bitmask_browser)
self.load(url)
def shutdown(self, *args):
@@ -138,10 +124,12 @@ class BrowserWindow(QWebView, WithTrayIcon):
if self.closing:
return
self.closing = True
+
bitmaskd.join()
terminate(pid)
cleanup()
print('[bitmask] shutting down gui...')
+
try:
self.stop()
try:
@@ -157,11 +145,11 @@ class BrowserWindow(QWebView, WithTrayIcon):
sys.exit(1)
-class AppProxy(QObject):
+class AppBridge(QObject):
@pyqtSlot()
def shutdown(self):
- """To be exposed from the js bridge"""
+ print "[+] shutdown called from js"
global browser
if browser:
browser.user_closed = True
@@ -171,8 +159,8 @@ class AppProxy(QObject):
def openSystemBrowser(self, url):
webbrowser.open(url)
-
pixbrowser = None
+closing = False
class NewPageConnector(QObject):
@@ -185,12 +173,17 @@ class NewPageConnector(QObject):
def _handle_kill(*args, **kw):
+ global pixbrowser
+ global closing
+ if closing:
+ sys.exit()
win = kw.get('win')
if win:
+ win.user_closed = True
QtCore.QTimer.singleShot(0, win.close)
- global pixbrowser
if pixbrowser:
QtCore.QTimer.singleShot(0, pixbrowser.close)
+ closing = True
def launch_gui():
@@ -206,7 +199,7 @@ def launch_gui():
qApp = QApplication([])
try:
browser = BrowserWindow(None)
- except NoAuthToken as e:
+ except NoAuthTokenError as e:
print('ERROR: ' + e.message)
sys.exit(1)
@@ -237,6 +230,9 @@ def start_app():
# Allow the frozen binary in the bundle double as the cli entrypoint
# Why have only a user interface when you can have two?
+ if DEBUG:
+ os.environ.setdefault('QTWEBENGINE_REMOTE_DEBUGGING', '8081')
+
if platform.system() == 'Windows':
# In windows, there are some args added to the invocation
# by PyInstaller, I guess...
@@ -257,9 +253,6 @@ def start_app():
launch_gui()
-class NoAuthToken(Exception):
- pass
-
if __name__ == "__main__":
start_app()
diff --git a/src/leap/bitmask/gui/app2.py b/src/leap/bitmask/gui/app2.py
index 649d5deb..3e83b435 100644
--- a/src/leap/bitmask/gui/app2.py
+++ b/src/leap/bitmask/gui/app2.py
@@ -45,6 +45,7 @@ from leap.common.config import get_path_prefix
from leap.bitmask.gui.systray import WithTrayIcon
from leap.bitmask.gui.housekeeping import cleanup, terminate, reset_authtoken
from leap.bitmask.gui.housekeeping import get_authenticated_url
+from leap.bitmask.gui.housekeeping import NoAuthTokenError
DEBUG = os.environ.get("DEBUG", False)
@@ -151,7 +152,7 @@ def launch_gui():
systray.closeFromSystray()
sys.exit(qApp.exec_())
- except NoAuthToken as e:
+ except NoAuthTokenError as e:
print('ERROR: ' + e.message)
sys.exit(1)
@@ -180,9 +181,5 @@ def start_app():
launch_gui()
-class NoAuthToken(Exception):
- pass
-
-
if __name__ == "__main__":
start_app()
diff --git a/src/leap/bitmask/gui/housekeeping.py b/src/leap/bitmask/gui/housekeeping.py
index 3202f5e6..7069adba 100644
--- a/src/leap/bitmask/gui/housekeeping.py
+++ b/src/leap/bitmask/gui/housekeeping.py
@@ -1,7 +1,13 @@
import os
+import signal
+import time
from leap.common.config import get_path_prefix
+
+class NoAuthTokenError(Exception):
+ pass
+
def get_authenticated_url():
url = "http://localhost:7070"
path = os.path.join(get_path_prefix(), 'leap', 'authtoken')
@@ -12,7 +18,7 @@ def get_authenticated_url():
# because touching the token file is one of the first
# things the backend does, and this BrowserWindow
# should be called *right after* launching the backend.
- raise NoAuthToken(
+ raise NoAuthTokenError(
'No authentication token found!')
time.sleep(0.1)
waiting -= 1
diff --git a/ui/app/index.html b/ui/app/index.html
index d500e369..2cd0bf17 100644
--- a/ui/app/index.html
+++ b/ui/app/index.html
@@ -10,5 +10,15 @@
<body>
<div id="app"></div>
<script src="app.bundle.js"></script>
+ <script src="qrc:///qtwebchannel/qwebchannel.js"></script>
+ <script>
+ function _onload() {
+ window.webChannel = new QWebChannel(qt.webChannelTransport, function (channel) {
+ window.bitmaskApp = channel.objects.bitmaskApp;
+ });
+ console.log(window.bitmaskApp);
+ }
+ window.onload = _onload;
+ </script>
</body>
-</html> \ No newline at end of file
+</html>