diff --git a/masonry/src/contexts.rs b/masonry/src/contexts.rs index d95077ee7..ae60fddf0 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; @@ -606,6 +608,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 a2f75aaab..af7f3a380 100644 --- a/masonry/src/event_loop_runner.rs +++ b/masonry/src/event_loop_runner.rs @@ -649,7 +649,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; @@ -696,6 +696,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 ddd1483dd..7c67cef77 100644 --- a/masonry/src/render_root.rs +++ b/masonry/src/render_root.rs @@ -9,6 +9,7 @@ use parley::{FontContext, LayoutContext}; use tracing::{info_span, warn}; use vello::kurbo::{self, Rect}; use vello::Scene; +use winit::window::ResizeDirection; #[cfg(not(target_arch = "wasm32"))] use std::time::Instant; @@ -123,6 +124,12 @@ pub enum RenderRootSignal { SetCursor(CursorIcon), SetSize(PhysicalSize), SetTitle(String), + DragWindow, + DragResizeWindow(ResizeDirection), + ToggleMaximized, + Minimize, + Exit, + ShowWindowMenu(LogicalPosition), } impl RenderRoot { diff --git a/masonry/src/testing/harness.rs b/masonry/src/testing/harness.rs index e432268fd..98dcd4cc3 100644 --- a/masonry/src/testing/harness.rs +++ b/masonry/src/testing/harness.rs @@ -264,6 +264,12 @@ impl TestHarness { RenderRootSignal::SetTitle(title) => { self.title = title; } + RenderRootSignal::DragWindow => (), + RenderRootSignal::DragResizeWindow(_) => (), + RenderRootSignal::ToggleMaximized => (), + RenderRootSignal::Minimize => (), + RenderRootSignal::Exit => (), + RenderRootSignal::ShowWindowMenu(_) => (), } } }