On X11 and Wayland, add is_maximized support

Fixes #1845.

Co-authored-by: Kirill Chibisov <contact@kchibisov.com>
This commit is contained in:
garasubo 2021-06-10 16:43:27 +09:00 committed by GitHub
parent 67cca71524
commit c916eb6137
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 2 deletions

View file

@ -3,6 +3,7 @@
- On Android, implement `Window::request_redraw` - On Android, implement `Window::request_redraw`
- **Breaking:** On Web, remove the `stdweb` backend. - **Breaking:** On Web, remove the `stdweb` backend.
- Added `Window::focus_window`to bring the window to the front and set input focus. - 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) # 0.25.0 (2021-05-15)

View file

@ -380,8 +380,7 @@ impl Window {
#[inline] #[inline]
pub fn is_maximized(&self) -> bool { pub fn is_maximized(&self) -> bool {
// TODO: Not implemented x11_or_wayland!(match self; Window(w) => w.is_maximized())
false
} }
#[inline] #[inline]

View file

@ -54,6 +54,9 @@ pub struct Window {
/// Fullscreen state. /// Fullscreen state.
fullscreen: Arc<AtomicBool>, fullscreen: Arc<AtomicBool>,
/// Maximized state.
maximized: Arc<AtomicBool>,
/// Available windowing features. /// Available windowing features.
windowing_features: WindowingFeatures, windowing_features: WindowingFeatures,
@ -87,6 +90,8 @@ impl Window {
let scale_factor = sctk::get_surface_scale_factor(&surface); let scale_factor = sctk::get_surface_scale_factor(&surface);
let window_id = super::make_wid(&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 = Arc::new(AtomicBool::new(false));
let fullscreen_clone = fullscreen.clone(); let fullscreen_clone = fullscreen.clone();
@ -113,6 +118,8 @@ impl Window {
window_update.refresh_frame = true; window_update.refresh_frame = true;
} }
Event::Configure { new_size, states } => { 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); let is_fullscreen = states.contains(&State::Fullscreen);
fullscreen_clone.store(is_fullscreen, Ordering::Relaxed); fullscreen_clone.store(is_fullscreen, Ordering::Relaxed);
@ -235,6 +242,7 @@ impl Window {
window_requests, window_requests,
event_loop_awakener: event_loop_window_target.event_loop_awakener.clone(), event_loop_awakener: event_loop_window_target.event_loop_awakener.clone(),
fullscreen, fullscreen,
maximized,
windowing_features, windowing_features,
}; };
@ -368,6 +376,11 @@ impl Window {
self.event_loop_awakener.ping(); self.event_loop_awakener.ping();
} }
#[inline]
pub fn is_maximized(&self) -> bool {
self.maximized.load(Ordering::Relaxed)
}
#[inline] #[inline]
pub fn set_maximized(&self, maximized: bool) { pub fn set_maximized(&self, maximized: bool) {
let maximize_request = WindowRequest::Maximize(maximized); let maximize_request = WindowRequest::Maximize(maximized);

View file

@ -779,6 +779,30 @@ impl UnownedWindow {
.expect("Failed to change window minimization"); .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<'_> { fn set_maximized_inner(&self, maximized: bool) -> util::Flusher<'_> {
let horz_atom = unsafe { let horz_atom = unsafe {
self.xconn self.xconn