mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 10:14:46 -04:00
Linux: Use the system dark mode setting
This comes from the desktop settings portal implemented in KDE 5.24 and GNOME 42
This commit is contained in:
parent
8bf10b1056
commit
bc97485ff2
@ -49,7 +49,7 @@ Environment variables
|
|||||||
the system theme -- beware of crashes and hangs.
|
the system theme -- beware of crashes and hangs.
|
||||||
* ``CALIBRE_SHOW_DEPRECATION_WARNINGS`` - causes calibre to print deprecation warnings to stdout. Useful for calibre developers.
|
* ``CALIBRE_SHOW_DEPRECATION_WARNINGS`` - causes calibre to print deprecation warnings to stdout. Useful for calibre developers.
|
||||||
* ``CALIBRE_NO_DEFAULT_PROGRAMS`` - prevent calibre from automatically registering the filetypes it is capable of handling with Windows.
|
* ``CALIBRE_NO_DEFAULT_PROGRAMS`` - prevent calibre from automatically registering the filetypes it is capable of handling with Windows.
|
||||||
* ``CALIBRE_USE_DARK_PALETTE`` - set it to ``1`` to have calibre use dark colors. Works on **Linux only**.
|
* ``CALIBRE_USE_DARK_PALETTE`` - set it to ``1`` to have calibre use dark colors and ``0`` for light colors. Works on **Linux only**.
|
||||||
* ``SYSFS_PATH`` - Use if sysfs is mounted somewhere other than /sys
|
* ``SYSFS_PATH`` - Use if sysfs is mounted somewhere other than /sys
|
||||||
* ``http_proxy``, ``https_proxy`` - used on Linux to specify an HTTP(S) proxy
|
* ``http_proxy``, ``https_proxy`` - used on Linux to specify an HTTP(S) proxy
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ from qt.core import (
|
|||||||
QFileIconProvider, QFileInfo, QFont, QFontDatabase, QFontInfo, QFontMetrics,
|
QFileIconProvider, QFileInfo, QFont, QFontDatabase, QFontInfo, QFontMetrics,
|
||||||
QGuiApplication, QIcon, QIODevice, QLocale, QNetworkProxyFactory, QObject,
|
QGuiApplication, QIcon, QIODevice, QLocale, QNetworkProxyFactory, QObject,
|
||||||
QPalette, QResource, QSettings, QSocketNotifier, QStringListModel, QStyle, Qt,
|
QPalette, QResource, QSettings, QSocketNotifier, QStringListModel, QStyle, Qt,
|
||||||
QThread, QTimer, QTranslator, QUrl, pyqtSignal
|
QThread, QTimer, QTranslator, QUrl, pyqtSignal, pyqtSlot
|
||||||
)
|
)
|
||||||
from threading import Lock, RLock
|
from threading import Lock, RLock
|
||||||
|
|
||||||
@ -47,6 +47,8 @@ try:
|
|||||||
NO_URL_FORMATTING = QUrl.UrlFormattingOption.None_
|
NO_URL_FORMATTING = QUrl.UrlFormattingOption.None_
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
NO_URL_FORMATTING = getattr(QUrl, 'None')
|
NO_URL_FORMATTING = getattr(QUrl, 'None')
|
||||||
|
if islinux:
|
||||||
|
from qt.dbus import QDBusConnection, QDBusMessage, QDBusVariant
|
||||||
|
|
||||||
|
|
||||||
class IconResourceManager:
|
class IconResourceManager:
|
||||||
@ -1234,7 +1236,14 @@ class Application(QApplication):
|
|||||||
elif ismacos:
|
elif ismacos:
|
||||||
use_dark_palette = False
|
use_dark_palette = False
|
||||||
else:
|
else:
|
||||||
|
if 'CALIBRE_USE_DARK_PALETTE' in os.environ:
|
||||||
use_dark_palette = os.environ.get('CALIBRE_USE_DARK_PALETTE') == '1'
|
use_dark_palette = os.environ.get('CALIBRE_USE_DARK_PALETTE') == '1'
|
||||||
|
else:
|
||||||
|
use_dark_palette = linux_is_system_dark_mode_enabled()
|
||||||
|
bus = QDBusConnection.sessionBus()
|
||||||
|
bus.connect(
|
||||||
|
'org.freedesktop.portal.Desktop', '/org/freedesktop/portal/desktop',
|
||||||
|
'org.freedesktop.portal.Settings', 'SettingChanged', 'ssv', self.linux_desktop_setting_changed)
|
||||||
if use_dark_palette:
|
if use_dark_palette:
|
||||||
self.set_dark_mode_palette()
|
self.set_dark_mode_palette()
|
||||||
elif self.original_palette_modified:
|
elif self.original_palette_modified:
|
||||||
@ -1247,6 +1256,18 @@ class Application(QApplication):
|
|||||||
self.load_calibre_style()
|
self.load_calibre_style()
|
||||||
self.on_palette_change()
|
self.on_palette_change()
|
||||||
|
|
||||||
|
if islinux:
|
||||||
|
@pyqtSlot(str, str, QDBusVariant)
|
||||||
|
def linux_desktop_setting_changed(self, namespace, key, val):
|
||||||
|
if (namespace, key) == ('org.freedesktop.appearance', 'color-scheme'):
|
||||||
|
use_dark_palette = val.variant() == 1
|
||||||
|
if use_dark_palette != bool(self.is_dark_theme):
|
||||||
|
if use_dark_palette:
|
||||||
|
self.set_dark_mode_palette()
|
||||||
|
else:
|
||||||
|
self.set_palette(self.original_palette)
|
||||||
|
self.on_palette_change()
|
||||||
|
|
||||||
def check_for_windows_palette_change(self):
|
def check_for_windows_palette_change(self):
|
||||||
use_dark_palette = bool(windows_is_system_dark_mode_enabled())
|
use_dark_palette = bool(windows_is_system_dark_mode_enabled())
|
||||||
if bool(self.is_dark_theme) != use_dark_palette:
|
if bool(self.is_dark_theme) != use_dark_palette:
|
||||||
@ -1670,6 +1691,18 @@ def windows_is_system_dark_mode_enabled():
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def linux_is_system_dark_mode_enabled():
|
||||||
|
bus = QDBusConnection.sessionBus()
|
||||||
|
m = QDBusMessage.createMethodCall(
|
||||||
|
'org.freedesktop.portal.Desktop', '/org/freedesktop/portal/desktop',
|
||||||
|
'org.freedesktop.portal.Settings', 'Read'
|
||||||
|
)
|
||||||
|
m.setArguments(['org.freedesktop.appearance', 'color-scheme'])
|
||||||
|
reply = bus.call(m, timeout=1000)
|
||||||
|
a = reply.arguments()
|
||||||
|
return len(a) and isinstance(a[0], int) and a[0] == 1
|
||||||
|
|
||||||
|
|
||||||
def make_view_use_window_background(view):
|
def make_view_use_window_background(view):
|
||||||
p = view.palette()
|
p = view.palette()
|
||||||
p.setColor(QPalette.ColorRole.Base, p.color(QPalette.ColorRole.Window))
|
p.setColor(QPalette.ColorRole.Base, p.color(QPalette.ColorRole.Window))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# autogenerated by __main__.py do not edit
|
# autogenerated by __main__.py do not edit
|
||||||
top_level_module_names=('QtCore', 'QtGui', 'QtWidgets', 'QtNetwork', 'QtSvg', 'QtPrintSupport', 'QtWebEngineCore', 'QtWebEngineWidgets')
|
top_level_module_names=('QtCore', 'QtGui', 'QtWidgets', 'QtNetwork', 'QtSvg', 'QtPrintSupport', 'QtWebEngineCore', 'QtWebEngineWidgets', 'QtDBus')
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
def __getattr__(name):
|
||||||
|
@ -22,6 +22,9 @@ module_lists = {
|
|||||||
'QtWebEngineCore',
|
'QtWebEngineCore',
|
||||||
'QtWebEngineWidgets',
|
'QtWebEngineWidgets',
|
||||||
),
|
),
|
||||||
|
'dbus': (
|
||||||
|
'QtDBus',
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -54,7 +57,7 @@ def scan(name):
|
|||||||
|
|
||||||
|
|
||||||
top_level_module_names = ()
|
top_level_module_names = ()
|
||||||
for name in ('core', 'webengine'):
|
for name in ('core', 'webengine', 'dbus'):
|
||||||
top_level_module_names += module_lists[name]
|
top_level_module_names += module_lists[name]
|
||||||
scan(name)
|
scan(name)
|
||||||
with open(f'{base}/__init__.py', 'w') as f:
|
with open(f'{base}/__init__.py', 'w') as f:
|
||||||
|
14
src/qt/dbus.py
Normal file
14
src/qt/dbus.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPL v3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
|
||||||
|
from .loader import dynamic_load
|
||||||
|
from .dbus_name_map import name_map, module_names
|
||||||
|
|
||||||
|
already_imported = {}
|
||||||
|
qt_modules = {}
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(name):
|
||||||
|
return dynamic_load(name, name_map, already_imported, qt_modules, module_names)
|
20
src/qt/dbus.pyi
Normal file
20
src/qt/dbus.pyi
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# autogenerated by __main__.py do not edit
|
||||||
|
import PyQt6.QtDBus
|
||||||
|
QDBus = PyQt6.QtDBus.QDBus
|
||||||
|
QDBusAbstractAdaptor = PyQt6.QtDBus.QDBusAbstractAdaptor
|
||||||
|
QDBusAbstractInterface = PyQt6.QtDBus.QDBusAbstractInterface
|
||||||
|
QDBusArgument = PyQt6.QtDBus.QDBusArgument
|
||||||
|
QDBusConnection = PyQt6.QtDBus.QDBusConnection
|
||||||
|
QDBusConnectionInterface = PyQt6.QtDBus.QDBusConnectionInterface
|
||||||
|
QDBusError = PyQt6.QtDBus.QDBusError
|
||||||
|
QDBusInterface = PyQt6.QtDBus.QDBusInterface
|
||||||
|
QDBusMessage = PyQt6.QtDBus.QDBusMessage
|
||||||
|
QDBusObjectPath = PyQt6.QtDBus.QDBusObjectPath
|
||||||
|
QDBusPendingCall = PyQt6.QtDBus.QDBusPendingCall
|
||||||
|
QDBusPendingCallWatcher = PyQt6.QtDBus.QDBusPendingCallWatcher
|
||||||
|
QDBusPendingReply = PyQt6.QtDBus.QDBusPendingReply
|
||||||
|
QDBusReply = PyQt6.QtDBus.QDBusReply
|
||||||
|
QDBusServiceWatcher = PyQt6.QtDBus.QDBusServiceWatcher
|
||||||
|
QDBusSignature = PyQt6.QtDBus.QDBusSignature
|
||||||
|
QDBusUnixFileDescriptor = PyQt6.QtDBus.QDBusUnixFileDescriptor
|
||||||
|
QDBusVariant = PyQt6.QtDBus.QDBusVariant
|
22
src/qt/dbus_name_map.py
Normal file
22
src/qt/dbus_name_map.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# autogenerated by __main__.py do not edit
|
||||||
|
name_map = {'QDBus': 'PyQt6.QtDBus',
|
||||||
|
'QDBusAbstractAdaptor': 'PyQt6.QtDBus',
|
||||||
|
'QDBusAbstractInterface': 'PyQt6.QtDBus',
|
||||||
|
'QDBusArgument': 'PyQt6.QtDBus',
|
||||||
|
'QDBusConnection': 'PyQt6.QtDBus',
|
||||||
|
'QDBusConnectionInterface': 'PyQt6.QtDBus',
|
||||||
|
'QDBusError': 'PyQt6.QtDBus',
|
||||||
|
'QDBusInterface': 'PyQt6.QtDBus',
|
||||||
|
'QDBusMessage': 'PyQt6.QtDBus',
|
||||||
|
'QDBusObjectPath': 'PyQt6.QtDBus',
|
||||||
|
'QDBusPendingCall': 'PyQt6.QtDBus',
|
||||||
|
'QDBusPendingCallWatcher': 'PyQt6.QtDBus',
|
||||||
|
'QDBusPendingReply': 'PyQt6.QtDBus',
|
||||||
|
'QDBusReply': 'PyQt6.QtDBus',
|
||||||
|
'QDBusServiceWatcher': 'PyQt6.QtDBus',
|
||||||
|
'QDBusSignature': 'PyQt6.QtDBus',
|
||||||
|
'QDBusUnixFileDescriptor': 'PyQt6.QtDBus',
|
||||||
|
'QDBusVariant': 'PyQt6.QtDBus',
|
||||||
|
'QtDBus': 'PyQt6.QtDBus'}
|
||||||
|
module_names = frozenset(('QtDBus',)
|
||||||
|
)
|
Loading…
x
Reference in New Issue
Block a user