Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 50 additions & 11 deletions gitfourchette/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class GFApplication(QApplication):
qtbaseTranslator: QTranslator
tempDir: QTemporaryDir
platformDefaultStyleName: str
platformDefaultPalette: QPalette
restyling: bool = False
"""Re-entrance guard for onRestyle()."""

# Heavyweight state
mainWindow: MainWindow | None
Expand Down Expand Up @@ -98,8 +101,9 @@ def __init__(self, argv: list[str], barebones=False):
if not (MACOS and APP_FREEZE_COMMIT):
self.setWindowIcon(QIcon("assets:icons/gitfourchette.png"))

# Get system default style name before applying further styling
# Get system default style & palette before applying further styling
self.platformDefaultStyleName = self.style().objectName()
self.platformDefaultPalette = QPalette(self.palette())

# Install translators for system language
# (for command line parser to display localized text)
Expand Down Expand Up @@ -449,6 +453,7 @@ def _applyPrefs(self, prefDiff: dict[str, Any], writeNow=False):

if "qtStyle" in prefDiff:
self.applyQtStylePref(forceApplyDefault=True)
self.restyle.emit()
Comment thread
ciansen marked this conversation as resolved.

if "language" in prefDiff:
self.applyLanguagePref()
Expand Down Expand Up @@ -489,12 +494,28 @@ def applyLanguagePref(self):

def applyQtStylePref(self, forceApplyDefault: bool):
from gitfourchette import settings
from gitfourchette import themes

themeColors = themes.resolveTheme(settings.prefs.qtStyle, self.platformDefaultPalette)

if settings.prefs.qtStyle:
if themeColors is not None:
# Our themes are designed on top of Fusion. Native styles (Breeze,
# Windows, macOS) ignore or mangle much of the stylesheet.
self.setStyle("Fusion")
elif settings.prefs.qtStyle:
self.setStyle(settings.prefs.qtStyle)
elif forceApplyDefault:
self.setStyle(self.platformDefaultStyleName)

# Note: setStyle() resets the palette, so this must come after it.
if themeColors is not None:
self.setPalette(themes.buildPalette(themeColors))
else:
# Empty palette: let the style/desktop provide the colors again.
# (Don't restore platformDefaultPalette - it may be stale if the
# user has changed their system palette while the app is running.)
self.setPalette(QPalette())

if MACOS:
self.setAttribute(Qt.ApplicationAttribute.AA_DontShowIconsInMenus, settings.qtIsNativeMacosStyle())

Expand Down Expand Up @@ -594,21 +615,39 @@ def eventFilter(self, watched, event: QEvent):
# -------------------------------------------------------------------------

def onRestyle(self):
from gitfourchette import settings
from gitfourchette import themes
from gitfourchette.toolbox.iconbank import clearStockIconCache
from gitfourchette.toolbox.qtutils import isDarkTheme
from gitfourchette.syntax.colorscheme import ColorScheme

# Force RecolorSvgIconEngine to re-render the icons
clearStockIconCache()
QPixmapCache.clear()
# setStyleSheet() below may alter the main window's effective palette,
# which sends us right back here through the PaletteChange event filter.
# Bail out instead of recursing until the stack blows up.
if self.restyling:
return
self.restyling = True

try:
# Force RecolorSvgIconEngine to re-render the icons
clearStockIconCache()
QPixmapCache.clear()

styleSheet = Path(QFile("assets:style.qss").fileName()).read_text()
if isDarkTheme(): # Append dark override
darkSupplement = Path(QFile("assets:style-dark.qss").fileName()).read_text()
styleSheet += darkSupplement

# Append our own theme, if any (its rules take precedence over the above)
themeColors = themes.resolveTheme(settings.prefs.qtStyle, self.platformDefaultPalette)
if themeColors is not None:
styleSheet += themes.buildStyleSheet(themeColors)

styleSheet = Path(QFile("assets:style.qss").fileName()).read_text()
if isDarkTheme(): # Append dark override
darkSupplement = Path(QFile("assets:style-dark.qss").fileName()).read_text()
styleSheet += darkSupplement
self.setStyleSheet(styleSheet)
self.setStyleSheet(styleSheet)

ColorScheme.refreshFallbackScheme()
ColorScheme.refreshFallbackScheme()
finally:
self.restyling = False

# -------------------------------------------------------------------------
# Utilities
Expand Down
Loading