mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
Detect OS color mode and set as property for stylesheets
Sets the detected OS color mode (dark/light) as a property on the QApplication so it can be referenced in stylesheets to select style rules suited to the OS color mode.
This commit is contained in:
parent
23bee23d81
commit
46f978e6f0
3 changed files with 38 additions and 1 deletions
|
@ -1,3 +1,4 @@
|
|||
import enum
|
||||
import functools
|
||||
import logging
|
||||
import os
|
||||
|
@ -33,6 +34,18 @@ from .updater import UpdaterThread
|
|||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OSColorMode(enum.Enum):
|
||||
"""
|
||||
Operating system color mode, e.g. Light or Dark Mode on macOS 10.14+ or Windows 10+.
|
||||
|
||||
The enum values are used as the names of Qt properties that will be selected by QSS
|
||||
property selectors to set color-mode-specific style rules.
|
||||
"""
|
||||
|
||||
LIGHT = "light"
|
||||
DARK = "dark"
|
||||
|
||||
|
||||
class Application(QtWidgets.QApplication):
|
||||
document_selected = QtCore.Signal(list)
|
||||
application_activated = QtCore.Signal()
|
||||
|
@ -61,6 +74,23 @@ class Application(QtWidgets.QApplication):
|
|||
|
||||
self.event = monkeypatch_event # type: ignore [method-assign]
|
||||
|
||||
self.os_color_mode = self.infer_os_color_mode()
|
||||
log.debug(f"Inferred system color scheme as {self.os_color_mode}")
|
||||
|
||||
def infer_os_color_mode(self) -> OSColorMode:
|
||||
"""
|
||||
Qt 6.5+ explicitly provides the OS color scheme via QStyleHints.colorScheme(),
|
||||
but we still need to support PySide2/Qt 5, so instead we infer the OS color
|
||||
scheme from the default palette.
|
||||
"""
|
||||
text_color, window_color = (
|
||||
self.palette().color(role)
|
||||
for role in (QtGui.QPalette.WindowText, QtGui.QPalette.Window)
|
||||
)
|
||||
if text_color.lightness() > window_color.lightness():
|
||||
return OSColorMode.DARK
|
||||
return OSColorMode.LIGHT
|
||||
|
||||
|
||||
@click.command()
|
||||
@click.option(
|
||||
|
|
|
@ -12,6 +12,8 @@ from colorama import Fore
|
|||
# FIXME: See https://github.com/freedomofpress/dangerzone/issues/320 for more details.
|
||||
if typing.TYPE_CHECKING:
|
||||
from PySide2 import QtCore, QtGui, QtWidgets
|
||||
|
||||
from . import Application
|
||||
else:
|
||||
try:
|
||||
from PySide6 import QtCore, QtGui, QtWidgets
|
||||
|
@ -35,7 +37,7 @@ class DangerzoneGui(DangerzoneCore):
|
|||
"""
|
||||
|
||||
def __init__(
|
||||
self, app: QtWidgets.QApplication, isolation_provider: IsolationProvider
|
||||
self, app: "Application", isolation_provider: IsolationProvider
|
||||
) -> None:
|
||||
super().__init__(isolation_provider)
|
||||
|
||||
|
|
|
@ -162,6 +162,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
|||
central_widget.setLayout(layout)
|
||||
self.setCentralWidget(central_widget)
|
||||
|
||||
# Set the OS color mode as a property on the MainWindow, which is the closest
|
||||
# thing we have to a top-level container element akin to an HTML `<body>`.
|
||||
# This allows us to make QSS rules conditional on the OS color mode.
|
||||
self.setProperty("OSColorMode", self.dangerzone.app.os_color_mode.value)
|
||||
|
||||
self.show()
|
||||
|
||||
def load_svg_image(self, filename: str) -> QtGui.QPixmap:
|
||||
|
|
Loading…
Reference in a new issue