From 062e0e52ee3fc34549729870973aecd702e05b7e Mon Sep 17 00:00:00 2001 From: acheronfail Date: Fri, 26 Apr 2019 03:09:32 +1000 Subject: [PATCH] Feat/fullscreen getters (#838) * feat: [macos] add get_fullscreen and get_simple_fullscreen * feat: [windows] add get_fullscreen * feat: [ios] add get_fullscreen * feat: [android] add get_fullscreen * feat: [emscripten] add get_fullscreen * feat: [linux] add get_fullscreen * feedback: `get_fullscreen() -> bool` -> `get_fullscreen() -> Option` --- examples/fullscreen.rs | 9 +++++++++ src/platform/macos.rs | 8 ++++++++ src/platform_impl/android/mod.rs | 7 +++++++ src/platform_impl/emscripten/mod.rs | 5 +++++ src/platform_impl/ios/mod.rs | 7 +++++++ src/platform_impl/linux/mod.rs | 9 +++++++++ src/platform_impl/linux/wayland/window.rs | 22 +++++++++++++++++++--- src/platform_impl/linux/x11/window.rs | 7 +++++++ src/platform_impl/macos/window.rs | 13 +++++++++++++ src/platform_impl/windows/window.rs | 6 ++++++ src/window.rs | 6 ++++++ 11 files changed, 96 insertions(+), 3 deletions(-) diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs index 788a608c..3fd96033 100644 --- a/examples/fullscreen.rs +++ b/examples/fullscreen.rs @@ -86,6 +86,15 @@ fn main() { window.set_fullscreen(Some(window.get_current_monitor())); } } + (VirtualKeyCode::S, ElementState::Pressed) => { + println!("window.get_fullscreen {:?}", window.get_fullscreen()); + + #[cfg(target_os = "macos")] + { + use winit::os::macos::WindowExt; + println!("window.get_simple_fullscreen {:?}", WindowExt::get_simple_fullscreen(&window)); + } + } (VirtualKeyCode::M, ElementState::Pressed) => { is_maximized = !is_maximized; window.set_maximized(is_maximized); diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 8997e3b2..bb312b23 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -23,6 +23,9 @@ pub trait WindowExtMacOS { /// - `true`: the dock icon will bounce until the application is focused. fn request_user_attention(&self, is_critical: bool); + /// Returns whether or not the window is in simple fullscreen mode. + fn get_simple_fullscreen(&self) -> bool; + /// Toggles a fullscreen mode that doesn't require a new macOS space. /// Returns a boolean indicating whether the transition was successful (this /// won't work if the window was already in the native fullscreen). @@ -49,6 +52,11 @@ impl WindowExtMacOS for Window { self.window.request_user_attention(is_critical) } + #[inline] + fn get_simple_fullscreen(&self) -> bool { + self.window.get_simple_fullscreen() + } + #[inline] fn set_simple_fullscreen(&self, fullscreen: bool) -> bool { self.window.set_simple_fullscreen(fullscreen) diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index a6c69250..8cad3426 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -368,6 +368,13 @@ impl Window { // Android has single screen maximized apps so nothing to do } + #[inline] + pub fn get_fullscreen(&self) -> Option { + // N/A + // Android has single screen maximized apps so nothing to do + None + } + #[inline] pub fn set_fullscreen(&self, _monitor: Option) { // N/A diff --git a/src/platform_impl/emscripten/mod.rs b/src/platform_impl/emscripten/mod.rs index 571d6b45..95baa7f8 100644 --- a/src/platform_impl/emscripten/mod.rs +++ b/src/platform_impl/emscripten/mod.rs @@ -580,6 +580,11 @@ impl Window { // iOS has single screen maximized apps so nothing to do } + #[inline] + pub fn get_fullscreen(&self) -> Option<::MonitorHandle> { + None + } + #[inline] pub fn set_fullscreen(&self, _monitor: Option<::MonitorHandle>) { // iOS has single screen maximized apps so nothing to do diff --git a/src/platform_impl/ios/mod.rs b/src/platform_impl/ios/mod.rs index da41d15d..ed8d74ba 100644 --- a/src/platform_impl/ios/mod.rs +++ b/src/platform_impl/ios/mod.rs @@ -473,6 +473,13 @@ impl Window { // iOS has single screen maximized apps so nothing to do } + #[inline] + pub fn get_fullscreen(&self) -> Option { + // N/A + // iOS has single screen maximized apps so nothing to do + None + } + #[inline] pub fn set_fullscreen(&self, _monitor: Option) { // N/A diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index ef79e662..b609a4bc 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -297,6 +297,15 @@ impl Window { } } + #[inline] + pub fn get_fullscreen(&self) -> Option { + match self { + &Window::X(ref w) => w.get_fullscreen(), + &Window::Wayland(ref w) => w.get_fullscreen() + .map(|monitor_id| RootMonitorHandle { inner: MonitorHandle::Wayland(monitor_id) }) + } + } + #[inline] pub fn set_fullscreen(&self, monitor: Option) { match self { diff --git a/src/platform_impl/linux/wayland/window.rs b/src/platform_impl/linux/wayland/window.rs index 622b3f8d..15f0341c 100644 --- a/src/platform_impl/linux/wayland/window.rs +++ b/src/platform_impl/linux/wayland/window.rs @@ -7,7 +7,7 @@ use monitor::MonitorHandle as RootMonitorHandle; use window::{CreationError, WindowAttributes, MouseCursor}; use sctk::surface::{get_dpi_factor, get_outputs}; -use sctk::window::{ConceptFrame, Event as WEvent, Window as SWindow, Theme}; +use sctk::window::{ConceptFrame, Event as WEvent, State as WState, Window as SWindow, Theme}; use sctk::reexports::client::Display; use sctk::reexports::client::protocol::{wl_seat, wl_surface}; use sctk::output::OutputMgr; @@ -23,7 +23,8 @@ pub struct Window { kill_switch: (Arc>, Arc>), display: Arc, need_frame_refresh: Arc>, - need_refresh: Arc> + need_refresh: Arc>, + fullscreen: Arc>, } impl Window { @@ -31,6 +32,7 @@ impl Window { let (width, height) = attributes.dimensions.map(Into::into).unwrap_or((800, 600)); // Create the window let size = Arc::new(Mutex::new((width, height))); + let fullscreen = Arc::new(Mutex::new(false)); let window_store = evlp.store.clone(); let surface = evlp.env.create_surface(move |dpi, surface| { @@ -45,12 +47,15 @@ impl Window { surface.clone(), (width, height), move |event| match event { - WEvent::Configure { new_size, .. } => { + WEvent::Configure { new_size, states } => { let mut store = window_store.lock().unwrap(); + let is_fullscreen = states.contains(&WState::Fullscreen); + for window in &mut store.windows { 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; *(window.need_frame_refresh.lock().unwrap()) = true; return; } @@ -117,6 +122,7 @@ impl Window { newsize: None, size: size.clone(), need_refresh: need_refresh.clone(), + fullscreen: fullscreen.clone(), need_frame_refresh: need_frame_refresh.clone(), surface: surface.clone(), kill_switch: kill_switch.clone(), @@ -135,6 +141,7 @@ impl Window { kill_switch: (kill_switch, evlp.cleanup_needed.clone()), need_frame_refresh, need_refresh, + fullscreen, }) } @@ -230,6 +237,14 @@ impl Window { } } + pub fn get_fullscreen(&self) -> Option { + if *(self.fullscreen.lock().unwrap()) { + Some(self.get_current_monitor()) + } else { + None + } + } + pub fn set_fullscreen(&self, monitor: Option) { if let Some(RootMonitorHandle { inner: PlatformMonitorHandle::Wayland(ref monitor_id), @@ -310,6 +325,7 @@ struct InternalWindow { newsize: Option<(u32, u32)>, size: Arc>, need_refresh: Arc>, + fullscreen: Arc>, need_frame_refresh: Arc>, closed: bool, kill_switch: Arc>, diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index 146fe8ff..c205018a 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -38,6 +38,7 @@ pub struct SharedState { pub guessed_dpi: Option, pub last_monitor: Option, pub dpi_adjusted: Option<(f64, f64)>, + pub fullscreen: Option, // Used to restore position after exiting fullscreen. pub restore_position: Option<(i32, i32)>, pub frame_extents: Option, @@ -536,8 +537,14 @@ impl UnownedWindow { } } + #[inline] + pub fn get_fullscreen(&self) -> Option { + self.shared_state.lock().fullscreen.clone() + } + #[inline] pub fn set_fullscreen(&self, monitor: Option) { + self.shared_state.lock().fullscreen = monitor.clone(); self.set_fullscreen_inner(monitor) .flush() .expect("Failed to change window fullscreen state"); diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 34edc551..00c7ab69 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -618,6 +618,11 @@ impl WindowExt for Window2 { } } + #[inline] + fn get_simple_fullscreen(&self) -> bool { + self.delegate.state.is_simple_fullscreen.get() + } + #[inline] fn set_simple_fullscreen(&self, fullscreen: bool) -> bool { let state = &self.delegate.state; @@ -1137,6 +1142,14 @@ impl Window2 { self.delegate.state.perform_maximized(maximized) } + #[inline] + pub fn get_fullscreen(&self) -> Option { + let state = &self.delegate.state; + let win_attribs = state.win_attribs.borrow(); + + win_attribs.fullscreen.clone() + } + #[inline] /// TODO: Right now set_fullscreen do not work on switching monitors /// in fullscreen mode diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 7fe74c32..555955bb 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -399,6 +399,12 @@ impl Window { }); } + #[inline] + pub fn get_fullscreen(&self) -> Option { + let window_state = self.window_state.lock(); + window_state.fullscreen.clone() + } + #[inline] pub fn set_fullscreen(&self, monitor: Option) { unsafe { diff --git a/src/window.rs b/src/window.rs index d837f3cb..0bc9c08b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -536,6 +536,12 @@ impl Window { self.window.set_fullscreen(monitor) } + /// Gets the window's current fullscreen state. + #[inline] + pub fn get_fullscreen(&self) -> Option { + self.window.get_fullscreen() + } + /// Turn window decorations on or off. #[inline] pub fn set_decorations(&self, decorations: bool) {