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

[Feature Request] org.freedesktop.appearance.color-scheme support to read dark mode preference #17061

Closed
vimpostor opened this issue Oct 5, 2021 · 52 comments · Fixed by #24242

Comments

@vimpostor
Copy link
Contributor

vimpostor commented Oct 5, 2021

Currently the "Follow global dark theme preference" switch on Linux uses an unreliable implementation.
Recently the org.freedesktop.appearance.color-scheme key got standardized across all DEs, which should be more reliable. It would be cool, if Telegram supported reading this setting and super cool if it could subscribe to its changes during runtime.

Useful links:
Gnome blog post
Spec
KDE initial implementation + proper implementation

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Oct 5, 2021

Finally. I'm tired of this dancing with DE-specific keys.

@ilya-fedin
Copy link
Contributor

Well, I implemented that locally, but I will push only when it would be possible to test how it works. Basically, that means 'after support of this preference will land to my desktop'. I have MATE on NixOS on host and a VM with KDE Neon. So, that means a MATE release with that feature in NixOS or a KDE release with that feature in KDE Neon.

@carnage-mode
Copy link

@ilya-fedin I think you can use https://gitlab.gnome.org/exalm/color-scheme-simulator to test the feature

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Oct 9, 2021

Excellent. But there's another problem: IsDarkMode has four implementations and it's already big. I don't really want to add a fifth implementation. And I can't remove the others since I don't feel this spec will have a big adoption outside of GNOME & KDE since it's portal-based.

@carnage-mode
Copy link

Are those four implementations cross platform or Linux specific?

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Oct 9, 2021

Are those four implementations cross platform or Linux specific?

Linux-specific. Both win/mac platform files have only one implementation of IsDarkMode. The Linux one has four implementations.

@carnage-mode
Copy link

Well GNOME and KDE account for the vast majority of Linux. Plus most other Linux DE's don't have their own app ecosystems, they use apps from those two. The only other app ecosystem is elementary, and they already follow the preference elementary/settings-daemon#38 (Telegram's dark mode doesn't really work on elementary rn). I think removing all the other implementations is safe choice. If that doesn't work, reducing the number of implementations and adding org.freedesktop.appearance.color-scheme could.

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Oct 9, 2021

Sorry, but that sounds like a marketing bullshit. Since I'm not in the majority here, don't expect I'll remove these implementations.

@carnage-mode
Copy link

Fair enough 👍

@vimpostor
Copy link
Contributor Author

IsDarkMode has four implementations and it's already big. I don't really want to add a fifth implementation.

The clean way would be to make an upstream Qt patch, such that QGuiApplication::paletteChanged triggers with the new key.
However I am also calling bullshit here and fail to see why adding the new key and keeping the 4 other methods as fallback would be a problem. Worst-case scenario you can remove the most unreliable of the 4 methods and replace it with the new one.

I don't feel this spec will have a big adoption outside of GNOME & KDE since it's portal-based.

Then the other DEs should implement Portal.

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Oct 9, 2021

The clean way would be to make an upstream Qt patch

The feature will reach in multiple years to tdesktop, then. There's no updates for Qt 5 and there's no plan to migrate to Qt 6 in near future.

However I am also calling bullshit here and fail to see why adding the new key and keeping the 4 other methods as fallback would be a problem.

Well, this wouldn't be a problem if someone refactor the code. I don't want to do this right now.

Then the other DEs should implement Portal.

That's not how reality works. In the real world, you have things like anti-dbus cult, DEs that release once in multiple years, the lack of knowledge that new APIs appeared, no plans to implement them in near future and etc. I have a feel MATE/Xfce/LXQt won't have support for that.

@ilya-fedin
Copy link
Contributor

So I finally managed to test with https://gitlab.gnome.org/exalm/color-scheme-simulator. It works. Will look at how KDE implementation lands, looks like it's still not merged. When it lands to a release KDE version, it would be possible to replace Gtk/Wayland (no gtk DEs except of GNOME exist on Wayland and Qt defaults to XWayland on GNOME, so the impact should be minimal) and KDE implementations with this one. But looking at the code in KDE review, their implementation doesn't seem to be good enough: tdesktop checks for color of the window backgroud, while their implementation checks for BreezeDark in color scheme name. I hope there's not so much KDE users using auto-night mode in Telegram. I have a feel this wouldn't work good anywhere outside of GNOME world.

