From 73248bdcedd781c2286e4c36dbf595cde15fa747 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 20 Dec 2019 03:08:28 +0300 Subject: [PATCH] On Wayland, under mutter(GNOME Wayland), fix CSD being behind the status bar, when starting window in maximized mode (#1324) Mutter can reposition window on resize, if it is behind mutter's "bounding box". So, when you start winit window in maximized mode with CSD, mutter places its CSD behind the GNOME's status bar initially, and then sends configure with the exact same size as your current window. If winit decides to optimize calling frame.resize(..) in this case, we won't call set_geometry(we're calling it through resize) and GNOME won't reposition your window to be inside the "bounding box", which is not a desired behavior for the end user. --- CHANGELOG.md | 1 + src/platform_impl/linux/wayland/event_loop.rs | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1ef822f..f53bb569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - On macOS, fix application not to terminate on `run_return`. - On Wayland, fix cursor icon updates on window borders when using CSD. +- On Wayland, under mutter(GNOME Wayland), fix CSD being behind the status bar, when starting window in maximized mode. # # 0.20.0 Alpha 5 (2019-12-09) diff --git a/src/platform_impl/linux/wayland/event_loop.rs b/src/platform_impl/linux/wayland/event_loop.rs index 61f24c0a..fba70fa8 100644 --- a/src/platform_impl/linux/wayland/event_loop.rs +++ b/src/platform_impl/linux/wayland/event_loop.rs @@ -673,20 +673,22 @@ impl EventLoop { window_target.store.lock().unwrap().for_each(|window| { if let Some(frame) = window.frame { if let Some(newsize) = window.newsize { - // Drop resize events equaled to the current size + let (w, h) = newsize; + // mutter (GNOME Wayland) relies on `set_geometry` to reposition window in case + // it overlaps mutter's `bounding box`, so we can't avoid this resize call, + // which calls `set_geometry` under the hood, for now. + frame.resize(w, h); + frame.refresh(); + // Don't send resize event downstream if the new size is identical to the + // current one. if newsize != *window.size { - let (w, h) = newsize; - frame.resize(w, h); - frame.refresh(); let logical_size = crate::dpi::LogicalSize::new(w as f64, h as f64); sink.send_window_event( crate::event::WindowEvent::Resized(logical_size), window.wid, ); + *window.size = (w, h); - } else { - // Refresh csd, etc, otherwise - frame.refresh(); } } else if window.frame_refresh { frame.refresh();