diff --git a/CHANGELOG.md b/CHANGELOG.md index 355a415c..633b0269 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ - On Android, implement `Window::request_redraw` - **Breaking:** On Web, remove the `stdweb` backend. - Added `Window::focus_window`to bring the window to the front and set input focus. +- On Wayland and X11, implement `is_maximized` method on `Window`. # 0.25.0 (2021-05-15) diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 2953271d..c85bc5af 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -380,8 +380,7 @@ impl Window { #[inline] pub fn is_maximized(&self) -> bool { - // TODO: Not implemented - false + x11_or_wayland!(match self; Window(w) => w.is_maximized()) } #[inline] diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 5f59651e..745dfc9d 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -54,6 +54,9 @@ pub struct Window { /// Fullscreen state. fullscreen: Arc, + /// Maximized state. + maximized: Arc, + /// Available windowing features. windowing_features: WindowingFeatures, @@ -87,6 +90,8 @@ impl Window { let scale_factor = sctk::get_surface_scale_factor(&surface); let window_id = super::make_wid(&surface); + let maximized = Arc::new(AtomicBool::new(false)); + let maximzied_clone = maximized.clone(); let fullscreen = Arc::new(AtomicBool::new(false)); let fullscreen_clone = fullscreen.clone(); @@ -113,6 +118,8 @@ impl Window { window_update.refresh_frame = true; } Event::Configure { new_size, states } => { + let is_maximized = states.contains(&State::Maximized); + maximzied_clone.store(is_maximized, Ordering::Relaxed); let is_fullscreen = states.contains(&State::Fullscreen); fullscreen_clone.store(is_fullscreen, Ordering::Relaxed); @@ -235,6 +242,7 @@ impl Window { window_requests, event_loop_awakener: event_loop_window_target.event_loop_awakener.clone(), fullscreen, + maximized, windowing_features, }; @@ -368,6 +376,11 @@ impl Window { self.event_loop_awakener.ping(); } + #[inline] + pub fn is_maximized(&self) -> bool { + self.maximized.load(Ordering::Relaxed) + } + #[inline] pub fn set_maximized(&self, maximized: bool) { let maximize_request = WindowRequest::Maximize(maximized); diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 1e5a32a2..9f3d5736 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -779,6 +779,30 @@ impl UnownedWindow { .expect("Failed to change window minimization"); } + #[inline] + pub fn is_maximized(&self) -> bool { + let state_atom = unsafe { self.xconn.get_atom_unchecked(b"_NET_WM_STATE\0") }; + let state = self + .xconn + .get_property(self.xwindow, state_atom, ffi::XA_ATOM); + let horz_atom = unsafe { + self.xconn + .get_atom_unchecked(b"_NET_WM_STATE_MAXIMIZED_HORZ\0") + }; + let vert_atom = unsafe { + self.xconn + .get_atom_unchecked(b"_NET_WM_STATE_MAXIMIZED_VERT\0") + }; + match state { + Ok(atoms) => { + let horz_maximized = atoms.iter().any(|atom: &ffi::Atom| *atom == horz_atom); + let vert_maximized = atoms.iter().any(|atom: &ffi::Atom| *atom == vert_atom); + horz_maximized && vert_maximized + } + _ => false, + } + } + fn set_maximized_inner(&self, maximized: bool) -> util::Flusher<'_> { let horz_atom = unsafe { self.xconn