@vimpostor
Copy link
Contributor Author

I agree, the current state of the pending KDE implementation is a disaster, but I am pretty sure it will be implemented properly for whatever release it lands in.

@vimpostor
Copy link
Contributor Author

vimpostor commented Oct 23, 2021

their implementation checks for BreezeDark in color scheme name. I hope there's not so much KDE users using auto-night mode in Telegram. I have a feel this wouldn't work good anywhere outside of GNOME world.

KDE has now properly implemented dark mode detection: https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/merge_requests/52
So this argument should no longer be valid.

Note that this will only make it into KDE 5.24, which will release Thu 2022-01-20, so next year - plenty of time for us to implement this :)

@ilya-fedin
Copy link
Contributor

IIRC GNOME 42 will be in next year as well, so there's no point in replacing the implementations right now given that Telegram releases have no schedule in general and are pretty often

@vimpostor
Copy link
Contributor Author

Yes, sounds good to me. Then let's wait until next year, the API is very new anyway.

@ilya-fedin
Copy link
Contributor

изображение

Looks like we already got differences in standard implementations. GNOME's blog post says that prefer-light is for future use and no preference should be used in light mode, but KDE sets prefer-light.

@vimpostor
Copy link
Contributor Author

Looks like we already got differences in standard implementations. GNOME's blog post says that prefer-light is for future use and no preference should be used in light mode, but KDE sets prefer-light.

That's just a different implementation. The spec does not say anything about whether a specific DE should use "Default" or "Light theme" in this case.
If we follow it this way, it will work with both Gnome and KDE implementation:

  • no-preference: Use light theme
  • prefer-dark: Use dark theme
  • prefer-light: Use light theme

@ilya-fedin
Copy link
Contributor

That's just a different implementation.

But that's just what I said xD

@ilya-fedin
Copy link
Contributor

The spec does not say anything about whether a specific DE should use "Default" or "Light theme" in this case.

As far, as I understand, no-preference means application should use its own default, prefer-dark means application should forcefully use a dark theme, prefer-light means application should forcefully use a light theme. It seems to me it's more sane to have no-preference by default rather than prefer-light.

@vimpostor
Copy link
Contributor Author

it seems to me it's more sane to have no-preference by default rather than prefer-light.

I disagree. If I choose a light theme in my DE, I probably want to have my applications use a light theme and not their own default (possibly dark default).

But that's more a discussion for the DE maintainers anyway. In our case, both are the same anyway, since Telegram Desktop (like most applications) uses light theme by default.

@carnage-mode
Copy link

All PRs on the GNOME and KDE side have been merged. Firefox has implemented this as well.

@vimpostor
Copy link
Contributor Author

All PRs on the GNOME and KDE side have been merged. Firefox has implemented this as well.

Afaik @ilya-fedin has already implemented this in a private branch and will make a PR once it makes sense to do so. FYI the KDE 5.24 release has been postponed to 2022-02-08

@TomiOhl
Copy link

TomiOhl commented Jan 25, 2022

It already does make sense though imo: elementary OS supports this since the summer and they all would be happy if Telegram supported it too :)
Plus at least it could be tested on a smaller user base, so any associated issues could be sorted out before the KDE/Gnome release.

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Jan 25, 2022

Afaik @ilya-fedin has already implemented this in a private branch

I implemented this in a stash 😅

It already does make sense though imo: elementary OS supports this since the summer and they all would be happy if Telegram supported it too :)

I still think that having yet another implementation of IsDarkMode doesn't have sense. So I will wait until the spec become dominant and I will replace all the implementations.

@WhyNotHugo
Copy link
Contributor

I recently released darkman v1.0 which implements the portal spec too -- this provides an implementation of the spec for non-DE users (and should work find on MATE). It would be nice to see support in Telegram.

Also, what are the four specs that Telegram currently does implement? I'd like to consider implementing the desktop side of one of them if it makes Telegram transition along with everything else.

