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

[feat] Change Window theme dynamically at runtime #5279

Open
Kakamotobi opened this issue Sep 25, 2022 · 11 comments · May be fixed by #10210
Open

[feat] Change Window theme dynamically at runtime #5279

Kakamotobi opened this issue Sep 25, 2022 · 11 comments · May be fixed by #10210
Labels
status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes type: feature request

Comments

@Kakamotobi
Copy link

Describe the problem

As far as I can tell from the docs, concerning the theme of the window, there are JS APIs for only (1) getting the window's current theme, and (2) listening to the system theme change.

I'm trying to set the window's theme to "dark"/"light" as well when the user chooses the "dark"/"light" theme in my app.

Is there a way to dynamically change the theme of the window through JavaScript?

Describe the solution you'd like

A JS API to change the theme of the window.

Alternatives considered

No response

Additional context

No response

@amrbashir
Copy link
Member

did you try https://tauri.app/v1/api/js/window/#theme-2 ?

@astudentinearth
Copy link

You can give the user 3 choices for theme. Dark, light, or follow system theme - just like a lot of other apps do. If the user decides not to follow the system theme you can use whichever one the user chooses. Do you have a hard dependency on the window theme itself?

@FabianLars
Copy link
Member

Is there a way to dynamically change the theme of the window through JavaScript?

Currently only when creating the window like

const webview = new WebviewWindow('uniqueLabel', {
  url: 'path/to/page.html',
  theme: "dark"
});

(same api avail in rust and tauri.conf.json)

@Kakamotobi
Copy link
Author

did you try https://tauri.app/v1/api/js/window/#theme-2 ?

I'm looking for a dynamic solution in JS and not the initial configuration.


You can give the user 3 choices for theme. Dark, light, or follow system theme - just like a lot of other apps do. If the user decides not to follow the system theme you can use whichever one the user chooses. Do you have a hard dependency on the window theme itself?

For now, all I want is a toggle button where the user can choose either light or dark mode. The problem is, the app window (top bar) always remains the same (light). I was wondering if it was possible to simply apply the theme change for the window something like: windowTheme = windowTheme === "light" ? "dark" : "light" in JS.


Currently only when creating the window like

const webview = new WebviewWindow('uniqueLabel', {
  url: 'path/to/page.html',
  theme: "dark"
});

(same api avail in rust and tauri.conf.json)

Thanks for the tip.

@Kakamotobi
Copy link
Author

I think an API like this in the WindowManager class would be convenient. Is it plausible?

type Theme = 'light' | 'dark';

async setTheme(theme: Theme): Promise<void> {
  return invokeTauriCommand({
    __tauriModule: 'Window',
    message: {
      cmd: 'manage',
      data: {
        label: this.label,
        cmd: {
          type: 'setTheme',
          payload: theme
        }
      }
    }
  })
}
import { appWindow } from '@tauri-apps/api/window';
await appWindow.setTheme("dark");

And perhaps the theme() getter can be renamed to getTheme() as such:

async getTheme(): Promise<Theme | null> {
  return invokeTauriCommand({
    __tauriModule: 'Window',
    message: {
      cmd: 'manage',
      data: {
        label: this.label,
        cmd: {
          type: 'getTheme'
        }
      }
    }
  })
}

@FabianLars FabianLars changed the title [feat] Window theme change [feat] Change Window theme dynamically at runtime Oct 7, 2022
@FabianLars
Copy link
Member

FabianLars commented Oct 7, 2022

Is it plausible?

As long as all or some of the platforms support changing the theme at runtime, yes! But i think this needs changes in Tao, so i'm going to upstream this issue and see if Amr screams at me 😄

@FabianLars
Copy link
Member

/upstream tauri-apps/tao

@wyhaya
Copy link

wyhaya commented Sep 29, 2023

Try it: tauri-plugin-theme

@martpie
Copy link

martpie commented Mar 21, 2024

@FabianLars Would you be open for any kind of contribution here? I am working on martpie/museeks#759, and I would like to achieve a behavior close to Electron's nativeTheme (behavior, not necessarily API).

I would really like that issue (and others, related to getting system theme preference manually) to be solved for Tauri 2.0 main release. This issue is just one thing to be solved to have dynamic theme support (system theme + possible override from a Tauri app user config).

Would you be open to an RFC explaining the needed changes? or PRs? I would be happy to contribute code, but getting the behavior right is critical, and this is likely to be a breaking change in behavior, so maybe discussing and documenting the weird edgecases first would be better.

@FabianLars
Copy link
Member

We're always open for contributions!

to be solved for Tauri 2.0 main release

Probably too late for that.

Would you be open to an RFC explaining the needed changes? or PRs?

Sure, we even have a rfc repo https://github.com/tauri-apps/rfcs which sadly never got the attention it deserved. If there's not that much to talk about (i honestly don't know, i thought we just need a setTheme method and can call it a day lol) then a normal issue is fine too imo.

and this is likely to be a breaking change in behavior

I don't see where it'd be breaking (at least where it doesn't count as a bugfix).

@selastingeorge
Copy link

In Windows, I use the following method:

use windows_sys::Win32::Graphics::Dwm::*;
use windows_sys::Win32::Foundation::*;
use tauri::{Theme,WebviewWindow};

pub fn set_window_theme(window:&WebviewWindow,theme:Theme) {
    unsafe {
        let handle = window.hwnd().unwrap().0;
        let value: BOOL = if theme == Theme::Dark {1} else {0};
        let attribute = DWMWA_USE_IMMERSIVE_DARK_MODE;
        DwmSetWindowAttribute(handle, attribute as u32, &value as *const _ as *const _, std::mem::size_of::<BOOL>() as u32);
    }
}

checkout this demo for more : Tauri Theme Demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: upstream This issue is blocked by upstream dependencies and we need to wait or contribute upstream fixes type: feature request
Projects
Status: 📬Proposal
Development

Successfully merging a pull request may close this issue.

7 participants