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 functools
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
@ -33,6 +34,18 @@ from .updater import UpdaterThread
|
||||||
log = logging.getLogger(__name__)
|
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):
|
class Application(QtWidgets.QApplication):
|
||||||
document_selected = QtCore.Signal(list)
|
document_selected = QtCore.Signal(list)
|
||||||
application_activated = QtCore.Signal()
|
application_activated = QtCore.Signal()
|
||||||
|
@ -61,6 +74,23 @@ class Application(QtWidgets.QApplication):
|
||||||
|
|
||||||
self.event = monkeypatch_event # type: ignore [method-assign]
|
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.command()
|
||||||
@click.option(
|
@click.option(
|
||||||
|
|
|
@ -12,6 +12,8 @@ from colorama import Fore
|
||||||
# FIXME: See https://github.com/freedomofpress/dangerzone/issues/320 for more details.
|
# FIXME: See https://github.com/freedomofpress/dangerzone/issues/320 for more details.
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
from PySide2 import QtCore, QtGui, QtWidgets
|
from PySide2 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
from . import Application
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
from PySide6 import QtCore, QtGui, QtWidgets
|
from PySide6 import QtCore, QtGui, QtWidgets
|
||||||
|
@ -35,7 +37,7 @@ class DangerzoneGui(DangerzoneCore):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, app: QtWidgets.QApplication, isolation_provider: IsolationProvider
|
self, app: "Application", isolation_provider: IsolationProvider
|
||||||
) -> None:
|
) -> None:
|
||||||
super().__init__(isolation_provider)
|
super().__init__(isolation_provider)
|
||||||
|
|
||||||
|
|
|
@ -162,6 +162,11 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
central_widget.setLayout(layout)
|
central_widget.setLayout(layout)
|
||||||
self.setCentralWidget(central_widget)
|
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()
|
self.show()
|
||||||
|
|
||||||
def load_svg_image(self, filename: str) -> QtGui.QPixmap:
|
def load_svg_image(self, filename: str) -> QtGui.QPixmap:
|
||||||
|
|
Loading…
Reference in a new issue