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

How to listen to theme change event in rust #14

Open
liyasthomas opened this issue Jul 10, 2024 · 4 comments
Open

How to listen to theme change event in rust #14

liyasthomas opened this issue Jul 10, 2024 · 4 comments

Comments

@liyasthomas
Copy link

liyasthomas commented Jul 10, 2024

Are there any events emitted on Rust side when set_theme is called from front-end?

Something like:

window.on_window_event(move |event| {
	if let tauri::WindowEvent::ThemeChanged(theme) = event {
		println!("Theme changed!");
	}
});
@wyhaya
Copy link
Owner

wyhaya commented Jul 11, 2024

Are there any events emitted on Rust side when set_theme is called from front-end?

No.

Currently, there is no good solution in Rust, but you can listen for theme changes in JavaScript and then send a notification.

const medie = window.matchMedia('(prefers-color-scheme: dark)')
medie.addEventListener('change', () => {
    invoke('theme_changed', {
        theme: medie.matches ? 'dark' : 'light'
    })
})
#[command]
fn theme_changed(theme: &str) {
    println!("Theme changed!");
}

@liyasthomas
Copy link
Author

I'm trying to set a custom inset to the traffic lights position using this plugin. But using tauri-plugin-theme seems to be resetting the custom inset on every theme change.

Even tho, I got it slightly working with the above implementation, but the traffic lights seem to be flickering a bit in between theme change.

Here's a demo of flickering:

Screen.Recording.2024-07-11.at.8.32.08.AM.mov

@wyhaya
Copy link
Owner

wyhaya commented Jul 11, 2024

Even tho, I got it slightly working with the above implementation, but the traffic lights seem to be flickering a bit in between theme change.

There is a certain delay in notifications between JavaScript and Rust, which is not a good approach.


You should complete the traffic lights position setup after the theme change and before the next render, but this seems to be beyond the scope of this plugin.

If you’re willing, you can fork this repo and then modify platform/macos.rs:

#[command]
pub fn set_theme<R: Runtime>(app: AppHandle<R>, theme: Theme) -> Result<(), &'static str> {
    save_theme_value(&app.config(), theme);
    for window in app.windows().values() {
        let ptr = window.ns_window().map_err(|_| "Invalid window handle")?;
        unsafe {
            let val = match theme {
                Theme::Auto => nil,
                Theme::Light => NSAppearance(NSAppearanceNameVibrantLight),
                Theme::Dark => NSAppearance(NSAppearanceNameVibrantDark),
            };
            (ptr as id).setAppearance(val);
        }
+       crate::traffic_light_positioner_plugin::setup_traffic_light_positioner(window.clone());
    }
    Ok(())
}
traffic_light_positioner_plugin.mov

@wyhaya
Copy link
Owner

wyhaya commented Jul 11, 2024

For your use case, implementing on top of Tauri would be best, but it’s not yet complete.

tauri-apps/tao#513
tauri-apps/tauri#4789

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

No branches or pull requests

2 participants