Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Listener for dark mode switch? #14

Closed
ribeaud opened this issue Sep 23, 2021 · 11 comments
Closed

Listener for dark mode switch? #14

ribeaud opened this issue Sep 23, 2021 · 11 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@ribeaud
Copy link

ribeaud commented Sep 23, 2021

Hi. I am using your very useful library to know whether dark mode has been switched on on a specific target system.

I was wondering if you plan to implement kind of listener. The problem I am currently having: if the OS switches the dark mode while the application is running, the application does not get notified about it. Only code being executed on-runtime, after the switch, will be able to fetch the newest value of the mode.

I hope, my explanation was clear enough. Otherwise, kindly let me know.

Best regards,

christian

@albertosottile albertosottile added the enhancement New feature or request label Oct 14, 2021
@albertosottile
Copy link
Owner

i actually have no plans in this regard. This could be a nice enhancement indeed, however I foresee a lot of work and I am not even sure this is possible in pure Python and for all the platform.

Personally, I could invest some time for macOS, but I am not sure when I will have enough capacity for doing this.

Nevertheless, PRs in this direction are more than welcome.

@albertosottile albertosottile added the help wanted Extra attention is needed label Oct 14, 2021
@albertosottile
Copy link
Owner

albertosottile commented Oct 17, 2021

Just FYI, this is something that is easily doable in PySide2 (and I guess pyqt5):

import darkdetect

from PySide2 import QtCore, QtWidgets

class LabelHandler():
    def __init__(self):
        self.label = QtWidgets.QLabel(f'Mode: {darkdetect.theme()}')

    @QtCore.Slot(str)
    def mode_change(self):
        self.label.setText(f'Mode: {darkdetect.theme()}')

if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    win = QtWidgets.QWidget()
    layout = QtWidgets.QVBoxLayout()

    lh = LabelHandler()
    layout.addWidget(lh.label)

    app.paletteChanged.connect(lh.mode_change)

    win.setLayout(layout)
    win.show()
    app.exec_()

Darkdetect was mostly created to overcome the limitations of GUI libraries, and detecting this change on the fly seems to be supported by (at least some) of them. I would encourage you to check whether this listener detection is supported in the library of your choice.

@TransparentLC
Copy link
Contributor

TransparentLC commented Apr 26, 2022

On Windows the dark mode setting is stored in registry key HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize DWORD AppsUseLightTheme. I found a WIN32 API function named RegNotifyChangeKeyValue which makes notifies about changes to a specified registry key. Perhaps a native pyd extension is required but I'm not familiar with WIN32 APIs.

@TransparentLC
Copy link
Contributor

TransparentLC commented Apr 28, 2022

I forked this repo and commited the native extension's code to add a listener function on Windows. Pass a callback function and it will be called with string "Dark" or "Light" when the OS switches the dark mode setting. On Linux and macOS it simply raises a NotImplementedError.

The listener is an infinite loop so a separated thread is required. However the thread is unstoppable so I think the API design and the implementation can be further improved.

Usage example:

import darkdetect, threading
# def listener(callback: typing.Callable[[str], None]) -> None: ...
t = threading.Thread(target=darkdetect.listener, args=(print,))
t.daemon = True
t.start()

Try it out by cloning it and install with command python setup.py build_ext --inplace and python setup.py install.

@TransparentLC
Copy link
Contributor

6b14eac9426ebd51311e7c4e848cb898.mp4

I guess we can spawn a subprocess gsettings monitor org.gnome.desktop.interface gtk-theme and read its output to detect dark mode switch on Linux. I'll try to add it to my fork (and the pull request).

@TransparentLC
Copy link
Contributor

@albertosottile I also found a solution for macOS: Golang: Detect dark mode change in OSX

@albertosottile
Copy link
Owner

albertosottile commented May 22, 2022

@albertosottile I also found a solution for macOS: Golang: Detect dark mode change in OSX

The detection method based on defaults read -g AppleInterfaceStyle is less reliable than the one implemented in darkdetect ([[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]).

In principle, Foundation allows monitoring values from NSUserDefaults with callbacks, but I was not able to get this working via ctypes when I tried.

For the moment, I would merge your PR as it is. We can then continue investigating if callback can be implemented on macOS with the NSUserDefaults-based detection method.

@TransparentLC
Copy link
Contributor

Just Googled for any available solutions and I don't have any device running macOS. So I'm afraid I can't provide further help for implementation for macOS.

@albertosottile
Copy link
Owner

The listeners for Windows and Linux were released in 0.6.0. I will keep this issue open for macOS.

@albertosottile
Copy link
Owner

I invested a lot of time in trying to implement a listener for macOS and failed miserably. Since I want to add more information on what I tried (in view of helping further people that might venture through the same path) I am now closing this issue and putting the macOS endeavor in #25.

@TransparentLC thanks again for having implemented the listeners for Windows and Linux!

@ribeaud
Copy link
Author

ribeaud commented Jul 19, 2022

Many thanks to all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants