Implement support for windows 10 dark mode, fixes #370.

This commit is contained in:
Tomas Groth 2020-10-02 02:18:39 +00:00 committed by Raoul Snyman
parent f09ce2fed0
commit 64b62c4f59
4 changed files with 56 additions and 12 deletions

View File

@ -36,7 +36,7 @@ from pathlib import Path
from shutil import copytree
from traceback import format_exception
from PyQt5 import QtCore, QtWebEngineWidgets, QtWidgets # noqa
from PyQt5 import QtCore, QtGui, QtWebEngineWidgets, QtWidgets # noqa
from openlp.core.api.deploy import check_for_remote_update
from openlp.core.common import is_macosx, is_win
@ -56,7 +56,7 @@ from openlp.core.ui.firsttimeform import FirstTimeForm
from openlp.core.ui.firsttimelanguageform import FirstTimeLanguageForm
from openlp.core.ui.mainwindow import MainWindow
from openlp.core.ui.splashscreen import SplashScreen
from openlp.core.ui.style import get_application_stylesheet
from openlp.core.ui.style import get_application_stylesheet, set_windows_darkmode
from openlp.core.version import check_for_update, get_version
@ -118,6 +118,9 @@ class OpenLP(QtCore.QObject, LogMixin):
self.backup_on_upgrade(has_run_wizard, can_show_splash)
# start the main app window
loader()
# Set the darkmode for windows is enabled
if is_win():
set_windows_darkmode(app)
self.main_window = MainWindow()
self.main_window.installEventFilter(self.main_window)
# Correct stylesheet bugs
@ -330,6 +333,10 @@ def main():
# Bug #1018855: Set the WM_CLASS property in X11
if not is_win() and not is_macosx():
qt_args.append('OpenLP')
elif is_win():
# support dark mode on windows 10. This makes the titlebar dark, the rest is setup later
# by calling set_windows_darkmode
qt_args.extend(['-platform', 'windows:darkmode=1'])
# Initialise the resources
qInitResources()
# Now create and actually run the application.

View File

@ -26,7 +26,7 @@ from datetime import datetime, timedelta
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import SlideLimits
from openlp.core.common import SlideLimits, is_win
from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import UiStrings, format_time, translate
from openlp.core.lib.settingstab import SettingsTab
@ -116,7 +116,7 @@ class AdvancedTab(SettingsTab):
self.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box')
self.ui_layout.addRow(self.enable_auto_close_check_box)
self.left_layout.addWidget(self.ui_group_box)
if HAS_DARK_STYLE:
if not is_win() and HAS_DARK_STYLE:
self.use_dark_style_checkbox = QtWidgets.QCheckBox(self.ui_group_box)
self.use_dark_style_checkbox.setObjectName('use_dark_style_checkbox')
self.ui_layout.addRow(self.use_dark_style_checkbox)
@ -292,7 +292,7 @@ class AdvancedTab(SettingsTab):
'Auto-scroll the next slide to bottom'))
self.enable_auto_close_check_box.setText(translate('OpenLP.AdvancedTab',
'Enable application exit confirmation'))
if HAS_DARK_STYLE:
if not is_win() and HAS_DARK_STYLE:
self.use_dark_style_checkbox.setText(translate('OpenLP.AdvancedTab', 'Use dark style (needs restart)'))
self.service_name_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Default Service Name'))
self.service_name_check_box.setText(translate('OpenLP.AdvancedTab', 'Enable default service name'))
@ -363,7 +363,7 @@ class AdvancedTab(SettingsTab):
if self.autoscroll_map[i] == autoscroll_value and i < self.autoscroll_combo_box.count():
self.autoscroll_combo_box.setCurrentIndex(i)
self.enable_auto_close_check_box.setChecked(self.settings.value('advanced/enable exit confirmation'))
if HAS_DARK_STYLE:
if not is_win() and HAS_DARK_STYLE:
self.use_dark_style_checkbox.setChecked(self.settings.value('advanced/use_dark_style'))
self.hide_mouse_check_box.setChecked(self.settings.value('advanced/hide mouse'))
self.service_name_day.setCurrentIndex(self.settings.value('advanced/default service day'))
@ -437,7 +437,7 @@ class AdvancedTab(SettingsTab):
self.settings_form.register_post_process('config_screen_changed')
self.settings_form.register_post_process('slidecontroller_update_slide_limits')
self.settings.setValue('advanced/search as type', self.is_search_as_you_type_enabled)
if HAS_DARK_STYLE:
if not is_win() and HAS_DARK_STYLE:
self.settings.setValue('advanced/use_dark_style', self.use_dark_style_checkbox.isChecked())
self.proxy_widget.save()

View File

