import sys
import subprocess
from JAK.Utils import Instance, bindings, getScreenGeometry
from JAK import Settings
from JAK.Widgets import JWindow
from JAK.WebEngine import JWebView
from JAK import __version__
if bindings() == "PyQt5":
print("PyQt5 Bindings")
from PyQt5.QtCore import Qt, QCoreApplication, QRect
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWebEngineWidgets import QWebEnginePage
else:
print("JAK_PREFERRED_BINDING environment variable not set, falling back to PySide2 Bindings.")
from PySide2.QtCore import Qt, QCoreApplication
from PySide2.QtWidgets import QApplication
class JWebApp(QApplication):
def __init__(self, config=Settings.config(), **app_config):
super(JWebApp, self).__init__(sys.argv)
self.config = config
self.setAAttribute(Qt.AA_UseHighDpiPixmaps)
self.setAAttribute(Qt.AA_EnableHighDpiScaling)
self.applicationStateChanged.connect(self._applicationStateChanged_cb)
for key, value in app_config.items():
if isinstance(value, dict):
for subkey, subvalue in app_config[key].items():
config[key][subkey] = subvalue
else:
config[key] = value
for attr in config["setAAttribute"]:
self.setAAttribute(attr)
if config["remote-debug"] or "--remote-debug" in sys.argv:
sys.argv.append("--remote-debugging-port=9000")
if config["debug"] or "--dev" in sys.argv:
print("Debugging On")
if not config["debug"]:
config["debug"] = True
else:
print("Production Mode On, use (--dev) for debugging")
Enable/Disable GPU acceleration
if not config["disableGPU"]:
Virtual machine detection using SystemD
detect_virtual_machine = subprocess.Popen(
["systemd-detect-virt"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
FIXME find a more reliable way of detecting NVIDIA cards
detect_nvidia_pci = subprocess.Popen(
"lspci | grep -i --color 'vga\|3d\|2d'", stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
shell=True
)
virtual = detect_virtual_machine.communicate()
nvidia_pci = detect_nvidia_pci.communicate()
nvidia_pci = nvidia_pci[0].decode("utf-8").lower()
if config["disableGPU"]:
self.disable_opengl()
print("Disabling GPU, Software Rendering explicitly activated")
else:
if virtual[-1]:
Detect virtual machine
print(f"Virtual machine detected:{virtual}")
self.disable_opengl()
elif nvidia_pci:
Detect NVIDIA cards
if "nvidia" in nvidia_pci:
print("NVIDIA detected:Known bug - kernel rejected pushbuf")
print("Falling back to Software Rendering")
self.disable_opengl()
else:
print(f"Virtual Machine:{virtual[-1]}")
Desktop file must match application name in lowercase with dashes instead of white space.
self.setDesktopFileName(f"{self.config['window']['title'].lower().replace(' ', '-')}.desktop")
self.setOrganizationDomain(self.config['webview']['webContents'])
self.setApplicationVersion(__version__)
if not self.config['webview']['online'] and self.config['webview']['IPC']:
if bindings() == "PyQt5":
from PyQt5.QtWebEngineCore import QWebEngineUrlScheme
else:
from PySide2.QtWebEngineCore import QWebEngineUrlScheme
QWebEngineUrlScheme.registerScheme(QWebEngineUrlScheme("ipc".encode()))
def _applicationStateChanged_cb(self, event):
view = Instance.retrieve("view")
page = view.page()
TODO freeze view when inactive to save ram
if event == Qt.ApplicationInactive:
print("inactive")
elif event == Qt.ApplicationActive:
print("active")
def disable_opengl(self):
Disable GPU acceleration https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/206307
self.setAAttribute(Qt.AA_UseSoftwareOpenGL)
def setAAttribute(self, attr):
QCoreApplication.setAttribute(attr, True)
def run(self):
Instance.record("view", JWebView(self.config))
if self.config['webview']["addCSS"]:
from JAK.Utils import JavaScript
JavaScript.css(self.config['webview']["addCSS"])
print("Custom CSS detected")
if self.config['window']["transparent"]:
from JAK.Utils import JavaScript
JavaScript.css("body, html {background-color:transparent !important;background-image:none !important;}")
if self.config['webview']["runJavaScript"]:
from JAK.Utils import JavaScript
JavaScript.send(self.config['webview']["runJavaScript"])
print("Custom JavaScript detected")
win = Instance.auto("win", JWindow(self.config))
if self.config['window']["fullScreen"]:
screen = getScreenGeometry()
win.resize(screen.width(), screen.height())
else:
win.resize(win.default_size("width"), win.default_size("height"))
win.setFocusPolicy(Qt.WheelFocus)
win.show()
win.setFocus()
win.window_original_position = win.frameGeometry()
result = self.exec_()
sys.exit(result)