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
Ability to force a theme on Windows #1666
Conversation
Any feedback about this or merging it in? |
I don't think there's any Windows maintainer capable of reviewing this. |
@@ -32,6 +32,7 @@ pub struct WindowState { | |||
pub modifiers_state: ModifiersState, | |||
pub fullscreen: Option<Fullscreen>, | |||
pub is_dark_mode: bool, | |||
pub forced_theme: Option<Theme>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would it make sense to get rid of is_dark_mode and use only theme ?
probably a breaking change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is_dark
is purely to check OS preference.
An approach could be extending the theme enum to be something like:
enum Theme {
OS_DETERMINED,
FORCED_DARK,
FORCED_LIGHT,
}
and OS_DETERMINED
would be the default.
However this does not get rid of is_dark
because using dark style can fail and it is used to check the OS preference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested on win10:
None
: Correctly shows the theme selected in the OSSome(theme)
: Correctly overrides the theme set by the userNone
+ theme switch: Correctly switches to OS themeSome(theme)
+ theme swtich: Correctly keeps the forced theme
Good to go imo if there are no further code related concerns
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have windows machine to test it, but I'd do some source level review, since I have some style questions.
src/platform/windows.rs
Outdated
@@ -125,6 +125,9 @@ pub trait WindowBuilderExtWindows { | |||
/// If you need COM API with `COINIT_MULTITHREADED` you must initialize it before calling any winit functions. | |||
/// See https://docs.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize#remarks for more information. | |||
fn with_drag_and_drop(self, flag: bool) -> WindowBuilder; | |||
|
|||
/// Forces either Dark or Light theme. By default the system settings are used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just by looking on that function, I feel like it'll make sense to accept Option<Theme>
, meaning that providing None
will use system's preferred Theme
. That seems more ergonomic and can interact better with downstream configurations, since otherwise they should avoid calling that method, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good feedback. I've decided to replace Option<> with a Theme::System
to be a bit more explicit.
Let me know if you disagree :)
…force_theme_v1
if *DARK_MODE_SUPPORTED { | ||
let is_dark_mode = should_use_dark_mode(); | ||
let is_dark_mode: bool = match preferred_theme { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you really need to specify the bool type ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks better and I feel like we're getting closer! Thanks for your work so far.
@@ -32,6 +32,7 @@ pub struct WindowState { | |||
pub modifiers_state: ModifiersState, | |||
pub fullscreen: Option<Fullscreen>, | |||
pub is_dark_mode: bool, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like for the more code simplicity we can use Theme
instead of bool
here, so try_dark_mode
will also return a Theme
, and then you'd have less mapping to bool -> Theme
, issuing a new ThemeChanged
when current_theme != new_theme
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I like this changed. Implemented it!
Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should address compilation warnings, besides that it should be good to go.
@@ -72,9 +74,12 @@ lazy_static! { | |||
|
|||
/// Attempt to set dark mode on a window, if necessary. | |||
/// Returns true if dark mode was set, false if not. | |||
pub fn try_dark_mode(hwnd: HWND) -> bool { | |||
pub fn try_dark_mode(hwnd: HWND, preferred_theme: Option<Theme>) -> Theme { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd actually rename this function, since it it's not about dark mode anymore, it's just about trying to get a theme, however when I see try, I'm expecting Result
, so I'm not sure if this is a good name. Maybe pick_theme
or something like that, if you have better ideas let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if your preferred theme is dark it could theoretically fail on old windows versions. In that case it would return Theme::Light
.
So I think try
should be included in the name. try_select_theme
, try_pick_theme
or try_theme
🤷
I don't think it should necessarily return a result. I could change it to a result but it would make the calling code less nice IMO. (It would return a result, if the result is ok the current theme is the preferred theme if the result is a error than the theme is light. Which works but the caller of try_dark_mode
needs to understand that the standard theme is light so I prefer to hide it away into the try_
function)
Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs rebase and should be good to go.
src/platform/windows.rs
Outdated
@@ -82,7 +82,7 @@ pub trait WindowExtWindows { | |||
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>); | |||
|
|||
/// Whether the system theme is currently Windows 10's "Dark Mode". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation doesn't match anymore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the comment
@@ -82,7 +82,7 @@ pub trait WindowExtWindows { | |||
fn set_taskbar_icon(&self, taskbar_icon: Option<Icon>); | |||
|
|||
/// Whether the system theme is currently Windows 10's "Dark Mode". | |||
fn is_dark_mode(&self) -> bool; | |||
fn theme(&self) -> Theme; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a breaking change, so it should be listed in the changelog
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the changelog
Co-authored-by: msiglreith <m.siglreith@gmail.com>
Added the
WindowBuilderExtWindows::with_theme
function to allow forcing a theme. In case you always want to have a dark theme no matter the system settings.cargo fmt
has been run on this branchcargo doc
builds successfullyCHANGELOG.md
if knowledge of this change could be valuable to usersCreated or updated an example program if it would help users understand this functionality