diff --git a/CHANGELOG.md b/CHANGELOG.md index 92924ce5..523dda53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - On Wayland, Add HiDPI cursor support - On Web, add the ability to query "Light" or "Dark" system theme send `ThemeChanged` on change. - Fix `Event::to_static` returning `None` for user events. +- On Wayland, Hide CSD for fullscreen windows. # 0.21.0 (2020-02-04) diff --git a/src/platform_impl/linux/wayland/event_loop.rs b/src/platform_impl/linux/wayland/event_loop.rs index 4a1e1959..47c5aea6 100644 --- a/src/platform_impl/linux/wayland/event_loop.rs +++ b/src/platform_impl/linux/wayland/event_loop.rs @@ -39,7 +39,10 @@ use crate::{ window::{CursorIcon, WindowId as RootWindowId}, }; -use super::{window::WindowStore, DeviceId, WindowId}; +use super::{ + window::{DecorationsAction, WindowStore}, + DeviceId, WindowId, +}; use smithay_client_toolkit::{ output::OutputMgr, @@ -713,6 +716,13 @@ impl EventLoop { crate::window::WindowId(crate::platform_impl::WindowId::Wayland(window.wid)); if let Some(frame) = window.frame { if let Some((w, h)) = window.newsize { + // Update decorations state + match window.decorations_action { + Some(DecorationsAction::Hide) => frame.set_decorate(false), + Some(DecorationsAction::Show) => frame.set_decorate(true), + None => (), + } + // 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. diff --git a/src/platform_impl/linux/wayland/window.rs b/src/platform_impl/linux/wayland/window.rs index 03b58b38..7c30a79b 100644 --- a/src/platform_impl/linux/wayland/window.rs +++ b/src/platform_impl/linux/wayland/window.rs @@ -41,6 +41,13 @@ pub struct Window { need_refresh: Arc>, fullscreen: Arc>, cursor_grab_changed: Arc>>, // Update grab state + decorated: Arc>, +} + +#[derive(Clone, Copy, Debug)] +pub enum DecorationsAction { + Hide, + Show, } impl Window { @@ -69,6 +76,9 @@ impl Window { let window_store = evlp.store.clone(); + let decorated = Arc::new(Mutex::new(attributes.decorations)); + let pending_decorations_action = Arc::new(Mutex::new(None)); + let my_surface = surface.clone(); let mut frame = SWindow::::init_from_env( &evlp.env, @@ -83,7 +93,23 @@ impl Window { if window.surface.as_ref().equals(&my_surface.as_ref()) { window.newsize = new_size; *(window.need_refresh.lock().unwrap()) = true; - *(window.fullscreen.lock().unwrap()) = is_fullscreen; + { + // Get whether we're in fullscreen + let mut fullscreen = window.fullscreen.lock().unwrap(); + // Fullscreen state was changed, so update decorations + if *fullscreen != is_fullscreen { + let decorated = { *window.decorated.lock().unwrap() }; + if decorated { + *window.pending_decorations_action.lock().unwrap() = + if is_fullscreen { + Some(DecorationsAction::Hide) + } else { + Some(DecorationsAction::Show) + }; + } + } + *fullscreen = is_fullscreen; + } *(window.need_frame_refresh.lock().unwrap()) = true; return; } @@ -174,6 +200,8 @@ impl Window { frame: Arc::downgrade(&frame), current_dpi: 1, new_dpi: None, + decorated: decorated.clone(), + pending_decorations_action: pending_decorations_action.clone(), }); evlp.evq.borrow_mut().sync_roundtrip().unwrap(); @@ -189,6 +217,7 @@ impl Window { cursor_manager, fullscreen, cursor_grab_changed, + decorated, }) } @@ -277,6 +306,7 @@ impl Window { } pub fn set_decorations(&self, decorate: bool) { + *(self.decorated.lock().unwrap()) = decorate; self.frame.lock().unwrap().set_decorate(decorate); *(self.need_frame_refresh.lock().unwrap()) = true; } @@ -409,6 +439,8 @@ struct InternalWindow { frame: Weak>>, current_dpi: i32, new_dpi: Option, + decorated: Arc>, + pending_decorations_action: Arc>>, } pub struct WindowStore { @@ -425,6 +457,7 @@ pub struct WindowStoreForEach<'a> { pub surface: &'a wl_surface::WlSurface, pub wid: WindowId, pub frame: Option<&'a mut SWindow>, + pub decorations_action: Option, } impl WindowStore { @@ -482,6 +515,7 @@ impl WindowStore { let opt_arc = window.frame.upgrade(); let mut opt_mutex_lock = opt_arc.as_ref().map(|m| m.lock().unwrap()); let mut size = { *window.size.lock().unwrap() }; + let decorations_action = { window.pending_decorations_action.lock().unwrap().take() }; f(WindowStoreForEach { newsize: window.newsize.take(), size: &mut size, @@ -492,6 +526,7 @@ impl WindowStore { surface: &window.surface, wid: make_wid(&window.surface), frame: opt_mutex_lock.as_mut().map(|m| &mut **m), + decorations_action, }); *window.size.lock().unwrap() = size; if let Some(dpi) = window.new_dpi.take() {