From ba941fa6038c5e040ef62c6c2989dbe029fac30a Mon Sep 17 00:00:00 2001 From: fabianlars Date: Sun, 12 Jan 2025 15:13:54 +0100 Subject: [PATCH] that was so weird to implement --- Cargo.lock | 34 ++++++++++++------- Cargo.toml | 2 ++ crates/tauri-cli/config.schema.json | 2 +- crates/tauri-runtime-wry/src/lib.rs | 32 +++++++++++++++-- crates/tauri-runtime/src/lib.rs | 11 +++++- crates/tauri-runtime/src/webview.rs | 22 ++++++++++++ crates/tauri-runtime/src/window.rs | 7 ++++ .../schemas/config.schema.json | 2 +- crates/tauri-utils/src/config.rs | 1 + crates/tauri/src/test/mock_runtime.rs | 9 +++++ examples/helloworld/tauri.conf.json | 4 ++- 11 files changed, 107 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 36696a0f6fab..2db5f586b11d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1775,7 +1775,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -2830,7 +2830,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6347,7 +6347,7 @@ dependencies = [ "aes-gcm", "aes-kw", "argon2", - "base64 0.22.1", + "base64 0.21.7", "bitfield", "block-padding", "blowfish", @@ -6937,7 +6937,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -7627,7 +7627,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -8939,8 +8939,7 @@ dependencies = [ [[package]] name = "tao" version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3731d04d4ac210cd5f344087733943b9bfb1a32654387dad4d1c70de21aee2c9" +source = "git+https://github.com/tauri-apps/tao#cdfba4ecfcf34b81b3cc13ba53d6b42c9d0b6259" dependencies = [ "bitflags 2.7.0", "cocoa", @@ -8965,7 +8964,7 @@ dependencies = [ "parking_lot", "raw-window-handle", "scopeguard", - "tao-macros", + "tao-macros 0.1.3 (git+https://github.com/tauri-apps/tao)", "unicode-segmentation", "url", "windows", @@ -8985,6 +8984,16 @@ dependencies = [ "syn 2.0.95", ] +[[package]] +name = "tao-macros" +version = "0.1.3" +source = "git+https://github.com/tauri-apps/tao#cdfba4ecfcf34b81b3cc13ba53d6b42c9d0b6259" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.95", +] + [[package]] name = "tap" version = "1.0.1" @@ -9593,7 +9602,7 @@ dependencies = [ "getrandom 0.2.15", "once_cell", "rustix 0.38.43", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -10845,7 +10854,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -11402,8 +11411,7 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e644bf458e27b11b0ecafc9e5633d1304fdae82baca1d42185669752fe6ca4f" +source = "git+https://github.com/tauri-apps/wry#26abf63d79c4a0fcff8ea39d0ff677686f5b546c" dependencies = [ "base64 0.22.1", "block2", @@ -11430,7 +11438,7 @@ dependencies = [ "raw-window-handle", "sha2", "soup3", - "tao-macros", + "tao-macros 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 2.0.10", "tracing", "url", diff --git a/Cargo.toml b/Cargo.toml index 963894b5910b..0c00ffe4c826 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,3 +70,5 @@ opt-level = "s" [patch.crates-io] schemars_derive = { git = 'https://github.com/tauri-apps/schemars.git', branch = 'feat/preserve-description-newlines' } tauri = { path = "./crates/tauri" } +wry = { git = "https://github.com/tauri-apps/wry" } +tao = { git = "https://github.com/tauri-apps/tao" } diff --git a/crates/tauri-cli/config.schema.json b/crates/tauri-cli/config.schema.json index 69a2a3160bfd..462cc7e9c0b0 100644 --- a/crates/tauri-cli/config.schema.json +++ b/crates/tauri-cli/config.schema.json @@ -425,7 +425,7 @@ ] }, "trafficLightPosition": { - "description": "The position of the window controls on macOS.\n Requires titleBarStyle: Overlay and decorations: true.", + "description": "The position of the window controls on macOS.\n\n Requires titleBarStyle: Overlay and decorations: true.", "anyOf": [ { "$ref": "#/definitions/LogicalPosition" diff --git a/crates/tauri-runtime-wry/src/lib.rs b/crates/tauri-runtime-wry/src/lib.rs index 57aac6e031bb..20e1248b1121 100644 --- a/crates/tauri-runtime-wry/src/lib.rs +++ b/crates/tauri-runtime-wry/src/lib.rs @@ -787,6 +787,9 @@ impl WindowBuilder for WindowBuilderWrapper { if let Some(identifier) = &config.tabbing_identifier { window = window.tabbing_identifier(identifier); } + if let Some(position) = &config.traffic_light_position { + window = window.traffic_light_position(position.x, position.y); + } } #[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))] @@ -1069,8 +1072,10 @@ impl WindowBuilder for WindowBuilderWrapper { } #[cfg(target_os = "macos")] - fn traffic_light_position(mut self, position: Position) -> Self { - self.inner = self.inner.with_traffic_light_inset(position); + fn traffic_light_position(mut self, x: f64, y: f64) -> Self { + self.inner = self + .inner + .with_traffic_light_inset(TaoLogicalPosition::new(x, y)); self } @@ -1276,6 +1281,7 @@ pub enum WindowMessage { SetOverlayIcon(Option), SetProgressBar(ProgressBarState), SetTitleBarStyle(tauri_utils::TitleBarStyle), + SetTrafficLightPosition(Position), SetTheme(Option), SetBackgroundColor(Option), DragWindow, @@ -2179,6 +2185,16 @@ impl WindowDispatch for WryWindowDispatcher { ) } + fn set_traffic_light_position(&self, position: Position) -> Result<()> { + send_user_message( + &self.context, + Message::Window( + self.window_id, + WindowMessage::SetTrafficLightPosition(position), + ), + ) + } + fn set_theme(&self, theme: Option) -> Result<()> { send_user_message( &self.context, @@ -3186,6 +3202,10 @@ fn handle_user_message( } }; } + WindowMessage::SetTrafficLightPosition(_position) => { + #[cfg(target_os = "macos")] + window.set_traffic_light_inset(_position); + } WindowMessage::SetTheme(theme) => { window.set_theme(match theme { Some(Theme::Light) => Some(TaoTheme::Light), @@ -4366,6 +4386,14 @@ fn create_webview( } } + #[cfg(target_os = "macos")] + { + use wry::WebViewBuilderExtDarwin; + if let Some(position) = &webview_attributes.traffic_light_position { + webview_builder = webview_builder.with_traffic_light_inset(*position); + } + } + webview_builder = webview_builder.with_ipc_handler(create_ipc_handler( kind, window_id.clone(), diff --git a/crates/tauri-runtime/src/lib.rs b/crates/tauri-runtime/src/lib.rs index 8c93a19a0907..7115c0bedc14 100644 --- a/crates/tauri-runtime/src/lib.rs +++ b/crates/tauri-runtime/src/lib.rs @@ -235,7 +235,7 @@ pub enum RunEvent { Resumed, /// Emitted when all of the event loop's input events have been processed and redraw processing is about to begin. /// - /// This event is useful as a place to put your code that should be run after all state-changing events have been handled and you want to do stuff (updating state, performing calculations, etc) that happens as the “main body” of your event loop. + /// This event is useful as a place to put your code that should be run after all state-changing events have been handled and you want to do stuff (updating state, performing calculations, etc) that happens as the "main body" of your event loop. MainEventsCleared, /// Emitted when the user wants to open the specified resource with the app. #[cfg(any(target_os = "macos", target_os = "ios"))] @@ -847,6 +847,15 @@ pub trait WindowDispatch: Debug + Clone + Send + Sync + Sized + 's /// - **Linux / Windows / iOS / Android:** Unsupported. fn set_title_bar_style(&self, style: tauri_utils::TitleBarStyle) -> Result<()>; + /// Change the position of the window controls. Available on macOS only. + /// + /// Requires titleBarStyle: Overlay and decorations: true. + /// + /// ## Platform-specific + /// + /// - **Linux / Windows / iOS / Android:** Unsupported. + fn set_traffic_light_position(&self, position: Position) -> Result<()>; + /// Sets the theme for this window. /// /// ## Platform-specific diff --git a/crates/tauri-runtime/src/webview.rs b/crates/tauri-runtime/src/webview.rs index f317a5857638..24b6f2ea24ee 100644 --- a/crates/tauri-runtime/src/webview.rs +++ b/crates/tauri-runtime/src/webview.rs @@ -215,6 +215,7 @@ pub struct WebviewAttributes { pub use_https_scheme: bool, pub devtools: Option, pub background_color: Option, + pub traffic_light_position: Option, } impl From<&WindowConfig> for WebviewAttributes { @@ -230,6 +231,13 @@ impl From<&WindowConfig> for WebviewAttributes { { builder = builder.transparent(config.transparent); } + #[cfg(target_os = "macos")] + { + if let Some(position) = &config.traffic_light_position { + builder = + builder.traffic_light_position(dpi::LogicalPosition::new(position.x, position.y).into()); + } + } builder = builder.accept_first_mouse(config.accept_first_mouse); if !config.drag_drop_enabled { builder = builder.disable_drag_drop_handler(); @@ -279,6 +287,7 @@ impl WebviewAttributes { use_https_scheme: false, devtools: None, background_color: None, + traffic_light_position: None, } } @@ -444,6 +453,19 @@ impl WebviewAttributes { self.background_color = Some(color); self } + + /// Change the position of the window controls. Available on macOS only. + /// + /// Requires titleBarStyle: Overlay and decorations: true. + /// + /// ## Platform-specific + /// + /// - **Linux / Windows / iOS / Android:** Unsupported. + #[must_use] + pub fn traffic_light_position(mut self, position: dpi::Position) -> Self { + self.traffic_light_position = Some(position); + self + } } /// IPC handler. diff --git a/crates/tauri-runtime/src/window.rs b/crates/tauri-runtime/src/window.rs index dc843100da98..0d69bca9cfba 100644 --- a/crates/tauri-runtime/src/window.rs +++ b/crates/tauri-runtime/src/window.rs @@ -423,6 +423,13 @@ pub trait WindowBuilder: WindowBuilderBase { #[must_use] fn title_bar_style(self, style: tauri_utils::TitleBarStyle) -> Self; + /// Change the position of the window controls on macOS. + /// + /// Requires titleBarStyle: Overlay and decorations: true. + #[cfg(target_os = "macos")] + #[must_use] + fn traffic_light_position(self, x: f64, y: f64) -> Self; + /// Hide the window title. #[cfg(target_os = "macos")] #[must_use] diff --git a/crates/tauri-schema-generator/schemas/config.schema.json b/crates/tauri-schema-generator/schemas/config.schema.json index 69a2a3160bfd..462cc7e9c0b0 100644 --- a/crates/tauri-schema-generator/schemas/config.schema.json +++ b/crates/tauri-schema-generator/schemas/config.schema.json @@ -425,7 +425,7 @@ ] }, "trafficLightPosition": { - "description": "The position of the window controls on macOS.\n Requires titleBarStyle: Overlay and decorations: true.", + "description": "The position of the window controls on macOS.\n\n Requires titleBarStyle: Overlay and decorations: true.", "anyOf": [ { "$ref": "#/definitions/LogicalPosition" diff --git a/crates/tauri-utils/src/config.rs b/crates/tauri-utils/src/config.rs index 0f25c99e47e7..7b791c031918 100644 --- a/crates/tauri-utils/src/config.rs +++ b/crates/tauri-utils/src/config.rs @@ -1581,6 +1581,7 @@ pub struct WindowConfig { #[serde(default, alias = "title-bar-style")] pub title_bar_style: TitleBarStyle, /// The position of the window controls on macOS. + /// /// Requires titleBarStyle: Overlay and decorations: true. #[serde(default, alias = "traffic-light-position")] pub traffic_light_position: Option, diff --git a/crates/tauri/src/test/mock_runtime.rs b/crates/tauri/src/test/mock_runtime.rs index 2d45794762ca..60e075b45384 100644 --- a/crates/tauri/src/test/mock_runtime.rs +++ b/crates/tauri/src/test/mock_runtime.rs @@ -465,6 +465,11 @@ impl WindowBuilder for MockWindowBuilder { self } + #[cfg(target_os = "macos")] + fn traffic_light_position(self, x: f64, y: f64) -> Self { + self + } + #[cfg(target_os = "macos")] fn hidden_title(self, transparent: bool) -> Self { self @@ -993,6 +998,10 @@ impl WindowDispatch for MockWindowDispatcher { Ok(()) } + fn set_traffic_light_position(&self, position: Position) -> Result<()> { + Ok(()) + } + fn set_size_constraints( &self, constraints: tauri_runtime::window::WindowSizeConstraints, diff --git a/examples/helloworld/tauri.conf.json b/examples/helloworld/tauri.conf.json index 5b6d19585f8d..89ca17569baa 100644 --- a/examples/helloworld/tauri.conf.json +++ b/examples/helloworld/tauri.conf.json @@ -14,7 +14,9 @@ "width": 800, "height": 600, "resizable": true, - "fullscreen": false + "fullscreen": false, + "titleBarStyle": "Overlay", + "trafficLightPosition": { "x": 100, "y": 100 } } ], "security": {