linux/x11: Ignore bounds.origin on resize event (#12604)

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 might
map 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.



Release Notes:

- N/A

Proof:

[Screencast from 2024-06-03
15-08-36.webm](https://github.com/zed-industries/zed/assets/1185253/90efccfc-8ec6-42d2-8380-1625eff57805)
This commit is contained in:
Thorsten Ball 2024-06-03 16:25:12 +02:00 committed by GitHub
parent 5f98b9617a
commit 338df5de1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -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<i32>) {
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()
}