From 8387e67fd66662111b716998b6795f995e02f807 Mon Sep 17 00:00:00 2001 From: Andrew Bastin Date: Tue, 7 Nov 2023 13:12:19 +0530 Subject: [PATCH] feat: dynamically change mac window theme based on hopp theme --- .../src-tauri/Cargo.toml | 18 +++++- .../src-tauri/src/mac/window.rs | 55 +++++++++++++++++-- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/packages/hoppscotch-selfhost-desktop/src-tauri/Cargo.toml b/packages/hoppscotch-selfhost-desktop/src-tauri/Cargo.toml index 7de7030bf..12a43c3fc 100644 --- a/packages/hoppscotch-selfhost-desktop/src-tauri/Cargo.toml +++ b/packages/hoppscotch-selfhost-desktop/src-tauri/Cargo.toml @@ -13,21 +13,33 @@ edition = "2021" tauri-build = { version = "1.4.0", features = [] } [dependencies] -tauri = { version = "1.4.1", features = [ "dialog-save", "fs-write-file", "http-all", "os-all", "shell-open", "window-start-dragging", "http-multipart"] } +tauri = { version = "1.4.1", features = [ + "dialog-save", + "fs-write-file", + "http-all", + "os-all", + "shell-open", + "window-start-dragging", + "http-multipart", +] } tauri-plugin-store = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" } tauri-plugin-deep-link = { git = "https://github.com/FabianLars/tauri-plugin-deep-link", branch = "main" } tauri-plugin-window-state = "0.1.0" reqwest = "0.11.20" serde_json = "1.0.107" url = "2.4.1" +hex_color = "2.0.0" [target.'cfg(target_os = "macos")'.dependencies] cocoa = "0.25.0" objc = "0.2.7" [target.'cfg(target_os = "windows")'.dependencies] -windows = { version = "0.51.1", features = ["Win32_Graphics_Dwm", "Win32_Foundation", "Win32_UI_Controls"] } -hex_color = "2.0.0" +windows = { version = "0.51.1", features = [ + "Win32_Graphics_Dwm", + "Win32_Foundation", + "Win32_UI_Controls", +] } [features] # this feature is used for production builds or when `devPath` points to the filesystem diff --git a/packages/hoppscotch-selfhost-desktop/src-tauri/src/mac/window.rs b/packages/hoppscotch-selfhost-desktop/src-tauri/src/mac/window.rs index e4c2ec854..1330bfba5 100644 --- a/packages/hoppscotch-selfhost-desktop/src-tauri/src/mac/window.rs +++ b/packages/hoppscotch-selfhost-desktop/src-tauri/src/mac/window.rs @@ -1,3 +1,4 @@ +use hex_color::HexColor; use tauri::{App, Manager, Runtime, Window}; // If anything breaks on macOS, this should be the place which is broken @@ -31,18 +32,48 @@ unsafe fn set_transparent_titlebar(id: cocoa::base::id) { id.setTitleVisibility_(cocoa::appkit::NSWindowTitleVisibility::NSWindowTitleHidden); } +struct UnsafeWindowHandle(*mut std::ffi::c_void); +unsafe impl Send for UnsafeWindowHandle {} +unsafe impl Sync for UnsafeWindowHandle {} + +#[cfg(target_os = "macos")] +fn update_window_theme(window: &tauri::Window, color: HexColor) { + use cocoa::appkit::{ + NSAppearance, NSAppearanceNameVibrantDark, NSAppearanceNameVibrantLight, NSWindow, + }; + + let brightness = (color.r as u64 + color.g as u64 + color.b as u64) / 3; + + unsafe { + let window_handle = UnsafeWindowHandle(window.ns_window().unwrap()); + + let _ = window.run_on_main_thread(move || { + let handle = window_handle; + + let selected_appearance = if brightness >= 128 { + NSAppearance(NSAppearanceNameVibrantLight) + } else { + NSAppearance(NSAppearanceNameVibrantDark) + }; + + NSWindow::setAppearance(handle.0 as cocoa::base::id, selected_appearance); + set_window_controls_pos( + handle.0 as cocoa::base::id, + WINDOW_CONTROL_PAD_X, + WINDOW_CONTROL_PAD_Y, + ); + }); + } +} + #[cfg(target_os = "macos")] fn set_window_controls_pos(window: cocoa::base::id, x: f64, y: f64) { use cocoa::{ - appkit::{NSAppearance, NSAppearanceNameVibrantLight, NSView, NSWindow, NSWindowButton}, + appkit::{NSView, NSWindow, NSWindowButton}, foundation::NSRect, }; unsafe { - // Set appearance windows to be light for better visibility when on light theme - // TODO: Detect when on dark theme and set to dark and on light switch to light - NSWindow::setAppearance(window, NSAppearance(NSAppearanceNameVibrantLight)); - let close = window.standardWindowButton_(NSWindowButton::NSWindowCloseButton); let miniaturize = window.standardWindowButton_(NSWindowButton::NSWindowMiniaturizeButton); let zoom = window.standardWindowButton_(NSWindowButton::NSWindowZoomButton); @@ -342,4 +373,18 @@ pub fn setup_mac_window(app: &mut App) { } app.get_window("main").unwrap().set_transparent_titlebar(); + + let window_handle = app.get_window("main").unwrap(); + update_window_theme(&window_handle, HexColor::WHITE); + + // Control window theme based on app update_window + app.listen_global("hopp-bg-changed", move |ev| { + let payload = serde_json::from_str::<&str>(ev.payload().unwrap()) + .unwrap() + .trim(); + + let color = HexColor::parse_rgb(payload).unwrap(); + + update_window_theme(&window_handle, color); + }); }