Skip to content

Commit

Permalink
Add basic window control (#670)
Browse files Browse the repository at this point in the history
This is the first merge-able part of #606.

It allows to implement custom CSDs via window management signals and a
new `WindowHandle` widget which is useful to implement a custom
titlebar.
  • Loading branch information
melix99 authored Nov 11, 2024
1 parent a6800f4 commit 6db696d
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
54 changes: 54 additions & 0 deletions masonry/src/contexts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<f64>) {
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
Expand Down
22 changes: 21 additions & 1 deletion masonry/src/event_loop_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions masonry/src/render_root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -123,6 +124,12 @@ pub enum RenderRootSignal {
SetCursor(CursorIcon),
SetSize(PhysicalSize<u32>),
SetTitle(String),
DragWindow,
DragResizeWindow(ResizeDirection),
ToggleMaximized,
Minimize,
Exit,
ShowWindowMenu(LogicalPosition<f64>),
}

impl RenderRoot {
Expand Down
6 changes: 6 additions & 0 deletions masonry/src/testing/harness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,12 @@ impl TestHarness {
RenderRootSignal::SetTitle(title) => {
self.title = title;
}
RenderRootSignal::DragWindow => (),
RenderRootSignal::DragResizeWindow(_) => (),
RenderRootSignal::ToggleMaximized => (),
RenderRootSignal::Minimize => (),
RenderRootSignal::Exit => (),
RenderRootSignal::ShowWindowMenu(_) => (),
}
}
}
Expand Down

0 comments on commit 6db696d

Please sign in to comment.