@ilya-fedin
Copy link
Contributor

They're not specs, it's reversed from source code of KDE and gtk

@ilya-fedin
Copy link
Contributor

I really don't like that portals were chosen for this spec. Portals being a D-Bus service can block Telegram starting up to 30 seconds when something goes wrong (this frequently comes from lightweight-configured systems). And this couldn't be avoided since the decision of day/night mode should be done before the window shows.

@vimpostor
Copy link
Contributor Author

vimpostor commented Feb 27, 2022

I really don't like that portals were chosen for this spec. Portals being a D-Bus service can block Telegram starting up to 30 seconds when something goes wrong (this frequently comes from lightweight-configured systems). And this couldn't be avoided since the decision of day/night mode should be done before the window shows.

I disagree, such "lightweight" systems are just misconfigured if they block on simple dbus queries. On my system, if I don't have xdg-desktop-portal installed, the dbus query fails immediately instead of blocking:

qdbus org.freedesktop.portal.Desktop /org/freedesktop/portal/desktop org.freedesktop.portal.Settings.Read "org.freedesktop.appearance" "color-scheme"

Cannot find 'org.freedesktop.portal.Settings.Read' in object /org/freedesktop/portal/desktop at org.freedesktop.portal.Desktop

If the dbus call blocks, Telegram's code is not wrong, it's the other way around: They have a misconfigured setup.

@ilya-fedin
Copy link
Contributor

Anyway, this is a headache that people go here and don't believe this is not tdesktop fault. So I don't like this, it's a headache for me. Those people just can't design an API in a sane way that won't have such problems when something is misconfigured.

@vimpostor
Copy link
Contributor Author

vimpostor commented Feb 27, 2022

Those people just can't design an API in a sane way that won't have such problems when something is misconfigured.

The API is designed in a sane way. No API can really be resistant against the kind of users that think their setup is somehow minimalistic or lightweight, because they actively remove basic functionality. I think you will get more headaches if you care about those users.
Also I somehow doubt that you get more headache from this defacto sane API than from reverse-engineering 4 different DE-dependent implementations...

Besides the API works in both imaginable scenarios:

  • xdg-desktop-portal dbus is available: Everything works
  • xdg-desktop-portal is not installed/unavailable: Dbus returns immediately with an error

People have to actively sabotage their setup to get the blocking behaviour.

@ilya-fedin
Copy link
Contributor

Well, I never saw a 30-sec timeout from Windows/macOS/X/Wayland APIs... Only D-Bus is so special.

@WhyNotHugo
Copy link
Contributor

They're not specs, it's reversed from source code of KDE and gtk

Do you have any pointers on how to implement the server aspect of one of these protocol? If telegram won't add portal support, then I'd like to implement one of these protocol on my side.

Portals being a D-Bus service can block Telegram starting up to 30 seconds when something goes wrong

