mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 14:51:30 +11:00
Implement Windowed Fullscreen
There are two kinds of fullscreen. One where you take over the whole output the other where you just set the window size to the screen size and get rid of decorations. The first one already existed, implement the second which is more common for normal desktop apps. Use an enum to consolidate all the fullscreen states.
This commit is contained in:
parent
a4052b8693
commit
1d97a2a506
24
src/lib.rs
24
src/lib.rs
|
@ -356,6 +356,24 @@ pub enum MouseCursor {
|
||||||
RowResize,
|
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<platform::MonitorId> {
|
||||||
|
if let FullScreenState::Exclusive(ref monitor) = *self {
|
||||||
|
Some(monitor.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Describes how winit handles the cursor.
|
/// Describes how winit handles the cursor.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub enum CursorState {
|
pub enum CursorState {
|
||||||
|
@ -392,10 +410,10 @@ pub struct WindowAttributes {
|
||||||
/// The default is `None`.
|
/// The default is `None`.
|
||||||
pub max_dimensions: Option<(u32, u32)>,
|
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`.
|
/// The default is `None`.
|
||||||
pub monitor: Option<platform::MonitorId>,
|
pub fullscreen: FullScreenState,
|
||||||
|
|
||||||
/// The title of the window in the title bar.
|
/// The title of the window in the title bar.
|
||||||
///
|
///
|
||||||
|
@ -435,9 +453,9 @@ impl Default for WindowAttributes {
|
||||||
dimensions: None,
|
dimensions: None,
|
||||||
min_dimensions: None,
|
min_dimensions: None,
|
||||||
max_dimensions: None,
|
max_dimensions: None,
|
||||||
monitor: None,
|
|
||||||
title: "winit window".to_owned(),
|
title: "winit window".to_owned(),
|
||||||
maximized: false,
|
maximized: false,
|
||||||
|
fullscreen: FullScreenState::None,
|
||||||
visible: true,
|
visible: true,
|
||||||
transparent: false,
|
transparent: false,
|
||||||
decorations: true,
|
decorations: true,
|
||||||
|
|
|
@ -260,6 +260,10 @@ impl Window {
|
||||||
pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
|
pub fn set_cursor_position(&self, x: i32, y: i32) -> Result<(), ()> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_fullscreen_windowed(&self, fullscreen: bool) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Window {}
|
unsafe impl Send for Window {}
|
||||||
|
|
|
@ -97,7 +97,7 @@ pub enum DeviceId {
|
||||||
Wayland(wayland::DeviceId)
|
Wayland(wayland::DeviceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub enum MonitorId {
|
pub enum MonitorId {
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
X(x11::MonitorId),
|
X(x11::MonitorId),
|
||||||
|
@ -317,6 +317,14 @@ impl Window2 {
|
||||||
&Window2::Wayland(ref _w) => {},
|
&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)
|
unsafe extern "C" fn x_error_callback(dpy: *mut x11::ffi::Display, event: *mut x11::ffi::XErrorEvent)
|
||||||
|
|
|
@ -359,6 +359,12 @@ pub struct MonitorId {
|
||||||
ctxt: Arc<WaylandContext>
|
ctxt: Arc<WaylandContext>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for MonitorId {
|
||||||
|
fn eq(&self, other: &MonitorId) -> bool {
|
||||||
|
self.id == other.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MonitorId {
|
impl MonitorId {
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn get_name(&self) -> Option<String> {
|
||||||
let mut guard = self.ctxt.evq.lock().unwrap();
|
let mut guard = self.ctxt.evq.lock().unwrap();
|
||||||
|
|
|
@ -54,7 +54,7 @@ impl Window {
|
||||||
*(decorated.handler()) = Some(DecoratedHandler::new());
|
*(decorated.handler()) = Some(DecoratedHandler::new());
|
||||||
|
|
||||||
// set fullscreen if necessary
|
// 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| {
|
ctxt.with_output(monitor_id.clone(), |output| {
|
||||||
decorated.set_fullscreen(Some(output))
|
decorated.set_fullscreen(Some(output))
|
||||||
});
|
});
|
||||||
|
|
|
@ -6,6 +6,11 @@ use native_monitor::NativeMonitorId;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct MonitorId(pub Arc<XConnection>, pub u32);
|
pub struct MonitorId(pub Arc<XConnection>, pub u32);
|
||||||
|
impl PartialEq for MonitorId {
|
||||||
|
fn eq(&self, other: &MonitorId) -> bool {
|
||||||
|
self.1 == other.1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_available_monitors(x: &Arc<XConnection>) -> VecDeque<MonitorId> {
|
pub fn get_available_monitors(x: &Arc<XConnection>) -> VecDeque<MonitorId> {
|
||||||
let nb_monitors = unsafe { (x.xlib.XScreenCount)(x.display) };
|
let nb_monitors = unsafe { (x.xlib.XScreenCount)(x.display) };
|
||||||
|
|
|
@ -11,6 +11,7 @@ use std::time::Duration;
|
||||||
|
|
||||||
use CursorState;
|
use CursorState;
|
||||||
use WindowAttributes;
|
use WindowAttributes;
|
||||||
|
use FullScreenState;
|
||||||
use platform::PlatformSpecificWindowBuilderAttributes;
|
use platform::PlatformSpecificWindowBuilderAttributes;
|
||||||
|
|
||||||
use platform::MonitorId as PlatformMonitorId;
|
use platform::MonitorId as PlatformMonitorId;
|
||||||
|
@ -128,12 +129,14 @@ impl Window {
|
||||||
|
|
||||||
let screen_id = match pl_attribs.screen_id {
|
let screen_id = match pl_attribs.screen_id {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
None => match window_attrs.monitor {
|
None => match window_attrs.fullscreen {
|
||||||
Some(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32,
|
FullScreenState::Exclusive(PlatformMonitorId::X(MonitorId(_, monitor))) => monitor as i32,
|
||||||
_ => unsafe { (display.xlib.XDefaultScreen)(display.display) },
|
_ => unsafe { (display.xlib.XDefaultScreen)(display.display) },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let is_fullscreen = window_attrs.fullscreen.get_monitor().is_some();
|
||||||
|
|
||||||
// finding the mode to switch to if necessary
|
// finding the mode to switch to if necessary
|
||||||
let (mode_to_switch_to, xf86_desk_mode) = unsafe {
|
let (mode_to_switch_to, xf86_desk_mode) = unsafe {
|
||||||
let mut mode_num: libc::c_int = mem::uninitialized();
|
let mut mode_num: libc::c_int = mem::uninitialized();
|
||||||
|
@ -142,7 +145,7 @@ impl Window {
|
||||||
(None, None)
|
(None, None)
|
||||||
} else {
|
} else {
|
||||||
let xf86_desk_mode: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(0));
|
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 matching_mode = (0 .. mode_num).map(|i| {
|
||||||
let m: ffi::XF86VidModeModeInfo = ptr::read(*modes.offset(i as isize) as *const _); m
|
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);
|
}).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);
|
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
|
// set visibility
|
||||||
if window_attrs.visible {
|
if window_attrs.visible {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
@ -261,8 +268,6 @@ impl Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_fullscreen = window_attrs.monitor.is_some();
|
|
||||||
|
|
||||||
if is_fullscreen {
|
if is_fullscreen {
|
||||||
Window::set_netwm(display, window, root, "_NET_WM_STATE_FULLSCREEN", true);
|
Window::set_netwm(display, window, root, "_NET_WM_STATE_FULLSCREEN", true);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ use MouseCursor;
|
||||||
use Window;
|
use Window;
|
||||||
use WindowBuilder;
|
use WindowBuilder;
|
||||||
use WindowId;
|
use WindowId;
|
||||||
|
use FullScreenState;
|
||||||
use native_monitor::NativeMonitorId;
|
use native_monitor::NativeMonitorId;
|
||||||
|
|
||||||
use libc;
|
use libc;
|
||||||
|
@ -59,10 +60,22 @@ impl WindowBuilder {
|
||||||
/// Requests fullscreen mode.
|
/// Requests fullscreen mode.
|
||||||
///
|
///
|
||||||
/// If you don't specify dimensions for the window, it will match the monitor's.
|
/// If you don't specify dimensions for the window, it will match the monitor's.
|
||||||
|
/// Disables fullscreen windowed mode if set.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_fullscreen(mut self, monitor: MonitorId) -> WindowBuilder {
|
pub fn with_fullscreen(mut self, monitor: MonitorId) -> WindowBuilder {
|
||||||
let MonitorId(monitor) = monitor;
|
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
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,8 +120,10 @@ impl WindowBuilder {
|
||||||
/// out of memory, etc.
|
/// out of memory, etc.
|
||||||
pub fn build(mut self, events_loop: &EventsLoop) -> Result<Window, CreationError> {
|
pub fn build(mut self, events_loop: &EventsLoop) -> Result<Window, CreationError> {
|
||||||
// resizing the window to the dimensions of the monitor when fullscreen
|
// resizing the window to the dimensions of the monitor when fullscreen
|
||||||
if self.window.dimensions.is_none() && self.window.monitor.is_some() {
|
if self.window.dimensions.is_none() {
|
||||||
self.window.dimensions = Some(self.window.monitor.as_ref().unwrap().get_dimensions())
|
if let Some(monitor) = self.window.fullscreen.get_monitor() {
|
||||||
|
self.window.dimensions = Some(monitor.get_dimensions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// default dimensions
|
// default dimensions
|
||||||
|
@ -305,6 +320,12 @@ impl Window {
|
||||||
self.window.set_maximized(maximized)
|
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]
|
#[inline]
|
||||||
pub fn id(&self) -> WindowId {
|
pub fn id(&self) -> WindowId {
|
||||||
WindowId(self.window.id())
|
WindowId(self.window.id())
|
||||||
|
@ -362,7 +383,7 @@ pub fn get_primary_monitor() -> MonitorId {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Identifier for a monitor.
|
/// Identifier for a monitor.
|
||||||
#[derive(Clone)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct MonitorId(platform::MonitorId);
|
pub struct MonitorId(platform::MonitorId);
|
||||||
|
|
||||||
impl MonitorId {
|
impl MonitorId {
|
||||||
|
|
Loading…
Reference in a new issue