-
-
Notifications
You must be signed in to change notification settings - Fork 255
[POC] Decide default theme on Windows based on the system theme #608
base: master
Are you sure you want to change the base?
Conversation
Just to reiterate: This is a proof of concept and even if I've spent a lot of time polishing this change, it isn't as good as I'd like it to be. |
wxWidgets provides an easy way to read registry values, apparently. Instead of forcing the user to switch their theme so that it corresponds to the system theme, it'd be a better idea to just do that for them. What this change does not do: If the user changes the system theme after Tenacity is initially configured, the theme won't change. Some additional style-related changes were also made. Signed-off-by: Panagiotis Vasilopoulos <[email protected]>
ef5aca8
to
e1b7073
Compare
Force-pushed to replace |
I think how this is often done is to have a "System Theme" theme option, which then uses the system theme. But in our case, I suppose it's really just about picking a different default custom theme instead, but I guess that could still work like that, but with a bit different naming than "System Theme"? "System Theme" would be also fine if we took colors and such from the current system theme for what we draw custom, instead of having predefined ones. Just some initial thoughts. |
Yeah, runtime switching is a whole different beast of a subject though. Which events would we listen to? Can we allow the user to manually override this? We should check whether the user is using another theme other then Light/Dark! The GNOME feature you brought up only exists unofficially on Windows (https://justgetflux.com/news/pages/v4/readme/), so I figured that it'd be a good idea to start from there as a very early step. |
GTK will get appropriate style change events, etc. I don't know if wxGTK exposes them to us properly or not these days, might need some
That would be the idea - the user would choose "System Theme", "Light Theme" or "Dark Theme" or whatever else we have. System Theme would honor system theme as much as possible, the rest are what our theme says to have. Initially "System Theme" would switch between light and dark variants appropriately, following the system theme, and maybe in the future follow it even more (e.g. look more like Yaru in colors on Ubuntu, because it would take the base colors out of the theme).
I'm not sure what that f.lux link shows, maybe you had a copy-paste mistake |
|
I think that this change should be merged, as including it, even if it isn't in a 100% ready state, is most likely better than nothing. |
Hello! I've been recently thinking about this pull request as I'm looking for stuff to merge into Saucedacity's codebase, based on the discussion in #733. I have found interest in maybe testing this out and even seeing how I can make this a preference. However, I've been looking at other ways on how to implement this, such as inverting theme colours without changing preference, etc. That works well for light themes but not so much for dark themes. I was looking through wxWidgets' 3.2.0 documentation, and I found wxSysColourChangedEvent. However, I don't exactly know how we're going to handle this event, but it is one to look at. UPDATE: A couple of things about wxSysColourChangedEvent:
I was able to trip a wxWidgets assertion by implementing this event handler just to test out if this works on Linux. While it works on Pop!_OS 22.04 (and I'd imagine this would be the case with GNOME 40+ or so), results may vary. On Windows, it should hopefully work. Overall, I propose this POC that builds on top of yours, but it uses wxSysColourChangedEvent instead of reading a registry key. It is cross-platform and is not limited to initial configuration. However, is likely better because you have intended to write this with the possibility of switching to a different toolkit (e.g. Qt). I will need to thoroughly look at your code to improve this POC here. UPDATE 2: Actually, it might not be a simple as I thought, but if the target is Windows only, then a modified POC still works because we can check that registry key each time the theme changes. This would be beyond initial configuration and can still benefit this. |
So, after a little more research, my final POC: for wxWidgets 3.1.3 or later, we use wxSystemAppearance to tell if the system's appearance is dark or not ( |
Okay. Here is the POC below. I have created two POCs, the first with Tenacity and the second with Saucedacity (as I initially wrote the code using Saucedacity's code base). Note that this requires wxWidgets >= 3.1.3 in order for either forks to properly build (not accounting for other issues). Of course, this is merely the theme switching part of the overall concept. No new preferences are introduced, but nevertheless, you can see where we're going with the theme switching code. The code was tested on Pop!_OS 22.04. Both work pretty well, actually. The main window updates automatically, but other windows that we theme don't automatically update (e.g. the About dialog box as that's what I tested with). Tenacity POC Patch: diff --git a/src/ProjectWindow.cpp b/src/ProjectWindow.cpp
index 1796c3428..cfef300c5 100644
--- a/src/ProjectWindow.cpp
+++ b/src/ProjectWindow.cpp
@@ -695,8 +695,25 @@ BEGIN_EVENT_TABLE(ProjectWindow, wxFrame)
EVT_UPDATE_UI(1, ProjectWindow::OnUpdateUI)
EVT_COMMAND(wxID_ANY, EVT_TOOLBAR_UPDATED, ProjectWindow::OnToolBarUpdate)
//mchinen:multithreaded calls - may not be threadsafe with CommandEvent: may have to change.
+
+ EVT_SYS_COLOUR_CHANGED(ProjectWindow::OnSysColourChanged)
END_EVENT_TABLE()
+void ProjectWindow::OnSysColourChanged(wxSysColourChangedEvent&)
+{
+ auto sysAppearance = wxSystemSettings::GetAppearance();
+
+ if (sysAppearance.IsDark())
+ {
+ theTheme.LoadTheme(themeDark);
+ } else
+ {
+ theTheme.LoadTheme(themeLight);
+ }
+
+ ThemePrefs::ApplyUpdatedImages();
+}
+
void ProjectWindow::ApplyUpdatedTheme()
{
auto &project = mProject;
diff --git a/src/ProjectWindow.h b/src/ProjectWindow.h
index 1d759c8e9..2c9cce311 100644
--- a/src/ProjectWindow.h
+++ b/src/ProjectWindow.h
@@ -155,6 +155,7 @@ public:
void OnMenu(wxCommandEvent & event);
void OnUpdateUI(wxUpdateUIEvent & event);
+ void OnSysColourChanged(wxSysColourChangedEvent& event);
void MacShowUndockedToolbars(bool show);
void OnActivate(wxActivateEvent & event); Saucedacity POC Patch: diff --git a/src/ProjectWindow.cpp b/src/ProjectWindow.cpp
index b0a50edab..d07600b50 100644
--- a/src/ProjectWindow.cpp
+++ b/src/ProjectWindow.cpp
@@ -676,8 +676,25 @@ BEGIN_EVENT_TABLE(ProjectWindow, wxFrame)
EVT_UPDATE_UI(1, ProjectWindow::OnUpdateUI)
EVT_COMMAND(wxID_ANY, EVT_TOOLBAR_UPDATED, ProjectWindow::OnToolBarUpdate)
//mchinen:multithreaded calls - may not be threadsafe with CommandEvent: may have to change.
+
+ EVT_SYS_COLOUR_CHANGED(ProjectWindow::OnSysColourChanged)
END_EVENT_TABLE()
+void ProjectWindow::OnSysColourChanged(wxSysColourChangedEvent&)
+{
+ auto sysAppearance = wxSystemSettings::GetAppearance();
+
+ if (sysAppearance.IsDark())
+ {
+ theTheme.LoadTheme(themeDark);
+ } else
+ {
+ theTheme.LoadTheme(themeDefault);
+ }
+
+ ThemePrefs::ApplyUpdatedImages();
+}
+
void ProjectWindow::ApplyUpdatedTheme()
{
auto &project = mProject;
diff --git a/src/ProjectWindow.h b/src/ProjectWindow.h
index 01f74a03e..c793f6f71 100644
--- a/src/ProjectWindow.h
+++ b/src/ProjectWindow.h
@@ -155,6 +155,7 @@ public:
void OnMenu(wxCommandEvent & event);
void OnUpdateUI(wxUpdateUIEvent & event);
+ void OnSysColourChanged(wxSysColourChangedEvent& event);
void MacShowUndockedToolbars(bool show);
void OnActivate(wxActivateEvent & event); I think this works well for the theme switching mechanism. I personally am satisfied with this part of the code, but it is clear that we need to add a new preference for this. |
Looks like @generic-pers0n if you're on IRC/Matrix, can you reach out about this or other things with me? I'm |
Today in "classes I wish I had known about from the beginning". |
Nevermind, I looked at my past notes, I only worked on Windows at first because of the 3.0 compatibility thing that distros like Debian or Void Linux still depend on. My focus was to get it to work first and polish it up later. You could borrow |
Meanwhile wxWidgets-3.2 finally came out, so it might be OKish to depend on it. Might be a blocker for older distro versions, but they wouldn't package a new application anyways either. |
Indeed I'm willing to talk about this! But what do you know? It turns out we rely on having to check the background color on other platforms. This was what I was thinking as a fallback for wxWidgets 3.0 initially. A little mini rant about our case and wxWidgets compatibilityI mean, On an unrelated note, I think this acts as another reason as to why I wanted to take a look at an alternative toolkit (namely Qt), which I have plans for. But let's not talk about that here. That's for another issue. |
You have a point. I would be using Edit: My Matrix username is |
So a new proposal based upon some talks with @leio:
For DBus, we probably might need to add a new dependency for using DBus, maybe GDBus given we use wxGTK on Linux. Additionally, I still have to learn DBus, so that's out of my skillset for now (unless @leio is willing to take up the challenge, but I don't know). Everything else I am capable of doing, and we already have the Windows code for wxWidgets <= 3.1.3. Also note: I'm currently looking at this for Saucedacity, so keep that in mind. We could always merge this into Saucedacity in the future, but that might be for a later date. |
I don't think you should worry at all about 3.0 for non-wxGTK, because on Mac and Windows we would be building and distributing a final binary ourselves, and that on top of 3.2. It's just Linux with wxGTK where there's some value in keeping compatibility with 3.0 due to wxWidgets distribution packages for some time. Anyhow, got a bit into rambling territory. tl;dr: I think it's very fine to require wx3.2 for Mac and Windows, and somewhat fine to require for linux/bsd (wxGTK) - users of distros without 3.2 packaged can use from the flatpak. |
TL;DR: I agree with raising the minimum version of wxWidgets to 3.2. I believe it provides many things where 3.0 lacked before (especially Technically, for Saucedacity, I did already announce that the minimum required version for wxWidgets would be wxWidgets 3.1(.3) going forward on all platforms (including wxGTK). I had planned that Saucedacity would later support the latest development version of wxWidgets (3.3.0) also, and this was because of the uneven distribution of wxWidgets on Linux distros (we would use the appropriate version of wxWidgets for Windows and macOS, depending on what wxWidgets recommends themselves, e.g., they encourage 3.3.0 in production use like they did for 3.1.0). Therefore, I agree with raising the minimum required version of wxWidgets to 3.2.0. EDIT: Just another note to throw in there: Saucedacity will not build against wxWidgets 3.0 due to breaking changes between the two. I tested this once and Saucedacity failed to build. At this point, for Saucedacity, it would be safe to proceed with moving forward with wxWidgets 3.2. I actually believe in raising the minimum version of wxWidgets to the latest stable. I believe that 3.2 is a much needed updated to wxWidgets and while there are clearly still it's shortcomings, it is better than using wxWidgets 3.0. |
wxWidgets provides an easy way to read registry values, apparently.
Instead of forcing the user to switch their theme so that it corresponds
to the system theme, it'd be a better idea to just do that for them.
What this change does not do: If the user changes the system theme after
Tenacity is initially configured, the theme won't change.
Additional Notes / Feedback Needed
Feedback Needed
This probably marks the "first substantial" patch I've sent in that concerns the code, so please bear with me, I'm trying my best.
Theme
class just to get things working, I really doubt that using it and exposing it everywhere is a good thing and sensible thing to do design-wise. I don't have any better alternatives in mind (other than creating a new class) and need some further feedback.#ifdef _WIN32
instead of#if defined(_WIN32)
like in other places. It made more sense syntax-wise, especially because I am not using a second condition over there. Need confirmation that this is okay.Checklist
-s
orSigned-off-by
* (See: Contributing § DCO)