diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 3d81e88fb4cfb3776b4729e7a4dad88284581259..3d0472026a3c12d7cfac2ee6d2dd0d517b83b293 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -281,6 +281,16 @@ pub struct Tiling { } impl Tiling { + /// Initializes a [`Tiling`] type with all sides tiled + pub fn tiled() -> Self { + Self { + top: true, + left: true, + right: true, + bottom: true, + } + } + /// Whether any edge is tiled pub fn is_tiled(&self) -> bool { self.top || self.left || self.right || self.bottom diff --git a/crates/gpui/src/platform/linux/wayland/client.rs b/crates/gpui/src/platform/linux/wayland/client.rs index dd645e959bf8f295ab079b53c6aa6c4a561bba5d..62fb6ccc8888a2df87d8e6642d62715c989a6e64 100644 --- a/crates/gpui/src/platform/linux/wayland/client.rs +++ b/crates/gpui/src/platform/linux/wayland/client.rs @@ -809,7 +809,7 @@ impl Dispatch for WaylandClientStatePtr { match event { wl_callback::Event::Done { .. } => { - window.frame(true); + window.frame(); } _ => {} } diff --git a/crates/gpui/src/platform/linux/wayland/window.rs b/crates/gpui/src/platform/linux/wayland/window.rs index 5ab64e9e1ef86d4e0dff25e165b2c05e8669b4e5..70d6ecec1bf804efb6c48f4fa693c151c52b1179 100644 --- a/crates/gpui/src/platform/linux/wayland/window.rs +++ b/crates/gpui/src/platform/linux/wayland/window.rs @@ -100,7 +100,6 @@ pub struct WaylandWindowState { in_progress_window_controls: Option, window_controls: WindowControls, inset: Option, - requested_inset: Option, } #[derive(Clone)] @@ -189,7 +188,6 @@ impl WaylandWindowState { window_menu: true, }, inset: None, - requested_inset: None, }) } @@ -316,12 +314,11 @@ impl WaylandWindowStatePtr { Rc::ptr_eq(&self.state, &other.state) } - pub fn frame(&self, request_frame_callback: bool) { - if request_frame_callback { - let mut state = self.state.borrow_mut(); - state.surface.frame(&state.globals.qh, state.surface.id()); - drop(state); - } + pub fn frame(&self) { + let mut state = self.state.borrow_mut(); + state.surface.frame(&state.globals.qh, state.surface.id()); + drop(state); + let mut cb = self.callbacks.borrow_mut(); if let Some(fun) = cb.request_frame.as_mut() { fun(); @@ -351,13 +348,12 @@ impl WaylandWindowStatePtr { state.fullscreen = configure.fullscreen; state.maximized = configure.maximized; state.tiling = configure.tiling; - if got_unmaximized { - configure.size = Some(state.window_bounds.size); - } else if !configure.maximized { - configure.size = - compute_outer_size(state.inset, configure.size, state.tiling); - } if !configure.fullscreen && !configure.maximized { + configure.size = if got_unmaximized { + Some(state.window_bounds.size) + } else { + compute_outer_size(state.inset, configure.size, state.tiling) + }; if let Some(size) = configure.size { state.window_bounds = Bounds { origin: Point::default(), @@ -373,12 +369,27 @@ impl WaylandWindowStatePtr { } let mut state = self.state.borrow_mut(); state.xdg_surface.ack_configure(serial); - let request_frame_callback = !state.acknowledged_first_configure; - state.acknowledged_first_configure = true; + let window_geometry = inset_by_tiling( + state.bounds.map_origin(|_| px(0.0)), + state.inset.unwrap_or(px(0.0)), + state.tiling, + ) + .map(|v| v.0 as i32) + .map_size(|v| if v <= 0 { 1 } else { v }); + + state.xdg_surface.set_window_geometry( + window_geometry.origin.x, + window_geometry.origin.y, + window_geometry.size.width, + window_geometry.size.height, + ); + + let request_frame_callback = !state.acknowledged_first_configure; if request_frame_callback { + state.acknowledged_first_configure = true; drop(state); - self.frame(true); + self.frame(); } } _ => {} @@ -470,6 +481,10 @@ impl WaylandWindowStatePtr { } } + if fullscreen || maximized { + tiling = Tiling::tiled(); + } + let mut state = self.state.borrow_mut(); state.in_progress_configure = Some(InProgressConfigure { size, @@ -893,26 +908,7 @@ impl PlatformWindow for WaylandWindow { } fn completed_frame(&self) { - let mut state = self.borrow_mut(); - if let Some(area) = state.requested_inset { - state.inset = Some(area); - } - - let window_geometry = inset_by_tiling( - state.bounds.map_origin(|_| px(0.0)), - state.inset.unwrap_or(px(0.0)), - state.tiling, - ) - .map(|v| v.0 as i32) - .map_size(|v| if v <= 0 { 1 } else { v }); - - state.xdg_surface.set_window_geometry( - window_geometry.origin.x, - window_geometry.origin.y, - window_geometry.size.width, - window_geometry.size.height, - ); - + let state = self.borrow(); state.surface.commit(); } @@ -973,7 +969,7 @@ impl PlatformWindow for WaylandWindow { fn set_client_inset(&self, inset: Pixels) { let mut state = self.borrow_mut(); if Some(inset) != state.inset { - state.requested_inset = Some(inset); + state.inset = Some(inset); update_window(state); } } diff --git a/crates/title_bar/src/platforms/platform_linux.rs b/crates/title_bar/src/platforms/platform_linux.rs index dd71e5962566554c580513d91424499e64d705ec..8e46100479f8d5d5520b2061f4a74442f2d4a602 100644 --- a/crates/title_bar/src/platforms/platform_linux.rs +++ b/crates/title_bar/src/platforms/platform_linux.rs @@ -1,4 +1,4 @@ -use gpui::{prelude::*, Action}; +use gpui::{prelude::*, Action, MouseButton}; use ui::prelude::*; @@ -23,6 +23,7 @@ impl RenderOnce for LinuxWindowControls { .id("generic-window-controls") .px_3() .gap_3() + .on_mouse_down(MouseButton::Left, |_, cx| cx.stop_propagation()) .child(WindowControl::new( "minimize", WindowControlType::Minimize,