diff --git a/masonry/src/contexts.rs b/masonry/src/contexts.rs index 6fecd9959..6d678c8f5 100644 --- a/masonry/src/contexts.rs +++ b/masonry/src/contexts.rs @@ -6,9 +6,11 @@ use std::time::Duration; use accesskit::TreeUpdate; +use dpi::LogicalPosition; use parley::{FontContext, LayoutContext}; use tracing::{trace, warn}; use vello::kurbo::Vec2; +use winit::window::ResizeDirection; use crate::action::Action; use crate::passes::layout::run_layout_on; @@ -619,6 +621,58 @@ impl_context_method!( .emit_signal(RenderRootSignal::Action(action, self.widget_state.id)); } + /// Start a window drag. + /// + /// Moves the window with the left mouse button until the button is released. + pub fn drag_window(&mut self) { + trace!("drag_window"); + self.global_state + .signal_queue + .push_back(RenderRootSignal::DragWindow); + } + + /// Start a window resize. + /// + /// Resizes the window with the left mouse button until the button is released. + pub fn drag_resize_window(&mut self, direction: ResizeDirection) { + trace!("drag_resize_window"); + self.global_state + .signal_queue + .push_back(RenderRootSignal::DragResizeWindow(direction)); + } + + /// Toggle the maximized state of the window. + pub fn toggle_maximized(&mut self) { + trace!("toggle_maximized"); + self.global_state + .signal_queue + .push_back(RenderRootSignal::ToggleMaximized); + } + + /// Minimize the window. + pub fn minimize(&mut self) { + trace!("minimize"); + self.global_state + .signal_queue + .push_back(RenderRootSignal::Minimize); + } + + /// Exit the application. + pub fn exit(&mut self) { + trace!("exit"); + self.global_state + .signal_queue + .push_back(RenderRootSignal::Exit); + } + + /// Show the window menu at a specified position. + pub fn show_window_menu(&mut self, position: LogicalPosition) { + trace!("show_window_menu"); + self.global_state + .signal_queue + .push_back(RenderRootSignal::ShowWindowMenu(position)); + } + /// Request a timer event. /// /// The return value is a token, which can be used to associate the diff --git a/masonry/src/event_loop_runner.rs b/masonry/src/event_loop_runner.rs index 0844b9818..f5c865365 100644 --- a/masonry/src/event_loop_runner.rs +++ b/masonry/src/event_loop_runner.rs @@ -647,7 +647,7 @@ impl MasonryState<'_> { pub fn handle_memory_warning(&mut self, _: &ActiveEventLoop) {} // --- MARK: SIGNALS --- - fn handle_signals(&mut self, _event_loop: &ActiveEventLoop, app_driver: &mut dyn AppDriver) { + fn handle_signals(&mut self, event_loop: &ActiveEventLoop, app_driver: &mut dyn AppDriver) { let WindowState::Rendering { window, .. } = &mut self.window else { tracing::warn!("Tried to handle a signal whilst suspended or before window created"); return; @@ -692,6 +692,26 @@ impl MasonryState<'_> { render_root::RenderRootSignal::SetTitle(title) => { window.set_title(&title); } + render_root::RenderRootSignal::DragWindow => { + // TODO - Handle return value? + let _ = window.drag_window(); + } + render_root::RenderRootSignal::DragResizeWindow(direction) => { + // TODO - Handle return value? + let _ = window.drag_resize_window(direction); + } + render_root::RenderRootSignal::ToggleMaximized => { + window.set_maximized(!window.is_maximized()); + } + render_root::RenderRootSignal::Minimize => { + window.set_minimized(true); + } + render_root::RenderRootSignal::Exit => { + event_loop.exit(); + } + render_root::RenderRootSignal::ShowWindowMenu(position) => { + window.show_window_menu(position); + } } } } diff --git a/masonry/src/render_root.rs b/masonry/src/render_root.rs index a9812ef9c..e1fbf4cf3 100644 --- a/masonry/src/render_root.rs +++ b/masonry/src/render_root.rs @@ -9,6 +9,7 @@ use parley::{FontContext, LayoutContext}; use tracing::warn; use vello::kurbo::{self, Rect}; use vello::Scene; +use winit::window::ResizeDirection; #[cfg(not(target_arch = "wasm32"))] use std::time::Instant; @@ -118,6 +119,12 @@ pub enum RenderRootSignal { SetCursor(CursorIcon), SetSize(PhysicalSize), SetTitle(String), + DragWindow, + DragResizeWindow(ResizeDirection), + ToggleMaximized, + Minimize, + Exit, + ShowWindowMenu(LogicalPosition), } impl RenderRoot {