-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add exclusive fullscreen mode #925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
985fe0d
3dd7184
bbd88af
cfed2f3
047c017
e293bd7
372056e
0f136ef
ba7a653
f00b10f
471e14b
6007e14
809e4ea
f419c6d
e4ee11c
68b7258
dcfc9f0
5be964e
f3e4624
d1e13ee
890643c
7930620
f956199
8b8a045
b6eb841
9492f65
796cd07
a7db552
81bbd31
de8bfdc
b597634
cd61cc0
28f7315
d739fb9
3737228
f17b74c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,56 +1,35 @@ | ||
| use std::io::{self, Write}; | ||
| use winit::{ | ||
| event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}, | ||
| event_loop::{ControlFlow, EventLoop}, | ||
| monitor::MonitorHandle, | ||
| window::WindowBuilder, | ||
| }; | ||
| use std::io::{stdin, stdout, Write}; | ||
| use winit::event::{ElementState, Event, KeyboardInput, VirtualKeyCode, WindowEvent}; | ||
| use winit::event_loop::{ControlFlow, EventLoop}; | ||
| use winit::monitor::{MonitorHandle, VideoMode}; | ||
| use winit::window::{Fullscreen, WindowBuilder}; | ||
|
|
||
| fn main() { | ||
| let event_loop = EventLoop::new(); | ||
|
|
||
| #[cfg(target_os = "macos")] | ||
| let mut macos_use_simple_fullscreen = false; | ||
|
|
||
| let monitor = { | ||
| // On macOS there are two fullscreen modes "native" and "simple" | ||
| #[cfg(target_os = "macos")] | ||
| { | ||
| print!("Please choose the fullscreen mode: (1) native, (2) simple: "); | ||
| io::stdout().flush().unwrap(); | ||
|
|
||
| let mut num = String::new(); | ||
| io::stdin().read_line(&mut num).unwrap(); | ||
| let num = num.trim().parse().ok().expect("Please enter a number"); | ||
| match num { | ||
| 2 => macos_use_simple_fullscreen = true, | ||
| _ => {} | ||
| } | ||
|
|
||
| // Prompt for monitor when using native fullscreen | ||
| if !macos_use_simple_fullscreen { | ||
| Some(prompt_for_monitor(&event_loop)) | ||
| } else { | ||
| None | ||
| } | ||
| } | ||
| print!("Please choose the fullscreen mode: (1) exclusive, (2) borderless: "); | ||
| stdout().flush().unwrap(); | ||
|
|
||
| #[cfg(not(target_os = "macos"))] | ||
| Some(prompt_for_monitor(&event_loop)) | ||
| }; | ||
| let mut num = String::new(); | ||
| stdin().read_line(&mut num).unwrap(); | ||
| let num = num.trim().parse().ok().expect("Please enter a number"); | ||
|
|
||
| let fullscreen = Some(match num { | ||
| 1 => Fullscreen::Exclusive(prompt_for_video_mode(&prompt_for_monitor(&event_loop))), | ||
| 2 => Fullscreen::Borderless(prompt_for_monitor(&event_loop)), | ||
| _ => panic!("Please enter a valid number"), | ||
| }); | ||
|
|
||
| let mut is_fullscreen = monitor.is_some(); | ||
| let mut is_maximized = false; | ||
| let mut decorations = true; | ||
|
|
||
| let window = WindowBuilder::new() | ||
| .with_title("Hello world!") | ||
| .with_fullscreen(monitor) | ||
| .with_fullscreen(fullscreen.clone()) | ||
| .build(&event_loop) | ||
| .unwrap(); | ||
|
|
||
| event_loop.run(move |event, _, control_flow| { | ||
| println!("{:?}", event); | ||
| *control_flow = ControlFlow::Wait; | ||
|
|
||
| match event { | ||
|
|
@@ -67,35 +46,14 @@ fn main() { | |
| } => match (virtual_code, state) { | ||
| (VirtualKeyCode::Escape, _) => *control_flow = ControlFlow::Exit, | ||
| (VirtualKeyCode::F, ElementState::Pressed) => { | ||
| #[cfg(target_os = "macos")] | ||
| { | ||
| if macos_use_simple_fullscreen { | ||
| use winit::platform::macos::WindowExtMacOS; | ||
| if WindowExtMacOS::set_simple_fullscreen(&window, !is_fullscreen) { | ||
| is_fullscreen = !is_fullscreen; | ||
| } | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| is_fullscreen = !is_fullscreen; | ||
| if !is_fullscreen { | ||
| if window.fullscreen().is_some() { | ||
|
goddessfreya marked this conversation as resolved.
|
||
| window.set_fullscreen(None); | ||
| } else { | ||
| window.set_fullscreen(Some(window.current_monitor())); | ||
| window.set_fullscreen(fullscreen.clone()); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to be using
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we want to use the current monitor here, I think we ought to re-query the video mode from the user as well. I would prefer for this to use whatever values were input by the user on start up, so that we don't have to worry about the monitor changing here. |
||
| } | ||
| } | ||
| (VirtualKeyCode::S, ElementState::Pressed) => { | ||
| println!("window.fullscreen {:?}", window.fullscreen()); | ||
|
|
||
| #[cfg(target_os = "macos")] | ||
| { | ||
| use winit::platform::macos::WindowExtMacOS; | ||
| println!( | ||
| "window.simple_fullscreen {:?}", | ||
| WindowExtMacOS::simple_fullscreen(&window) | ||
| ); | ||
| } | ||
| } | ||
| (VirtualKeyCode::M, ElementState::Pressed) => { | ||
| is_maximized = !is_maximized; | ||
|
|
@@ -121,10 +79,10 @@ fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle { | |
| } | ||
|
|
||
| print!("Please write the number of the monitor to use: "); | ||
| io::stdout().flush().unwrap(); | ||
| stdout().flush().unwrap(); | ||
|
|
||
| let mut num = String::new(); | ||
| io::stdin().read_line(&mut num).unwrap(); | ||
| stdin().read_line(&mut num).unwrap(); | ||
| let num = num.trim().parse().ok().expect("Please enter a number"); | ||
| let monitor = event_loop | ||
| .available_monitors() | ||
|
|
@@ -135,3 +93,24 @@ fn prompt_for_monitor(event_loop: &EventLoop<()>) -> MonitorHandle { | |
|
|
||
| monitor | ||
| } | ||
|
|
||
| fn prompt_for_video_mode(monitor: &MonitorHandle) -> VideoMode { | ||
| for (i, video_mode) in monitor.video_modes().enumerate() { | ||
| println!("Video mode #{}: {}", i, video_mode); | ||
| } | ||
|
|
||
| print!("Please write the number of the video mode to use: "); | ||
| stdout().flush().unwrap(); | ||
|
|
||
| let mut num = String::new(); | ||
| stdin().read_line(&mut num).unwrap(); | ||
| let num = num.trim().parse().ok().expect("Please enter a number"); | ||
| let video_mode = monitor | ||
| .video_modes() | ||
| .nth(num) | ||
| .expect("Please enter a valid ID"); | ||
|
|
||
| println!("Using {}", video_mode); | ||
|
|
||
| video_mode | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,17 +52,41 @@ impl Iterator for AvailableMonitorsIter { | |
| /// - [`MonitorHandle::video_modes`][monitor_get]. | ||
| /// | ||
| /// [monitor_get]: ../monitor/struct.MonitorHandle.html#method.video_modes | ||
| #[derive(Debug, Clone, Eq, PartialEq, Hash)] | ||
| #[derive(Derivative)] | ||
| #[derivative(Clone, Debug = "transparent", PartialEq, Eq, Hash)] | ||
| pub struct VideoMode { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I realize this specific feedback would've been better-placed in the original PR, but it's only occurred to me now: is it possible to add a function to
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't be a problem, but I'm inclined to do this in a separate pull request since I will have to implement it for all four platforms. I think the borderless mode would suffice for a sensible default in any case. |
||
| pub(crate) size: (u32, u32), | ||
| pub(crate) bit_depth: u16, | ||
| pub(crate) refresh_rate: u16, | ||
| pub(crate) video_mode: platform_impl::VideoMode, | ||
| } | ||
|
|
||
| impl PartialOrd for VideoMode { | ||
| fn partial_cmp(&self, other: &VideoMode) -> Option<std::cmp::Ordering> { | ||
| Some(self.cmp(other)) | ||
| } | ||
| } | ||
|
|
||
| impl Ord for VideoMode { | ||
| fn cmp(&self, other: &VideoMode) -> std::cmp::Ordering { | ||
| // TODO: we can impl `Ord` for `PhysicalSize` once we switch from `f32` | ||
| // to `u32` there | ||
| let size: (u32, u32) = self.size().into(); | ||
|
goddessfreya marked this conversation as resolved.
|
||
| let other_size: (u32, u32) = other.size().into(); | ||
| self.monitor().cmp(&other.monitor()).then( | ||
| size.cmp(&other_size) | ||
| .then( | ||
| self.refresh_rate() | ||
| .cmp(&other.refresh_rate()) | ||
| .then(self.bit_depth().cmp(&other.bit_depth())), | ||
| ) | ||
| .reverse(), | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| impl VideoMode { | ||
| /// Returns the resolution of this video mode. | ||
| #[inline] | ||
| pub fn size(&self) -> PhysicalSize { | ||
| self.size.into() | ||
| self.video_mode.size() | ||
| } | ||
|
|
||
| /// Returns the bit depth of this video mode, as in how many bits you have | ||
|
|
@@ -73,15 +97,37 @@ impl VideoMode { | |
| /// | ||
| /// - **Wayland:** Always returns 32. | ||
| /// - **iOS:** Always returns 32. | ||
| #[inline] | ||
| pub fn bit_depth(&self) -> u16 { | ||
| self.bit_depth | ||
| self.video_mode.bit_depth() | ||
| } | ||
|
|
||
| /// Returns the refresh rate of this video mode. **Note**: the returned | ||
| /// refresh rate is an integer approximation, and you shouldn't rely on this | ||
| /// value to be exact. | ||
| #[inline] | ||
| pub fn refresh_rate(&self) -> u16 { | ||
| self.refresh_rate | ||
| self.video_mode.refresh_rate() | ||
| } | ||
|
|
||
| /// Returns the monitor that this video mode is valid for. Each monitor has | ||
| /// a separate set of valid video modes. | ||
| #[inline] | ||
| pub fn monitor(&self) -> MonitorHandle { | ||
| self.video_mode.monitor() | ||
| } | ||
| } | ||
|
|
||
| impl std::fmt::Display for VideoMode { | ||
| fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
| write!( | ||
| f, | ||
| "{}x{} @ {} Hz ({} bpp)", | ||
| self.size().width, | ||
| self.size().height, | ||
| self.refresh_rate(), | ||
| self.bit_depth() | ||
| ) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -90,7 +136,7 @@ impl VideoMode { | |
| /// Allows you to retrieve information about a given monitor and can be used in [`Window`] creation. | ||
| /// | ||
| /// [`Window`]: ../window/struct.Window.html | ||
| #[derive(Debug, Clone)] | ||
| #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] | ||
| pub struct MonitorHandle { | ||
| pub(crate) inner: platform_impl::MonitorHandle, | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.