mnelab icon indicating copy to clipboard operation
mnelab copied to clipboard

Add theme detection for Windows

Open cbrnr opened this issue 3 years ago • 1 comments

Currently light/dark theme detection works only on macOS. On Windows and Linux, Qt apps still don't have native dark theme support 😞.

cbrnr avatar Mar 20 '21 20:03 cbrnr

Alright, detection works now, but there are two problems (at least as of Qt 5.15.4, I'm still hoping things will improve with PyQt6/PySide6 but I haven't tested this):

  1. Qt doesn't detect theme changes on the fly, only on application start. It seems like there's no QEvent.PaletteChange emitted on Windows and GNOME/Linux.
  2. It seems like there is no built-in Qt dark theme on Windows and GNOME/Linux, because only the icons change with the app theme.

In summary, switching between dark/light modes currently works only on macOS. We could add limited support for Windows and GNOME/Linux by adapting the theme only upon application start. That would at least be better than nothing. To do this, we need to manually change the palette as mentioned here: https://stackoverflow.com/a/56851493/1112283

from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QPalette, QColor

# dark theme
palette = QPalette()
palette.setColor(QPalette.Window, QColor(53, 53, 53))
palette.setColor(QPalette.WindowText, Qt.white)
palette.setColor(QPalette.Base, QColor(25, 25, 25))
palette.setColor(QPalette.AlternateBase, QColor(53, 53, 53))
palette.setColor(QPalette.ToolTipBase, Qt.black)
palette.setColor(QPalette.ToolTipText, Qt.white)
palette.setColor(QPalette.Text, Qt.white)
palette.setColor(QPalette.Button, QColor(53, 53, 53))
palette.setColor(QPalette.ButtonText, Qt.white)
palette.setColor(QPalette.BrightText, Qt.red)
palette.setColor(QPalette.Link, QColor(42, 130, 218))
palette.setColor(QPalette.Highlight, QColor(42, 130, 218))
palette.setColor(QPalette.HighlightedText, Qt.black)
QCoreApplication.instance().setPalette(palette)

# TODO: switch palette back to light theme

Finally, if we decide to integrate these changes for Windows and GNOME/Linux, we should switch to Darkdetect instead of rolling our own interface_style() function.

cbrnr avatar Mar 20 '21 21:03 cbrnr

We could give the Fusion style a shot (on Windows at least), maybe light/dark modes work with that style (https://www.qt.io/blog/dark-mode-on-windows-11-with-qt-6.5).

Edit: Yes, the Fusion style adapts to light and dark modes. The title bar stays light though, and the icons do not use their light variants when in dark mode, so some tweaking is still required. But in principle, adding this line to __init__.py does most of the work:

app.setStyle("Fusion")

cbrnr avatar Dec 14 '23 06:12 cbrnr

Fixed by #398.

cbrnr avatar Dec 28 '23 15:12 cbrnr