This happened recently due to two services having a circular dependency on each other. The 30 timeout is to detect deadlocks. This can happen to ANY service, including notification daemon, however, it's a serious guy and wasn't due to user misconfiguration. I understand the frustration here, but it was simply an upstream bug. A notification daemon can have the same issue tomorrow and also block for 30 seconds (though I sincerely hope this kind of regression won't pop up again soon).

And this couldn't be avoided since the decision of day/night mode should be done before the window shows.

The window can be shown right away, and update whenever the daemon responds. This is a very common approach for this kind of thing.

@ilya-fedin
Copy link
Contributor

The window can be shown right away, and update whenever the daemon responds. This is a very common approach for this kind of thing.

Then people will create bugs that they see the window in day mode for a second and this harms their eyes

@ilya-fedin
Copy link
Contributor

This happened recently due to two services having a circular dependency on each other. The 30 timeout is to detect deadlocks. This can happen to ANY service, including notification daemon, however, it's a serious guy and wasn't due to user misconfiguration. I understand the frustration here, but it was simply an upstream bug. A notification daemon can have the same issue tomorrow and also block for 30 seconds (though I sincerely hope this kind of regression won't pop up again soon).

btw, I have a friend who have a long-starting portals service even with xdg-desktop-portal from master. He created an issue, but was ignored by portal developers (flatpak/xdg-desktop-portal#701). I, too, have two issues opened at xdg-desktop-portal repo, one of them is one year old and is still ignored. Also, I remember a KDE developer wanted to add quick-reply to the notifications spec, then GNOEM folks forced him to ask portal folks, he created and issue and... guess what? They ignored him for a year, then he gave up and closed the issue at xdg-desktop-portal repo, closed the PR at xdg-specs repo and this feature became KDE-specific.

@vimpostor
Copy link
Contributor Author

vimpostor commented Feb 27, 2022

Also, I remember a KDE developer wanted to add quick-reply to the notifications spec, then GNOEM folks forced him to ask portal folks, he created and issue and... guess what? They ignored him for a year, then he gave up and closed the issue at xdg-desktop-portal repo, closed the PR at xdg-specs repo and this feature became KDE-specific.

Gnome developers defining these specs after their own narrow view of an ideal world seems to be a recurring theme... Just look at Wayland defining the scaling factor as int, just because GTK does not properly support fractional scaling at all (even though other UI toolkits support it).
Another ridiculous example is Gnome devs dunking on good proposals for the new System Tray spec, just because they personally don't see any usecase for a system tray whatsoever in their narrow ideal view.

Coming back to the issue, what if we use org.freedesktop.appearance.color-scheme just for runtime dark mode change listening and keep the initial detection on startup as is. We are doing something similar in Keepass
Connecting to dbus signals should not block in any case (I think?)

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Feb 27, 2022

nother ridiculous example is Gnome devs dunking on good proposals for the new System Tray spec, just because they personally don't see any usecase for a system tray whatsoever in their narrow ideal view.

I also like this discussion, I call it 'census of clowns'. Instead of developing a sane wide-applicable API like hints in X11, one of them implements a protocol especially for PiPs (lol) and then others want make this a portal API and enforce drawing of controls on compositor side. 🙈

It seems both xdg-specs and wayland-protocols taken over by GNOME folks.

Coming back to the issue, what if we use org.freedesktop.appearance.color-scheme just for runtime dark mode change listening and keep the initial detection on startup as is. We are doing something similar in Keepass
Connecting to dbus signals should not block in any case (I think?)

This is not a blocker, what a blocker is backward compatibility. I don't really want to have five implementations and this spec is supported only by the latest release of KDE yet. GNOME is not released, an Ubuntu LTS release with those DE versions is not released, too (as far as I heard KDE 5.24 won't be in Ubuntu 22.04, so it means Ubuntu 24.04 for KDE). This will create a lot of bug reports that the feature stopped to work.

@ilya-fedin
Copy link
Contributor

Latest Telegram release is still used by people who use Linux Mint 17, btw

@vimpostor
Copy link
Contributor Author

vimpostor commented Feb 27, 2022

I also like this discussion, I call it 'census of clowns'.

This is not just a clown, this seems to be the entire circus...
BTW this is just another sideeffect of defining your display protocol so secure that you have to define a workaround for literally every possible usecase. Funnily enough most of these usecases requiring workarounds are not even of obscure nature (like maybe weird xdotool usecases), but are basic accessibility such as Screen Readers or Autotype support for PW managers.

It seems both xdg-specs and wayland-protocols taken over by GNOME folks.

I agree and I have personally come to terms with it by seeing it as an advantage as this will ensure that Wayland will also not become widely adopted in the next 10 years, which honestly is a good thing with all the problems around Wayland.

This is not a blocker, what a blocker is backward compatibility. I don't really want to have five implementations and this spec is supported only by the latest release of KDE yet. GNOME is not released, an Ubuntu LTS release with those DE versions is not released, too (as far as I heard KDE 5.24 won't be in Ubuntu 22.04, so it means Ubuntu 24.04 for KDE). This will create a lot of bug reports that the feature stopped to work.

My personal opinion is that I usually don't care about users of very old LTS distros and it is always better to follow the latest standards, but I acknowledge that my view is a bit extreme and see that a widely used program like Telegram cannot just ignore these users.
So maybe we should indeed wait a year or so before implementing this spec...

@ilya-fedin
Copy link
Contributor

I want to wait until GNOME 42 release at least. But will see how it's all goes on...

@WhyNotHugo
Copy link
Contributor

Cccc

Then people will create bugs that they see the window in day mode for a second and this harms their eyes

Quite true

Gnome developers defining these specs after their own narrow view of an ideal world seems to be a recurring theme... Just look at Wayland defining the scaling factor as int, just because GTK does not properly support fractional scaling at all (even though other UI toolkits support it).

This is also sadly very true. I tried to participate in the dark mode API discussion but was ignored. They decided to agree on it behind closed doors and not allow others to participate. It's not a very healthy attitude for the open source community.

Coming back to the issue, what if we use org.freedesktop.appearance.color-scheme just for runtime dark mode change listening and keep the initial detection on startup as is.

Is this a DBus API or what? Can you explain how it works? It seems telegram is the client for a protocol, and I'd like to implement the server side of it. I don't really care if you implement the portal spec or some other spec, I mostly just want to understand how to integrate with it. This one, or one of the other 3 ones you mentioned.

It just bothers me that telegram is permanently in dark mode and I struggle to read on sunny days -- it has four ways of switching mode automatically, so pointers to any of these protocols would be enough really.

It seems both xdg-specs and wayland-protocols taken over by GNOME folks.

Yup, and if your usage or UI differs from theirs, your just wrong 😔

@ilya-fedin
Copy link
Contributor

@TomiOhl
Copy link

TomiOhl commented Feb 27, 2022

Elementary OS user here. Auto dark mode in telegram never worked. Not even for a minute. No surprise. Stable elementary supports freedesktop color-scheme since last August. Half a year already. Feel like it's a bit weird to miss out on a feature because the DE I use is too new even though it's an LTS version. Yes, some people are still using Mint 17... So are we gonna keep everything as is because some users are too lazy to update from decade old systems? Let's put it the other way: do such users even care?

Just thinking out loud, no need to answer. I even understand why would it be okay to wait at least for the next Ubuntu LTS. But that should probably be the date to update. Some people on older versions will open an issue if the functionality breaks for them, sure... So they can be informed and issue closed, no big deal imo.

Just my 2 cents

@WhyNotHugo
Copy link
Contributor

@ilya-fedin Thanks for the pointer. As far as I can see, the implementations are:

  • Monitor changes to the KDE theme via the xdg-desktop portal, and determine if the Qt theme background is darker than a given value. Ignored if the theme is QFusionStyle.
  • Something X11-specific (not applicable in this case).
  • Monitor changes to the GTK theme via the xdg-desktop portal, and determine if its name ends in -dark.
  • Check the KDE background via the settings portal org.kde.kdeglobals.Colors:Window, BackgroundNormal, and determine if it's darker than a given value.

(1) is very KDE and Qt specific and cannot be really re-used outside that context. Re-implementing the KDE portal aspect of it sounds doable, but it then reads a Qt theme, so no hacking possible there.
(2) Is not applicable to Wayland, so not relevant.
(3) Is pretty close to working. My light day GTK theme is Arc-Darker, and my dark theme is Arc-Dark.
(4) Cannot be used if any of the above match, so not getting into it further.

I notice that (3) is actually failing in my case due to how the name is checked. Replacing .contains with .endsWith here should fix it. I can make a PR for this if it sound good to you.

@WhyNotHugo
Copy link
Contributor

BTW, looks like this already relies on the xdg-desktop-portal and specifically, uses org.freedesktop.portal.Settings.Read under the hood, which is the exact same method used to read the new dark-theme spec. If this portal were to have a startup delay due to a bug (as discussed above), Telegram is already susceptible to the 30s delay anyway. There's no new runtime dependency here.

@ilya-fedin
Copy link
Contributor

  • Monitor changes to the KDE theme via the xdg-desktop portal, and determine if the Qt theme background is darker than a given value. Ignored if the theme is QFusionStyle.

Qt theme, not KDE theme. QFusionStyle/QWindowsStyle are Qt's built-in themes and out-of-interest, it usually means theming is unconfigured and thus the option shouldn't be presented in Telegram UI.

  • Something X11-specific (not applicable in this case).

It's the gtk's method of getting settings on X11. Most people configure Telegram's mode with this protocol, lightweight enviroments use xsettingsd.

(2) Is not applicable to Wayland, so not relevant.

Are you throwing out 93% (X) users of Linux?

Replacing .contains with .endsWith here should fix it.

I don't understand how endsWith is better here. contains will find -dark in any postition in a string, endsWith only in the end.

Telegram is already susceptible to the 30s delay anyway.

Yeah, that's what I don't like. Previously it was only due to KDE/GNOME, now it's standardized.

@WhyNotHugo
Copy link
Contributor

Are you throwing out 93% (X) users of Linux?

I meant it's not relevant for my own setup, so I'm ignoring it cause it won't get me anywhere. It's surely of value for X11 users and will continue to be for a while.

Yeah, that's what I don't like. Previously it was only due to KDE/GNOME, now it's standardized.

The portals are not KDE/GNOME specific. They're required by browsers (and others) on any Wayland compositor for things like screen sharing. They're also required by things like Flatpak.

More on point: Telegram already tries to use the portals on any desktop to read Qt and Gtk settings. Trying to read an additional setting introduces no new dependency; it literally calls the same method with different parameters.

Currently KDE and GNOME are guaranteed to have the portal, and other setups vary, but if the settings portal is present, Telegram already tries to use it on any desktop.

I don't understand how endsWith is better here. contains will find -dark in any postition in a string, endsWith only in the end.

Because contains matches a false-positive in this case, but endsWith wouldn't match that. Note that Arc-Darker only has dark accents but is a light theme (e.g: its backgrounds are white). It's a bit of an unfortunate naming convention I'll admit, but it is what it is.

@ilya-fedin
Copy link
Contributor

The portals are not KDE/GNOME specific.

The settings keys are

They're required by browsers (and others) on any Wayland compositor for things like screen sharing.

This is one of Wayland API design faults, though...

Trying to read an additional setting introduces no new dependency; it literally calls the same method with different parameters.

I'm saying that earlier there was a hope that maybe sometime a standardized protocol become and this mess will end. But now it's clear this 30-sec thingie is forever.

Because contains matches a false-positive in this case, but endsWith wouldn't match that

There are names like "Materia-dark-compact"

@WhyNotHugo
Copy link
Contributor

This is one of Wayland API design faults, though...

I've no idea why screensharing and screenshotting is implemented the way it is TBH. The excuse seems to be for containerisation support, but there are simpler ways to handle security contexts (e.g.: creating separate sockets with less priviledges for a sandboxed client).

I'm saying that earlier there was a hope that maybe sometime a standardized protocol become and this mess will end. But now it's clear this 30-sec thingie is forever.

Yeah, this dark mode thing could well have been its own standard name and support multiple implementations (e.g.: like notifications). OTOH, even a badly implemented notification daemon can deadlock for 30' when starting up.

There are names like "Materia-dark-compact"

Maybe match endsWith("-dark") || contains("-dark-")?

@ilya-fedin
Copy link
Contributor

Yeah, this dark mode thing could well have been its own standard name and support multiple implementations (e.g.: like notifications). OTOH, even a badly implemented notification daemon can deadlock for 30' when starting up.

Any D-Bus service would have such a problem, so there was a hope it can be an X/Wayland protocol.

Maybe match endsWith("-dark") || contains("-dark-")?

Should work

@WhyNotHugo
Copy link
Contributor

WhyNotHugo commented Mar 2, 2022

Any D-Bus service would have such a problem, so there was a hope it can be an X/Wayland protocol.

Gtk and Notifications already depend on the portal. Not sure about Qt, but I think it does too.


Opened a PR for the other tweak.

@ilya-fedin
Copy link
Contributor

ilya-fedin commented Mar 2, 2022

Gtk and Notifications already depend on the portal. Not sure about Qt, but I think it does too.

Qt's portal support is very basic. It supports only OpenURI and FileChooser portals. I don't quite understand what do you mean by "Notifications already depend on the portal" though.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants