From 944a6eeea2119253b1816e17eff784302c8b4124 Mon Sep 17 00:00:00 2001 From: Timon Date: Sat, 13 Sep 2025 13:15:52 -0700 Subject: [PATCH] Desktop: Hook up native window controls (#3161) * Implement window controls * Fix drag target size * Maximize with drag area double click --- desktop/src/app.rs | 9 ++++++++- desktop/wrapper/src/intercept_frontend_message.rs | 3 +++ desktop/wrapper/src/messages.rs | 3 ++- editor/src/messages/app_window/app_window_message.rs | 1 + .../messages/app_window/app_window_message_handler.rs | 3 +++ editor/src/messages/frontend/frontend_message.rs | 1 + frontend/src/components/layout/LayoutRow.svelte | 2 +- frontend/src/components/window/title-bar/TitleBar.svelte | 4 +++- frontend/wasm/src/editor_api.rs | 7 +++++++ 9 files changed, 29 insertions(+), 4 deletions(-) diff --git a/desktop/src/app.rs b/desktop/src/app.rs index 761d97a6..4326f1f8 100644 --- a/desktop/src/app.rs +++ b/desktop/src/app.rs @@ -164,6 +164,11 @@ impl WinitApp { window.set_minimized(minimized); } } + DesktopFrontendMessage::DragWindow => { + if let Some(window) = &self.window { + let _ = window.drag_window(); + } + } DesktopFrontendMessage::CloseWindow => { let _ = self.event_loop_proxy.send_event(CustomEvent::CloseWindow); } @@ -271,7 +276,9 @@ impl ApplicationHandler for WinitApp { let mut window = Window::default_attributes() .with_title(APP_NAME) .with_min_inner_size(winit::dpi::LogicalSize::new(400, 300)) - .with_inner_size(winit::dpi::LogicalSize::new(1200, 800)); + .with_inner_size(winit::dpi::LogicalSize::new(1200, 800)) + .with_decorations(false) + .with_resizable(true); #[cfg(target_os = "linux")] { diff --git a/desktop/wrapper/src/intercept_frontend_message.rs b/desktop/wrapper/src/intercept_frontend_message.rs index 1b6bed3e..68eb5493 100644 --- a/desktop/wrapper/src/intercept_frontend_message.rs +++ b/desktop/wrapper/src/intercept_frontend_message.rs @@ -70,6 +70,9 @@ pub(super) fn intercept_frontend_message(dispatcher: &mut DesktopWrapperMessageD // Forward this to update the UI return Some(message); } + FrontendMessage::DragWindow => { + dispatcher.respond(DesktopFrontendMessage::DragWindow); + } FrontendMessage::CloseWindow => { dispatcher.respond(DesktopFrontendMessage::CloseWindow); } diff --git a/desktop/wrapper/src/messages.rs b/desktop/wrapper/src/messages.rs index c335b78d..8804944e 100644 --- a/desktop/wrapper/src/messages.rs +++ b/desktop/wrapper/src/messages.rs @@ -36,6 +36,8 @@ pub enum DesktopFrontendMessage { maximized: bool, minimized: bool, }, + DragWindow, + CloseWindow, PersistenceWriteDocument { id: DocumentId, document: Document, @@ -55,7 +57,6 @@ pub enum DesktopFrontendMessage { preferences: Preferences, }, PersistenceLoadPreferences, - CloseWindow, } pub enum DesktopWrapperMessage { diff --git a/editor/src/messages/app_window/app_window_message.rs b/editor/src/messages/app_window/app_window_message.rs index d0631606..5c48089e 100644 --- a/editor/src/messages/app_window/app_window_message.rs +++ b/editor/src/messages/app_window/app_window_message.rs @@ -8,5 +8,6 @@ pub enum AppWindowMessage { AppWindowMinimize, AppWindowMaximize, AppWindowUpdatePlatform { platform: AppWindowPlatform }, + AppWindowDrag, AppWindowClose, } diff --git a/editor/src/messages/app_window/app_window_message_handler.rs b/editor/src/messages/app_window/app_window_message_handler.rs index db4036b5..ed1ce473 100644 --- a/editor/src/messages/app_window/app_window_message_handler.rs +++ b/editor/src/messages/app_window/app_window_message_handler.rs @@ -31,6 +31,9 @@ impl MessageHandler for AppWindowMessageHandler { self.platform = platform; responses.add(FrontendMessage::UpdatePlatform { platform: self.platform }); } + AppWindowMessage::AppWindowDrag => { + responses.add(FrontendMessage::DragWindow); + } AppWindowMessage::AppWindowClose => { responses.add(FrontendMessage::CloseWindow); } diff --git a/editor/src/messages/frontend/frontend_message.rs b/editor/src/messages/frontend/frontend_message.rs index bbba55c5..5a1d3249 100644 --- a/editor/src/messages/frontend/frontend_message.rs +++ b/editor/src/messages/frontend/frontend_message.rs @@ -343,6 +343,7 @@ pub enum FrontendMessage { maximized: bool, minimized: bool, }, + DragWindow, CloseWindow, UpdateViewportHolePunch { active: bool, diff --git a/frontend/src/components/layout/LayoutRow.svelte b/frontend/src/components/layout/LayoutRow.svelte index fad0220a..6f1b8f78 100644 --- a/frontend/src/components/layout/LayoutRow.svelte +++ b/frontend/src/components/layout/LayoutRow.svelte @@ -43,6 +43,7 @@ on:dragover on:dragstart on:drop + on:mousedown on:mouseup on:pointerdown on:pointerenter @@ -67,7 +68,6 @@ on:keydown on:keypress on:keyup on:lostpointercapture -on:mousedown on:mouseenter on:mouseleave on:mousemove diff --git a/frontend/src/components/window/title-bar/TitleBar.svelte b/frontend/src/components/window/title-bar/TitleBar.svelte index dc204569..eb246269 100644 --- a/frontend/src/components/window/title-bar/TitleBar.svelte +++ b/frontend/src/components/window/title-bar/TitleBar.svelte @@ -76,13 +76,15 @@ {/each} {/if} + editor.handle.appWindowDrag()} on:dblclick={() => editor.handle.appWindowMaximize()} /> - + editor.handle.appWindowDrag()} on:dblclick={() => editor.handle.appWindowMaximize()}> + editor.handle.appWindowDrag()} on:dblclick={() => editor.handle.appWindowMaximize()} /> {#if platform === "Windows"} {:else if platform === "Linux"} diff --git a/frontend/wasm/src/editor_api.rs b/frontend/wasm/src/editor_api.rs index ea4b5d12..c05c09f1 100644 --- a/frontend/wasm/src/editor_api.rs +++ b/frontend/wasm/src/editor_api.rs @@ -352,6 +352,13 @@ impl EditorHandle { self.dispatch(message); } + /// Drag the application window + #[wasm_bindgen(js_name = appWindowDrag)] + pub fn app_window_start_drag(&self) { + let message = AppWindowMessage::AppWindowDrag; + self.dispatch(message); + } + /// Displays a dialog with an error message #[wasm_bindgen(js_name = errorDialog)] pub fn error_dialog(&self, title: String, description: String) {