Detect dark application style/theme of currently used desktop in Qt - c++

The bounty expires in 7 days. Answers to this question are eligible for a +50 reputation bounty.
codeling wants to draw more attention to this question:
Give concise information (and ideally code) on how to detect dark theme on KDE and Gnome desktop environments using Qt, or if there is no direct way with Qt, using plain C++ (or at least as little additional libraries as possible).
In our Qt-based C++ application, I'm trying to automatically switch application styles based on whether the user has configured dark or bright theme.
I have figured out the notification of when a change happens (see below, for other's reference).
My main problem is the reliable detection of whether currently a dark or bright theme is used on linux (for windows see below); on XFCE, the check for QPalette color roles as mentioned in this answer works, but this does not work on Gnome and KDE Plasma for me (tested under both Ubuntu 22.04 and Fedora 36, my app built against Qt versions 6.5beta2 and 6.4.2, respectively); there the colors still seem to be taken from what I've set as XFCE theme on the same machine (and when starting xfce4-appearance-settings and changing the theme there, my app picks up the change). I would however like to adapt to the current desktop's dark mode setting.
So, my question is: How do I reliably detect application dark mode of the currently used desktop on Qt? I'm not averse to implementing a little custom platform-specific code if nothing is available directly in Qt, but it would be great if it would work without using additional libraries.
A note I saw for QApplication::setPalette I thought might be relevant here, namely "Some styles do not use the palette for all drawing, for instance, if they make use of native theme engines.", what are these all about? I did not see a link to a documentation for this feature, and a quick search for the term "qt native theme engine" also didn't seem to yield any useful results.
Since on Linux, some events are reliably triggered whenever a system theme change happens (see below), I suppose Qt can detect the theme change, it just doesn't expose data about it publicly?
Getting notified of theme changes
On Linux: via listening for QEvent::StyleChange events of the application's QMainWindow; two caveats and one side note:
That event does, despite QWidget::changeEvent documentation explicitly mentioning it, not trigger a changeEvent (for me), but has to be caught via the more generic QWidget::event
StyleChange only seems to be triggered since some Qt 6.4 version (in my tests, it was not triggered by 5.15.2 and 6.3.1, but triggered for 6.4.2 and 6.5.0beta2).
I've also noticed that there's a ThemeChange event that is also triggered (at the same time as the StyleChange; not sure what the difference is between these two though, and in what case one would be triggered but not the other... I suppose StyleChange is used for any change to the style of a widget, so that it's also called when applying some style sheet settings, while ThemeChange really indicates a change of the system theme? Though ThemeChange seems to be considered a non-public Event type, at least it doesn't appear in the documentation (marked \omitvalue)
On Windows, via checking for changes to the registry key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize (the StyleChange unfortunately isn't triggered there at all - a Qt bug?). .
Detecting dark theme on Windows
Application bright/dark mode determined by registry key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize\AppsUseLightTheme (1 for bright, 0 for dark). This check is also done in Qt's plugins/platforms/windows/qwindowstheme (queryDarkMode`), but I think this is not exposed publicly as generic interface anywhere?

Related

How do I test whether a touchinput in Windows is from a finger or the stylus? in C/C++

I have a windows multi-touch app where I want to treat touch events from the stylus/pen differently than events from a finger.
I have been searching microsoft docs for hours to see how to determine this.
Is it possible? (I can't believe not)
A secondary thing is how to determine the state of the "pen button" (or buttons) when the pen is touching.
Well seems the issue is the old pre-windows 8 API doesn't support that information. You have to use the newer API which is only available on windows 8+ the "Pointer Input" messages and associated structures and methods.
And you have to use the headers and libs from the new SDK.

How to shell to another app and have it appear in a Borland VCL form (c++)

I'm actually in charge of a FIP networking c++ application, working for the first time with Embarcadero C++ Builder XE5.
The app is nearly finished, but I can't find how to implement the last feature...
I wanted to open an external Windows HyperTerminal in order to see what happen on a given COM port, for this purpose I'm using ShellExecute() to launch it from my application but it's a bit ugly since there is 2 different windows.
I was wondering if it was possible to integrate this newly opened HyperTerminal into an existing form (Panel for instance). I couldn't find nothing related excepted this =>
Delphi style, but i don't understand a byte of #mghie answer since it's delphi.
If anyone have a clue I'm really interested, even the most basic clue!
For almost all of my projects where COM port interaction is needed I use AsyncPro. The project is very well documented with a ~1000 page reference manual.
Reference Manual
Developer's Guide
For this case, the package provides a VCL terminal that simply drops onto a form. It's quite flexible with a lot of options to configure its behaviour.
I wanted something similar in past but with no success.
1.The only thing I was able to do is the exact opposite.
dock my VCL window inside another (not VCL app) but that solved my problems
If you terminal is console window then I doubt even this can be done.
anyway find handle of desired window
find handle to a dockable subcomponent
set the parent of your subwindow to it / or use manual dock
2.maybe you can do some funny stuff
like hide terminal somewhere
and continuoslly copy its graphics to your window
newer done that hide thing
but copy the contents is doable (although on windows a little unstable sometimes)
done it once to feed my App with IR-camera feed from different App
while 'focus' stays on hidden terminal it should work
also you can try to post messages to it somehow if you need the focus ...
Sorry for a vague answer but at least you see some approaches of mine
maybe someone has a better way to do this

Qt application in kiosk mode

I need to start my qt application on desktop under windows and linux in kiosk mode.
May I do it, using qt or special system calls? (not adjusting operation system)
I think you could look into the KDE iosk framework:
http://techbase.kde.org/KDE_System_Administration/Kiosk/Introduction
This is basically written in Qt, and should be working both on Linux and Windows. If you face any troubles, you can at least take their code as a good and robust base.
Here you can find the first paragraph of the introduction inline for your convenience:
The KDE Kiosk is a framework that has been built into KDE since version 3. It allows administrators to create a controlled environment for their users by customizing and locking almost any aspect of the desktop which includes the benign such as setting and fixing the background wallpaper, the functional such as disabling user log outs and access to the print system and the more security conscientious such as disabling access to a command shell.

Global hotkeys in a cross-platform Qt application

I'm creating a cross platform utility, in C++ using Qt, for which I need to have shortcut keys (or hotkeys, not really sure about the difference). Essentially the application will run and only be visible as an icon in the system tray, and do stuff when you press certain shortcut keys (eg, Ctrl-Shift-f4 or something).
I am under the impression that Qt doesn't provide a way to handle shortcut keys unless the application is in focus, which, in my case it won't be. So, that's out (if however that is a viable option, please clue me in).
I've found plenty of examples/documentation explaining how to do this using Xlib/Xcb for linux, win32 api for windows, and carbon for osx, but I'm having a hard time finding a way to do this that would be applicable within the scope of a Qt application.
What would be a way to accomplish what I need?
I'm digging up this old non-answered question because, using QML, I encountered the same issue. The Shortcut QML type allow you to specify a context property but you still need a focused application or window.
However, I found a library resolving this issue : QHotkey. Describing itself on Github as :
A global shortcut/hotkey for Desktop Qt-Applications.
The QHotkey is a class that can be used to create hotkeys/global shortcuts, aka shortcuts that work everywhere, independent of the application state. This means your application can be active, inactive, minimized or not visible at all and still receive the shortcuts.
QHockey is available as a package through qpm and can be used directly from C++.

Change Windows Mobile 6.1 Theme Programmatically

I am trying to figure out the proper procedure for applying a new tsk based theme file in windows mobile 6.1.
I have tried working off of the page http://www.pocketpcdn.com/articles/changetodaytheme.html But this only changes the background, not the system colors for things such as the top and bottom bars on the screen.
wceload.exe seems to work perfectly for some tsk's and partially for others.
Does anyone know more about tsk files and applying them programmatically in Windows Mobile 6.1?
My application is an open source application, the code is avail;able via read only svn, feel free to check it out # google code
I ended up finding a solution, I don't think it is a universal solution though.
Calling "\Windows\cusTSK.exe \Windows\ThemeName.tsk" changes the top and bottom bars, but does not change all apsects of the theme... so calling wceload.exe and then calling cuTSK.exe in that order seems to be able to change the theme using all tsk files that I have tested.
The cusTSK.exe binary does not exist on the Windows Mobile 6.1 Professional emulator image that you can download from msdn, so I think that this file that exists on custom roms and HTC made devices, that is why I do not think this is a universal solution, but it works for my purposes