diff --git a/src/lib.rs b/src/lib.rs index 0121365e..bb72c979 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -356,6 +356,24 @@ pub enum MouseCursor { RowResize, } +/// Describes if the Window is in one of the fullscreen modes +#[derive(Clone, PartialEq)] +pub enum FullScreenState { + None, + Windowed, + Exclusive(platform::MonitorId), +} + +impl FullScreenState { + pub fn get_monitor(&self) -> Option { + if let FullScreenState::Exclusive(ref monitor) = *self { + Some(monitor.clone()) + } else { + None + } + } +} + /// Describes how winit handles the cursor. #[derive(Debug, Copy, Clone, PartialEq)] pub enum CursorState { @@ -392,10 +410,10 @@ pub struct WindowAttributes { /// The default is `None`. pub max_dimensions: Option<(u32, u32)>, - /// If `Some`, the window will be in fullscreen mode with the given monitor. + /// Whether the window should be set as fullscreen upon creation. /// /// The default is `None`. - pub monitor: Option, + pub fullscreen: FullScreenState, /// The title of the window in the title bar. /// @@ -435,9 +453,9 @@ impl Default for WindowAttributes { dimensions: None, min_dimensions: None, max_dimensions: None, - monitor: None, title: "winit window".to_owned(), maximized: false, + fullscreen: FullScreenState::None, visible: true, transparent: false, decorations: true, diff --git a/src/platform/android/mod.rs b/src/platform/android/mod.rs index 09c9cb14..61a3adb9 100644 --- a/src/platform/android/mod.rs +++ b/src/platform/android/mod.rs @@ -260,6 +260,10 @@ impl Window { pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> { unimplemented!(); } + + #[inline] + pub fn set_fullscreen_windowed(&self, fullscreen: bool) { + } } unsafe impl Send for Window {} diff --git a/src/platform/linux/mod.rs b/src/platform/linux/mod.rs index 03e5ae4c..5db5818d 100644 --- a/src/platform/linux/mod.rs +++ b/src/platform/linux/mod.rs @@ -97,7 +97,7 @@ pub enum DeviceId { Wayland(wayland::DeviceId) } -#[derive(Clone)] +#[derive(Clone, PartialEq)] pub enum MonitorId { #[doc(hidden)] X(x11::MonitorId), @@ -317,6 +317,14 @@ impl Window2 { &Window2::Wayland(ref _w) => {}, } } + + #[inline] + pub fn set_fullscreen_windowed(&self, fullscreen: bool) { + match self { + &Window2::X(ref w) => w.set_fullscreen_windowed(fullscreen), + &Window2::Wayland(ref _w) => {}, + } + } } unsafe extern "C" fn x_error_callback(dpy: *mut x11::ffi::Display, event: *mut x11::ffi::XErrorEvent) diff --git a/src/platform/linux/wayland/context.rs b/src/platform/linux/wayland/context.rs index 98367bbf..90aad34e 100644 --- a/src/platform/linux/wayland/context.rs +++ b/src/platform/linux/wayland/context.rs @@ -359,6 +359,12 @@ pub struct MonitorId { ctxt: Arc } +impl PartialEq for MonitorId { + fn eq(&self, other: &MonitorId) -> bool { + self.id == other.id + } +} + impl MonitorId { pub fn get_name(&self) -> Option { let mut guard = self.ctxt.evq.lock().unwrap(); diff --git a/src/platform/linux/wayland/window.rs b/src/platform/linux/wayland/window.rs index b67d77f2..98e56e0e 100644 --- a/src/platform/linux/wayland/window.rs +++ b/src/platform/linux/wayland/window.rs @@ -54,7 +54,7 @@ impl Window { *(decorated.handler()) = Some(DecoratedHandler::new()); // set fullscreen if necessary - if let Some(PlatformMonitorId::Wayland(ref monitor_id)) = attributes.monitor { + if let Some(PlatformMonitorId::Wayland(ref monitor_id)) = attributes.fullscreen.get_monitor() { ctxt.with_output(monitor_id.clone(), |output| { decorated.set_fullscreen(Some(output)) }); diff --git a/src/platform/linux/x11/monitor.rs b/src/platform/linux/x11/monitor.rs index d6479c91..392f0a4f 100644 --- a/src/platform/linux/x11/monitor.rs +++ b/src/platform/linux/x11/monitor.rs @@ -6,6 +6,11 @@ use native_monitor::NativeMonitorId; #[derive(Clone)] pub struct MonitorId(pub Arc, pub u32); +impl PartialEq for MonitorId { + fn eq(&self, other: &MonitorId) -> bool { + self.1 == other.1 + } +} pub fn get_available_monitors(x: &Arc) -> VecDeque { let nb_monitors = unsafe { (x.xlib.XScreenCount)(x.display) }; diff --git a/src/platform/linux/x11/window.rs b/src/platform/linux/x11/window.rs index f7b1e8d1..b588bf33 100644 --- a/src/platform/linux/x11/window.rs +++ b/src/platform/linux/x11/window.rs @@ -11,6 +11,7 @@ use std::time::Duration; use CursorState; use WindowAttributes; +use FullScreenState; use platform::PlatformSpecificWindowBuilderAttributes; use platform::MonitorId as PlatformMonitorId; @@ -128,12 +129,14 @@ impl Window { let screen_id = match pl_attribs.screen_id { Some(id) => id, - None => match window_attrs.monitor { - Some(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32, + None => match window_attrs.fullscreen { + FullScreenState::Exclusive(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32, _ => unsafe { (display.xlib.XDefaultScreen)(display.display) }, } }; + let is_fullscreen = window_attrs.fullscreen.get_monitor().is_some(); + // finding the mode to switch to if necessary let (mode_to_switch_to, xf86_desk_mode) = unsafe { let mut mode_num: libc::c_int = mem::uninitialized(); @@ -142,7 +145,7 @@ impl Window { (None, None) } else { let xf86_desk_mode: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(0)); - let mode_to_switch_to = if window_attrs.monitor.is_some() { + let mode_to_switch_to = if is_fullscreen { let matching_mode = (0 .. mode_num).map(|i| { let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m }).find(|m| m.hdisplay == dimensions.0 as u16 && m.vdisplay == dimensions.1 as u16); @@ -234,6 +237,10 @@ impl Window { Window::set_netwm(display, window, root, "_NET_WM_STATE_MAXIMIZED_VERT", true); } + if window_attrs.fullscreen == FullScreenState::Windowed { + Window::set_netwm(display, window, root, "_NET_WM_STATE_FULLSCREEN", true); + } + // set visibility if window_attrs.visible { unsafe { @@ -261,8 +268,6 @@ impl Window { } } - let is_fullscreen = window_attrs.monitor.is_some(); - if is_fullscreen { Window::set_netwm(display, window, root, "_NET_WM_STATE_FULLSCREEN", true); diff --git a/src/window.rs b/src/window.rs index c81f58ce..a64a7f6e 100644 --- a/src/window.rs +++ b/src/window.rs @@ -7,6 +7,7 @@ use MouseCursor; use Window; use WindowBuilder; use WindowId; +use FullScreenState; use native_monitor::NativeMonitorId; use libc; @@ -59,10 +60,22 @@ impl WindowBuilder { /// Requests fullscreen mode. /// /// If you don't specify dimensions for the window, it will match the monitor's. + /// Disables fullscreen windowed mode if set. #[inline] pub fn with_fullscreen(mut self, monitor: MonitorId) -> WindowBuilder { let MonitorId(monitor) = monitor; - self.window.monitor = Some(monitor); + self.window.fullscreen = FullScreenState::Exclusive(monitor); + self + } + + /// Requests fullscreen windowed mode. + /// + /// Disables the non-windowed fullscreen mode if set + #[inline] + pub fn with_fullscreen_windowed(mut self, fullscreen: bool) -> WindowBuilder { + if fullscreen { + self.window.fullscreen = FullScreenState::Windowed; + } self } @@ -107,8 +120,10 @@ impl WindowBuilder { /// out of memory, etc. pub fn build(mut self, events_loop: &EventsLoop) -> Result { // resizing the window to the dimensions of the monitor when fullscreen - if self.window.dimensions.is_none() && self.window.monitor.is_some() { - self.window.dimensions = Some(self.window.monitor.as_ref().unwrap().get_dimensions()) + if self.window.dimensions.is_none() { + if let Some(monitor) = self.window.fullscreen.get_monitor() { + self.window.dimensions = Some(monitor.get_dimensions()); + } } // default dimensions @@ -305,6 +320,12 @@ impl Window { self.window.set_maximized(maximized) } + /// Sets the window to fullscreen or back + #[inline] + pub fn set_fullscreen_windowed(&self, fullscreen: bool) { + self.window.set_fullscreen_windowed(fullscreen) + } + #[inline] pub fn id(&self) -> WindowId { WindowId(self.window.id()) @@ -362,7 +383,7 @@ pub fn get_primary_monitor() -> MonitorId { } /// Identifier for a monitor. -#[derive(Clone)] +#[derive(Clone, PartialEq)] pub struct MonitorId(platform::MonitorId); impl MonitorId {