mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Windows: Automatically change colors between light and dark when the system wide preference is changed
This commit is contained in:
parent
1ec0085eff
commit
f695e49bd6
@ -49,8 +49,7 @@ Environment variables
|
||||
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_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 and ``0`` for normal colors (ignored on macOS).
|
||||
On Windows 10 in the absence of this variable, the Windows system preference for dark colors is used.
|
||||
* ``CALIBRE_USE_DARK_PALETTE`` - set it to ``1`` to have calibre use dark colors. Works on **Linux only**.
|
||||
* ``SYSFS_PATH`` - Use if sysfs is mounted somewhere other than /sys
|
||||
* ``http_proxy``, ``https_proxy`` - used on Linux to specify an HTTP(S) proxy
|
||||
|
||||
|
@ -30,6 +30,7 @@ from calibre.ebooks.metadata import MetaInformation
|
||||
from calibre.gui2.linux_file_dialogs import (
|
||||
check_for_linux_native_dialogs, linux_native_dialog
|
||||
)
|
||||
from calibre.gui2.palette import dark_palette, fix_palette_colors
|
||||
from calibre.gui2.qt_file_dialogs import FileDialog
|
||||
from calibre.ptempfile import base_dir
|
||||
from calibre.utils.config_base import tweaks
|
||||
@ -1076,6 +1077,11 @@ class Application(QApplication):
|
||||
QApplication.setDesktopFileName(override_program_name)
|
||||
QApplication.setAttribute(Qt.ApplicationAttribute.AA_ShareOpenGLContexts, True) # needed for webengine
|
||||
QApplication.__init__(self, qargs)
|
||||
self.original_palette = self.palette()
|
||||
self.original_palette_modified = fix_palette_colors(self.original_palette)
|
||||
if iswindows:
|
||||
self.win_event_filter = WinEventFilter()
|
||||
self.installNativeEventFilter(self.win_event_filter)
|
||||
icon_resource_manager.initialize()
|
||||
sh = self.styleHints()
|
||||
if hasattr(sh, 'setShowShortcutsInContextMenus'):
|
||||
@ -1146,14 +1152,6 @@ class Application(QApplication):
|
||||
raise SystemExit(1)
|
||||
|
||||
if iswindows:
|
||||
# On windows the highlighted colors for inactive widgets are the
|
||||
# same as non highlighted colors. This is a regression from Qt 4.
|
||||
# https://bugreports.qt-project.org/browse/QTBUG-41060
|
||||
p = self.palette()
|
||||
for role in (QPalette.ColorRole.Highlight, QPalette.ColorRole.HighlightedText, QPalette.ColorRole.Base, QPalette.ColorRole.AlternateBase):
|
||||
p.setColor(QPalette.ColorGroup.Inactive, role, p.color(QPalette.ColorGroup.Active, role))
|
||||
self.setPalette(p)
|
||||
|
||||
# Prevent text copied to the clipboard from being lost on quit due to
|
||||
# Qt 5 bug: https://bugreports.qt-project.org/browse/QTBUG-41125
|
||||
self.aboutToQuit.connect(self.flush_clipboard)
|
||||
@ -1221,7 +1219,6 @@ class Application(QApplication):
|
||||
load_builtin_fonts()
|
||||
|
||||
def set_dark_mode_palette(self):
|
||||
from calibre.gui2.palette import dark_palette
|
||||
self.set_palette(dark_palette())
|
||||
|
||||
def setup_styles(self, force_calibre_style):
|
||||
@ -1232,15 +1229,16 @@ class Application(QApplication):
|
||||
if force_calibre_style:
|
||||
using_calibre_style = True
|
||||
if using_calibre_style:
|
||||
use_dark_palette = False
|
||||
if 'CALIBRE_USE_DARK_PALETTE' in os.environ:
|
||||
if not ismacos:
|
||||
use_dark_palette = os.environ['CALIBRE_USE_DARK_PALETTE'] != '0'
|
||||
if iswindows:
|
||||
use_dark_palette = windows_is_system_dark_mode_enabled()
|
||||
elif ismacos:
|
||||
use_dark_palette = False
|
||||
else:
|
||||
if iswindows:
|
||||
use_dark_palette = windows_is_system_dark_mode_enabled()
|
||||
use_dark_palette = os.environ.get('CALIBRE_USE_DARK_PALETTE') == '1'
|
||||
if use_dark_palette:
|
||||
self.set_dark_mode_palette()
|
||||
elif self.original_palette_modified:
|
||||
self.set_palette(self.original_palette)
|
||||
|
||||
self.using_calibre_style = using_calibre_style
|
||||
if DEBUG:
|
||||
@ -1249,6 +1247,15 @@ class Application(QApplication):
|
||||
self.load_calibre_style()
|
||||
self.on_palette_change()
|
||||
|
||||
def check_for_windows_palette_change(self):
|
||||
use_dark_palette = bool(windows_is_system_dark_mode_enabled())
|
||||
if bool(self.is_dark_theme) != use_dark_palette:
|
||||
if use_dark_palette:
|
||||
self.set_dark_mode_palette()
|
||||
else:
|
||||
self.set_palette(self.original_palette)
|
||||
self.on_palette_change()
|
||||
|
||||
def set_palette(self, pal):
|
||||
self.ignore_palette_changes = True
|
||||
self.setPalette(pal)
|
||||
@ -1633,6 +1640,24 @@ def add_to_recent_docs(path):
|
||||
winutil.add_to_recent_docs(str(path), app.windows_app_uid)
|
||||
|
||||
|
||||
if iswindows:
|
||||
import ctypes
|
||||
from qt.core import QAbstractNativeEventFilter
|
||||
|
||||
class WinEventFilter(QAbstractNativeEventFilter):
|
||||
|
||||
def nativeEventFilter(self, eventType, message):
|
||||
if eventType == b"windows_generic_MSG":
|
||||
msg = ctypes.wintypes.MSG.from_address(message.__int__())
|
||||
# https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-settingchange
|
||||
if msg.message == 0x001A: # WM_SETTINGCHANGE
|
||||
if ctypes.wstring_at(msg.lParam) == 'ImmersiveColorSet':
|
||||
QApplication.instance().check_for_windows_palette_change()
|
||||
# prevent Qt from handling this event
|
||||
return True, 0
|
||||
return False, 0
|
||||
|
||||
|
||||
def windows_is_system_dark_mode_enabled():
|
||||
s = QSettings(r"HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize", QSettings.Format.NativeFormat)
|
||||
if s.status() == QSettings.Status.NoError:
|
||||
|
@ -2,7 +2,7 @@
|
||||
# License: GPL v3 Copyright: 2019, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from qt.core import QColor, QPalette, Qt
|
||||
from calibre.constants import dark_link_color
|
||||
from calibre.constants import dark_link_color, iswindows
|
||||
|
||||
|
||||
dark_link_color = QColor(dark_link_color)
|
||||
@ -10,6 +10,17 @@ dark_color = QColor(45,45,45)
|
||||
dark_text_color = QColor('#ddd')
|
||||
|
||||
|
||||
def fix_palette_colors(p):
|
||||
if iswindows:
|
||||
# On Windows the highlighted colors for inactive widgets are the
|
||||
# same as non highlighted colors. This is a regression from Qt 4.
|
||||
# https://bugreports.qt-project.org/browse/QTBUG-41060
|
||||
for role in (QPalette.ColorRole.Highlight, QPalette.ColorRole.HighlightedText, QPalette.ColorRole.Base, QPalette.ColorRole.AlternateBase):
|
||||
p.setColor(QPalette.ColorGroup.Inactive, role, p.color(QPalette.ColorGroup.Active, role))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def dark_palette():
|
||||
p = QPalette()
|
||||
disabled_color = QColor(127,127,127)
|
||||
|
Loading…
x
Reference in New Issue
Block a user