@ -21,7 +21,7 @@
"""
The :mod:`~openlp.core.ui.dark` module looks for and loads a dark theme
"""
from PyQt5 import QtGui, QtWidgets
from PyQt5 import QtCore, QtGui, QtWidgets
from openlp.core.common import is_win
from openlp.core.common.registry import Registry
@ -76,6 +76,41 @@ QProgressBar{
"""
def set_windows_darkmode(app):
"""
Setup darkmode on the application if enabled in the OS (windows) settings
Source: https://github.com/worstje/manuskript/blob/develop/manuskript/main.py (GPL3)
"""
theme_settings = QtCore.QSettings('HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Themes'
'\\Personalize',
QtCore.QSettings.NativeFormat)
if theme_settings.value('AppsUseLightTheme') == 0:
app.setStyle('Fusion')
dark_palette = QtGui.QPalette()
dark_color = QtGui.QColor(45, 45, 45)
disabled_color = QtGui.QColor(127, 127, 127)
dark_palette.setColor(QtGui.QPalette.Window, dark_color)
dark_palette.setColor(QtGui.QPalette.WindowText, QtCore.Qt.white)
dark_palette.setColor(QtGui.QPalette.Base, QtGui.QColor(18, 18, 18))
dark_palette.setColor(QtGui.QPalette.AlternateBase, dark_color)
dark_palette.setColor(QtGui.QPalette.ToolTipBase, QtCore.Qt.white)
dark_palette.setColor(QtGui.QPalette.ToolTipText, QtCore.Qt.white)
dark_palette.setColor(QtGui.QPalette.Text, QtCore.Qt.white)
dark_palette.setColor(QtGui.QPalette.Disabled, QtGui.QPalette.Text, disabled_color)
dark_palette.setColor(QtGui.QPalette.Button, dark_color)
dark_palette.setColor(QtGui.QPalette.ButtonText, QtCore.Qt.white)
dark_palette.setColor(QtGui.QPalette.Disabled, QtGui.QPalette.ButtonText, disabled_color)
dark_palette.setColor(QtGui.QPalette.BrightText, QtCore.Qt.red)
dark_palette.setColor(QtGui.QPalette.Link, QtGui.QColor(42, 130, 218))
dark_palette.setColor(QtGui.QPalette.Highlight, QtGui.QColor(42, 130, 218))
dark_palette.setColor(QtGui.QPalette.HighlightedText, QtCore.Qt.black)
dark_palette.setColor(QtGui.QPalette.Disabled, QtGui.QPalette.HighlightedText, disabled_color)
# Fixes ugly (not to mention hard to read) disabled menu items.
# Source: https://bugreports.qt.io/browse/QTBUG-10322?focusedCommentId=371060#comment-371060
dark_palette.setColor(QtGui.QPalette.Disabled, QtGui.QPalette.Light, QtCore.Qt.transparent)
app.setPalette(dark_palette)
def get_application_stylesheet():
"""
Return the correct application stylesheet based on the current style and operating system
@ -83,7 +118,7 @@ def get_application_stylesheet():
:return str: The correct stylesheet as a string
"""
stylesheet = ''
if HAS_DARK_STYLE and Registry().get('settings').value('advanced/use_dark_style'):
if not is_win() and HAS_DARK_STYLE and Registry().get('settings').value('advanced/use_dark_style'):
stylesheet = qdarkstyle.load_stylesheet_pyqt5()
else:
if not Registry().get('settings').value('advanced/alternate rows'):

View File

@ -31,10 +31,12 @@ from openlp.core.ui.style import MEDIA_MANAGER_STYLE, WIN_REPAIR_STYLESHEET, get
@skipIf(not hasattr(openlp.core.ui.style, 'qdarkstyle'), 'qdarkstyle is not installed')
@patch('openlp.core.ui.style.HAS_DARK_STYLE', True)
@patch('openlp.core.ui.style.is_win')
@patch('openlp.core.ui.style.qdarkstyle')
def test_get_application_stylesheet_dark(mocked_qdarkstyle, mock_settings):
def test_get_application_stylesheet_dark(mocked_qdarkstyle, mocked_is_win, mock_settings):
"""Test that the dark stylesheet is returned when available and enabled"""
# GIVEN: We're on Windows and no dark style is set
# GIVEN: We're not on Windows and dark style is set
mocked_is_win.return_value = False
mocked_settings = MagicMock()
mocked_settings.value.return_value = True
mock_settings.return_value = mocked_settings
@ -52,7 +54,7 @@ def test_get_application_stylesheet_dark(mocked_qdarkstyle, mock_settings):
@patch('openlp.core.app.QtWidgets.QApplication.palette')
def test_get_application_stylesheet_not_alternate_rows(mocked_palette, mocked_is_win, mock_settings):
"""Test that the alternate rows stylesheet is returned when enabled in settings"""
# GIVEN: We're on Windows and no dark style is set
# GIVEN: We're not on Windows and no dark style is set
mocked_is_win.return_value = False
mock_settings.value.return_value = False
mocked_palette.return_value.color.return_value.name.return_value = 'color'