diff --git a/web-greeter/__main__.py b/web-greeter/__main__.py
index fa6d7af..a46e6be 100644
--- a/web-greeter/__main__.py
+++ b/web-greeter/__main__.py
@@ -61,7 +61,7 @@ def set_debug(value: bool):
conf = config.web_greeter_config["config"]
app = config.web_greeter_config["app"]
conf["greeter"]["debug_mode"] = value
- app["decorated"] = value
+ app["frame"] = value
app["fullscreen"] = not value
def parse(argv):
diff --git a/web-greeter/bridge/Greeter.py b/web-greeter/bridge/Greeter.py
index 19deb2c..ff84c10 100644
--- a/web-greeter/bridge/Greeter.py
+++ b/web-greeter/bridge/Greeter.py
@@ -27,6 +27,7 @@
# along with Web Greeter; If not, see .
# Standard Lib
+from browser.error_prompt import Dialog
import subprocess
import threading
@@ -36,9 +37,11 @@ gi.require_version('LightDM', '1')
from gi.repository import LightDM
from browser.bridge import Bridge, BridgeObject
-from PyQt5.QtCore import QVariant, QTimer
+from PyQt5.QtCore import QFileSystemWatcher, QVariant, QTimer
from config import web_greeter_config
+from utils.battery import Battery
+import globals
# This Application
from . import (
@@ -56,19 +59,52 @@ LightDMGreeter = LightDM.Greeter()
LightDMUsers = LightDM.UserList()
-def changeBrightness(self, method: str, quantity: int):
- if self._config["features"]["backlight"]["enabled"] != True:
+def changeBrightness(method: str, quantity: int = None):
+ backlight = web_greeter_config["config"]["features"]["backlight"]
+ if not backlight["enabled"]:
return
+ if not quantity:
+ quantity = backlight["value"]
try:
- steps = self._config["features"]["backlight"]["steps"]
+ steps = backlight["steps"]
child = subprocess.run(["xbacklight", method, str(quantity), "-steps", str(steps)])
if child.returncode == 1:
raise ChildProcessError("xbacklight returned 1")
except Exception as err:
logger.error("Brightness: {}".format(err))
else:
- self.brightness_update.emit()
+ if globals.greeter:
+ globals.greeter.greeter.brightness_update.emit()
+def increaseBrightness(quantity: int = None):
+ backlight = web_greeter_config["config"]["features"]["backlight"]
+ if not backlight["enabled"]:
+ return
+ if not quantity:
+ quantity = backlight["value"]
+ thread = threading.Thread(target=changeBrightness,
+ args=("-inc", quantity))
+ thread.start()
+
+def decreaseBrightness(quantity: int = None):
+ backlight = web_greeter_config["config"]["features"]["backlight"]
+ if not backlight["enabled"]:
+ return
+ if not quantity:
+ quantity = backlight["value"]
+ thread = threading.Thread(target=changeBrightness,
+ args=("-dec", quantity))
+ thread.start()
+
+def setBrightness(quantity: int = None):
+ backlight = web_greeter_config["config"]["features"]["backlight"]
+ if not backlight["enabled"]:
+ return
+ if not quantity:
+ quantity = backlight["value"]
+ thread = threading.Thread(target=changeBrightness,
+ args=("-set", quantity))
+ thread.start()
def getBrightness(self):
if self._config["features"]["backlight"]["enabled"] != True:
@@ -106,13 +142,23 @@ class Greeter(BridgeObject):
self._shared_data_directory = ''
self._themes_directory = web_greeter_config["app"]["theme_dir"]
- # if self._config.features.battery == True:
- # self._battery = battery.Battery()
+ if self._config["features"]["battery"]:
+ self._battery = Battery()
- LightDMGreeter.connect_to_daemon_sync()
+ try:
+ LightDMGreeter.connect_to_daemon_sync()
+ except Exception as err:
+ logger.error(err)
+ dia = Dialog(title="An error ocurred",
+ message="Detected a problem that could interfere with the system login process",
+ detail="LightDM: {0}\nYou can continue without major problems, but you won't be able to log in".format(err),
+ buttons=["Okay"])
+ dia.exec()
+ pass
self._connect_signals()
self._determine_shared_data_directory_path()
+ logger.debug("LightDM API connected")
def _determine_shared_data_directory_path(self):
user = LightDMUsers.get_users()[0]
@@ -174,9 +220,7 @@ class Greeter(BridgeObject):
@brightness.setter
def brightness(self, quantity):
- thread = threading.Thread(target=changeBrightness,
- args=(self, "-set", quantity))
- thread.start()
+ setBrightness(quantity)
@Bridge.prop(bool, notify=noop_signal)
def can_hibernate(self):
@@ -305,21 +349,15 @@ class Greeter(BridgeObject):
@Bridge.method(int)
def brightnessSet(self, quantity):
- thread = threading.Thread(target=changeBrightness,
- args=(self, "-set", quantity))
- thread.start()
+ setBrightness(quantity)
@Bridge.method(int)
def brightnessIncrease(self, quantity):
- thread = threading.Thread(target=changeBrightness,
- args=(self, "-inc", quantity))
- thread.start()
+ increaseBrightness(quantity)
@Bridge.method(int)
def brightnessDecrease(self, quantity):
- thread = threading.Thread(target=changeBrightness,
- args=(self, "-dec", quantity))
- thread.start()
+ decreaseBrightness(quantity)
@Bridge.method()
def cancel_authentication(self):
diff --git a/web-greeter/bridge/__init__.py b/web-greeter/bridge/__init__.py
index 6e164be..fb8d8ab 100644
--- a/web-greeter/bridge/__init__.py
+++ b/web-greeter/bridge/__init__.py
@@ -119,6 +119,7 @@ def battery_to_dict(battery):
name = battery.get_name(),
level = battery.get_level(),
state = battery.get_state(),
+ ac_status = battery.get_ac_status(),
capacity = battery.get_capacity(),
time = battery.get_time(),
watt = battery.get_watt()
diff --git a/web-greeter/browser/browser.py b/web-greeter/browser/browser.py
index fa94e74..86271bf 100644
--- a/web-greeter/browser/browser.py
+++ b/web-greeter/browser/browser.py
@@ -29,7 +29,6 @@
# Standard lib
from browser.window import MainWindow
-from browser.devtools import DevTools
import os
from typing import (
Dict,
@@ -39,10 +38,10 @@ from typing import (
# 3rd-Party Libs
from PyQt5.QtCore import QUrl, Qt, QCoreApplication, QFile
-from PyQt5.QtWidgets import QApplication, QDesktopWidget, QDockWidget, QMainWindow
+from PyQt5.QtWidgets import QAction, QApplication, QDesktopWidget, QDockWidget, QMainWindow, qApp
from PyQt5.QtWebEngineCore import QWebEngineUrlScheme
from PyQt5.QtWebEngineWidgets import QWebEngineScript, QWebEngineProfile, QWebEngineSettings, QWebEngineView, QWebEnginePage
-from PyQt5.QtGui import QColor
+from PyQt5.QtGui import QColor, QIcon
from PyQt5.QtWebChannel import QWebChannel
from browser.error_prompt import WebPage
@@ -106,7 +105,13 @@ class Application:
self.window.windowFlags() | Qt.WindowType.MaximizeUsingFullscreenGeometryHint
)
+ if web_greeter_config["app"]["frame"]:
+ self._init_menu_bar()
+
state = self.states['NORMAL']
+ if web_greeter_config["app"]["fullscreen"]:
+ state = self.states["FULLSCREEN"]
+
try:
self.window.windowHandle().setWindowState(state)
except Exception:
@@ -127,6 +132,27 @@ class Application:
logger.debug("Web Greeter started")
return self.app.exec_()
+ def _init_menu_bar(self):
+ exit_action = QAction(QIcon('exit.png'), '&Exit', self.window)
+ exit_action.setShortcut('Ctrl+Q')
+ exit_action.setStatusTip('Exit application')
+ exit_action.triggered.connect(qApp.quit)
+
+ menu_bar = self.window.menuBar()
+
+ file_menu = menu_bar.addMenu('&File')
+ file_menu.addAction(exit_action)
+
+ edit_menu = menu_bar.addMenu('&Edit')
+ edit_menu.addAction(exit_action)
+
+ view_menu = menu_bar.addMenu('&View')
+ view_menu.addAction(exit_action)
+
+ about_menu = menu_bar.addMenu('&About')
+ about_menu.addAction(exit_action)
+
+
class Browser(Application):
url_scheme: QWebEngineUrlScheme
@@ -211,8 +237,10 @@ class Browser(Application):
return
if self.qdock.isVisible():
self.qdock.hide()
+ self.view.setFocus()
else:
self.qdock.show()
+ self.dev_view.setFocus()
def _initialize_page(self):
page_settings = self.page.settings().globalSettings()
diff --git a/web-greeter/browser/error_prompt.py b/web-greeter/browser/error_prompt.py
index 1a38cf4..c035629 100644
--- a/web-greeter/browser/error_prompt.py
+++ b/web-greeter/browser/error_prompt.py
@@ -28,8 +28,9 @@
# Standard lib
# 3rd-Party Libs
+from typing import List
from PyQt5.QtWebEngineWidgets import QWebEnginePage
-from PyQt5.QtWidgets import QDialogButtonBox, QDialog, QVBoxLayout, QLabel, QPushButton
+from PyQt5.QtWidgets import QAbstractButton, QDialogButtonBox, QDialog, QVBoxLayout, QLabel, QPushButton
from config import web_greeter_config
import globals
@@ -86,54 +87,49 @@ class WebPage(QWebEnginePage):
source=sourceID, line=lineNumber, msg=message)
errorPrompt(errorMessage)
-class ErrorDialog(QDialog):
- def __init__(self, parent=None, err=""):
+class Dialog(QDialog):
+ def __init__(self, parent=None, title:str = "Dialog", message:str = "Message", detail:str = "", buttons: List[str] = []):
super().__init__(parent)
-
- self.setWindowTitle("Error")
+ self.setWindowTitle(title)
self.buttonBox = QDialogButtonBox()
- cancelBtn = QPushButton("Cancel")
- defaultBtn = QPushButton("Set default theme")
- reloadBtn = QPushButton("Reload theme")
-
- reloadBtn.clicked.connect(self.handle_reload)
-
- self.buttonBox.addButton(defaultBtn, QDialogButtonBox.ButtonRole.AcceptRole)
- self.buttonBox.addButton(reloadBtn, QDialogButtonBox.ButtonRole.ResetRole)
- self.buttonBox.addButton(cancelBtn, QDialogButtonBox.ButtonRole.RejectRole)
+ for i in range(0, len(buttons)):
+ button = QPushButton(buttons[i])
+ button.role = i
+ self.buttonBox.addButton(button, QDialogButtonBox.ButtonRole.NoRole)
- self.buttonBox.accepted.connect(self.accept)
- self.buttonBox.rejected.connect(self.reject)
+ self.buttonBox.clicked.connect(self.handle_click)
self.layout = QVBoxLayout()
- message = QLabel("An error ocurred. Do you want to change to default theme?")
- err = QLabel(err)
- self.layout.addWidget(message)
- self.layout.addWidget(err)
+ self.layout.addWidget(QLabel(message))
+ self.layout.addWidget(QLabel(detail))
self.layout.addWidget(self.buttonBox)
- self.setLayout(self.layout)
- def handle_reload(self, value: bool):
- self.done(2)
+ self.setLayout(self.layout)
+ def handle_click(self, button: QAbstractButton):
+ self.done(button.role)
def errorPrompt(err):
if not web_greeter_config["config"]["greeter"]["detect_theme_errors"]:
return
- dia = ErrorDialog(globals.greeter.window, err)
+ dia = Dialog(parent=globals.greeter.window, title="Error",
+ message="An error ocurred. Do you want to change to default theme?",
+ detail=err,
+ buttons=["Reload theme", "Set default theme", "Cancel"],
+ )
dia.exec()
result = dia.result()
- if result == 0: # Cancel
+ if result == 2: # Cancel
return
elif result == 1: # Default theme
web_greeter_config["config"]["greeter"]["theme"] = "gruvbox"
globals.greeter.load_theme()
return
- elif result == 2: # Reload
+ elif result == 0: # Reload
globals.greeter.load_theme()
return
diff --git a/web-greeter/browser/window.py b/web-greeter/browser/window.py
index 0ef46dd..5f8ad95 100644
--- a/web-greeter/browser/window.py
+++ b/web-greeter/browser/window.py
@@ -25,22 +25,49 @@
# You should have received a copy of the GNU General Public License
# along with Web Greeter; If not, see .
-from PyQt5.QtCore import Qt
-from PyQt5.QtWidgets import QMainWindow
+from bridge.Greeter import changeBrightness, decreaseBrightness, increaseBrightness
+from PyQt5.QtCore import QFileSystemWatcher, Qt
+from PyQt5.QtWidgets import QAction, QMainWindow
from PyQt5.QtGui import QKeyEvent
+from config import web_greeter_config
import globals
class MainWindow(QMainWindow):
- def keyPressEvent(self, keyEvent: QKeyEvent) -> None:
- super().keyPressEvent(keyEvent)
- key = keyEvent.key()
- mod = keyEvent.modifiers() # type: Qt.KeyboardModifiers
- if (key == Qt.Key.Key_MonBrightnessUp):
- pass
- elif (key == Qt.Key.Key_MonBrightnessDown):
- pass
- elif (key == Qt.Key.Key_I
- and mod & Qt.KeyboardModifier.ControlModifier
- and mod & Qt.KeyboardModifier.ShiftModifier):
- globals.greeter.toggle_devtools()
+ def __init__(self):
+ super().__init__()
+ self.init_actions()
+ # self.watchBrightness()
+
+ def init_actions(self):
+ devAct = QAction(text="&Toggle Devtools", parent=self)
+ devAct.setShortcut("Shift+Ctrl+I")
+ devAct.triggered.connect(self.toggle_devtools)
+
+ monBUp = QAction(text="&Increase brightness", parent=self)
+ monBDo = QAction(text="&Decrease brightness", parent=self)
+ monBUp.setShortcut(Qt.Key.Key_MonBrightnessUp)
+ monBDo.setShortcut(Qt.Key.Key_MonBrightnessDown)
+ monBUp.triggered.connect(self.inc_brightness)
+ monBDo.triggered.connect(self.dec_brightness)
+
+ self.addAction(devAct)
+ self.addAction(monBUp)
+ self.addAction(monBDo)
+
+ def toggle_devtools(self):
+ globals.greeter.toggle_devtools()
+
+ def inc_brightness(self):
+ increaseBrightness()
+ def dec_brightness(self):
+ decreaseBrightness()
+
+ def watchBrightness(self):
+ self.watcher = QFileSystemWatcher(parent=self)
+ self.watcher.addPath("/sys/class/backlight/intel_backlight/brightness")
+ self.watcher.fileChanged.connect(self.updateBrightness)
+
+ def updateBrightness(self):
+ if globals.greeter:
+ globals.greeter.greeter.brightness_update.emit()