From 716288bba45e980a8a947318bcfd9326795fe8b0 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Mon, 3 Jun 2024 15:09:22 +0200 Subject: [PATCH] linux/x11: Ignore bounds.origin on resize event This fixes #11236 by ignoring the `bounds.origin` values when the window is only being resized. The cause for the issue was that the `ConfigureNotify` event would contain "wrong" values when the window was being resized (by dragging a corner). In my case it would *always* contain x:14/y:49, which is I think maps to the origin of the top bar in GNOME. We would then persist these wrong values when serializing the workspace. On restart, we'd use these values and end up with the window decorations in the wrong place. What I still don't know: 1. What exactly the 14/49 map to, because it's not the origin of the top bar in GNOME. I also tried the X11 TranslateCoordinates call but couldn't get meaningful results back (even taking scale factor into account). 2. Why the window decorations end up looking wrong vs. the window being in the first place. But if you look at my screenshot in #11236, it looks like the decorations are off exactly by 14/49px. That being said, I think the solution here is a good one for now: we don't do an additional X11 call and when we're resizing, we're not interested in the origin changing. --- crates/gpui/src/platform/linux/x11/window.rs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/crates/gpui/src/platform/linux/x11/window.rs b/crates/gpui/src/platform/linux/x11/window.rs index 8181aa0d62b5d..bc4fb0212c3d8 100644 --- a/crates/gpui/src/platform/linux/x11/window.rs +++ b/crates/gpui/src/platform/linux/x11/window.rs @@ -24,7 +24,6 @@ use x11rb::{ use std::{ cell::RefCell, ffi::c_void, - mem, num::NonZeroU32, ops::Div, ptr::NonNull, @@ -610,11 +609,21 @@ impl X11WindowStatePtr { pub fn configure(&self, bounds: Bounds) { let mut resize_args = None; - let do_move; + let is_resize; { let mut state = self.state.borrow_mut(); - let old_bounds = mem::replace(&mut state.bounds, bounds); - do_move = old_bounds.origin != bounds.origin; + + is_resize = bounds.size.width != state.bounds.size.width + || bounds.size.height != state.bounds.size.height; + + // If it's a resize event (only width/height changed), we ignore `bounds.origin` + // because it contains wrong values. + if is_resize { + state.bounds.size = bounds.size; + } else { + state.bounds = bounds; + } + let gpu_size = query_render_extent(&self.xcb_connection, self.x_window); if state.renderer.viewport_size() != gpu_size { state @@ -630,7 +639,7 @@ impl X11WindowStatePtr { fun(content_size, scale_factor) } } - if do_move { + if !is_resize { if let Some(ref mut fun) = callbacks.moved { fun() }