forked from openlp/openlp
Implement support for windows 10 dark mode, fixes #370.
This commit is contained in:
parent
f09ce2fed0
commit
64b62c4f59
@ -36,7 +36,7 @@ from pathlib import Path
|
|||||||
from shutil import copytree
|
from shutil import copytree
|
||||||
from traceback import format_exception
|
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.api.deploy import check_for_remote_update
|
||||||
from openlp.core.common import is_macosx, is_win
|
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.firsttimelanguageform import FirstTimeLanguageForm
|
||||||
from openlp.core.ui.mainwindow import MainWindow
|
from openlp.core.ui.mainwindow import MainWindow
|
||||||
from openlp.core.ui.splashscreen import SplashScreen
|
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
|
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)
|
self.backup_on_upgrade(has_run_wizard, can_show_splash)
|
||||||
# start the main app window
|
# start the main app window
|
||||||
loader()
|
loader()
|
||||||
|
# Set the darkmode for windows is enabled
|
||||||
|
if is_win():
|
||||||
|
set_windows_darkmode(app)
|
||||||
self.main_window = MainWindow()
|
self.main_window = MainWindow()
|
||||||
self.main_window.installEventFilter(self.main_window)
|
self.main_window.installEventFilter(self.main_window)
|
||||||
# Correct stylesheet bugs
|
# Correct stylesheet bugs
|
||||||
@ -330,6 +333,10 @@ def main():
|
|||||||
# Bug #1018855: Set the WM_CLASS property in X11
|
# Bug #1018855: Set the WM_CLASS property in X11
|
||||||
if not is_win() and not is_macosx():
|
if not is_win() and not is_macosx():
|
||||||
qt_args.append('OpenLP')
|
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
|
# Initialise the resources
|
||||||
qInitResources()
|
qInitResources()
|
||||||
# Now create and actually run the application.
|
# Now create and actually run the application.
|
||||||
|
@ -26,7 +26,7 @@ from datetime import datetime, timedelta
|
|||||||
|
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
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.applocation import AppLocation
|
||||||
from openlp.core.common.i18n import UiStrings, format_time, translate
|
from openlp.core.common.i18n import UiStrings, format_time, translate
|
||||||
from openlp.core.lib.settingstab import SettingsTab
|
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.enable_auto_close_check_box.setObjectName('enable_auto_close_check_box')
|
||||||
self.ui_layout.addRow(self.enable_auto_close_check_box)
|
self.ui_layout.addRow(self.enable_auto_close_check_box)
|
||||||
self.left_layout.addWidget(self.ui_group_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 = QtWidgets.QCheckBox(self.ui_group_box)
|
||||||
self.use_dark_style_checkbox.setObjectName('use_dark_style_checkbox')
|
self.use_dark_style_checkbox.setObjectName('use_dark_style_checkbox')
|
||||||
self.ui_layout.addRow(self.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'))
|
'Auto-scroll the next slide to bottom'))
|
||||||
self.enable_auto_close_check_box.setText(translate('OpenLP.AdvancedTab',
|
self.enable_auto_close_check_box.setText(translate('OpenLP.AdvancedTab',
|
||||||
'Enable application exit confirmation'))
|
'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.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_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Default Service Name'))
|
||||||
self.service_name_check_box.setText(translate('OpenLP.AdvancedTab', 'Enable 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():
|
if self.autoscroll_map[i] == autoscroll_value and i < self.autoscroll_combo_box.count():
|
||||||
self.autoscroll_combo_box.setCurrentIndex(i)
|
self.autoscroll_combo_box.setCurrentIndex(i)
|
||||||
self.enable_auto_close_check_box.setChecked(self.settings.value('advanced/enable exit confirmation'))
|
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.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.hide_mouse_check_box.setChecked(self.settings.value('advanced/hide mouse'))
|
||||||
self.service_name_day.setCurrentIndex(self.settings.value('advanced/default service day'))
|
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('config_screen_changed')
|
||||||
self.settings_form.register_post_process('slidecontroller_update_slide_limits')
|
self.settings_form.register_post_process('slidecontroller_update_slide_limits')
|
||||||
self.settings.setValue('advanced/search as type', self.is_search_as_you_type_enabled)
|
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.settings.setValue('advanced/use_dark_style', self.use_dark_style_checkbox.isChecked())
|
||||||
self.proxy_widget.save()
|
self.proxy_widget.save()
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
"""
|
"""
|
||||||
The :mod:`~openlp.core.ui.dark` module looks for and loads a dark theme
|
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 import is_win
|
||||||
from openlp.core.common.registry import Registry
|
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():
|
def get_application_stylesheet():
|
||||||
"""
|
"""
|
||||||
Return the correct application stylesheet based on the current style and operating system
|
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
|
:return str: The correct stylesheet as a string
|
||||||
"""
|
"""
|
||||||
stylesheet = ''
|
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()
|
stylesheet = qdarkstyle.load_stylesheet_pyqt5()
|
||||||
else:
|
else:
|
||||||
if not Registry().get('settings').value('advanced/alternate rows'):
|
if not Registry().get('settings').value('advanced/alternate rows'):
|
||||||
|
@ -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')
|
@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.HAS_DARK_STYLE', True)
|
||||||
|
@patch('openlp.core.ui.style.is_win')
|
||||||
@patch('openlp.core.ui.style.qdarkstyle')
|
@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"""
|
"""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 = MagicMock()
|
||||||
mocked_settings.value.return_value = True
|
mocked_settings.value.return_value = True
|
||||||
mock_settings.return_value = mocked_settings
|
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')
|
@patch('openlp.core.app.QtWidgets.QApplication.palette')
|
||||||
def test_get_application_stylesheet_not_alternate_rows(mocked_palette, mocked_is_win, mock_settings):
|
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"""
|
"""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
|
mocked_is_win.return_value = False
|
||||||
mock_settings.value.return_value = False
|
mock_settings.value.return_value = False
|
||||||
mocked_palette.return_value.color.return_value.name.return_value = 'color'
|
mocked_palette.return_value.color.return_value.name.return_value = 'color'
|
||||||
|
Loading…
Reference in New Issue
Block a user