Rework 'Fullscreen::Borderless' enum variant

This changes 'Fullscreen::Borderless' enum variant from
'Fullscreen::Borderless(MonitorHandle)' to
'Fullscreen::Borderless(Option<MonitorHandle>)'. Providing
'None' to it will result in picking the current monitor.
This commit is contained in:
Kirill Chibisov 2020-09-22 04:54:47 +03:00 committed by GitHub
parent 644dc13e00
commit 71e3d25422
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 89 additions and 46 deletions

View file

@ -41,6 +41,7 @@
- On Web, the event handler closure passed to `EventLoop::run` now gets dropped after the event loop is destroyed. - On Web, the event handler closure passed to `EventLoop::run` now gets dropped after the event loop is destroyed.
- **Breaking:** On Web, the canvas element associated to a `Window` is no longer removed from the DOM when the `Window` is dropped. - **Breaking:** On Web, the canvas element associated to a `Window` is no longer removed from the DOM when the `Window` is dropped.
- On Web, `WindowEvent::Resized` is now emitted when `Window::set_inner_size` is called. - On Web, `WindowEvent::Resized` is now emitted when `Window::set_inner_size` is called.
- **Breaking:** `Fullscreen` enum now uses `Borderless(Option<MonitorHandle>)` instead of `Borderless(MonitorHandle)` to allow picking the current monitor.
# 0.22.2 (2020-05-16) # 0.22.2 (2020-05-16)

View file

@ -19,7 +19,7 @@ fn main() {
let fullscreen = Some(match num { let fullscreen = Some(match num {
1 => Fullscreen::Exclusive(prompt_for_video_mode(&prompt_for_monitor(&event_loop))), 1 => Fullscreen::Exclusive(prompt_for_video_mode(&prompt_for_monitor(&event_loop))),
2 => Fullscreen::Borderless(prompt_for_monitor(&event_loop)), 2 => Fullscreen::Borderless(Some(prompt_for_monitor(&event_loop))),
_ => panic!("Please enter a valid number"), _ => panic!("Please enter a valid number"),
}); });

View file

@ -83,9 +83,7 @@ fn main() {
); );
} }
F => window.set_fullscreen(match (state, modifiers.alt()) { F => window.set_fullscreen(match (state, modifiers.alt()) {
(true, false) => { (true, false) => Some(Fullscreen::Borderless(None)),
Some(Fullscreen::Borderless(window.current_monitor().unwrap()))
}
(true, true) => Some(Fullscreen::Exclusive( (true, true) => Some(Fullscreen::Exclusive(
video_modes.iter().nth(video_mode_id).unwrap().clone(), video_modes.iter().nth(video_mode_id).unwrap().clone(),
)), )),

View file

@ -21,6 +21,7 @@ fn main() {
eprintln!("debugging keys:"); eprintln!("debugging keys:");
eprintln!(" (E) Enter exclusive fullscreen"); eprintln!(" (E) Enter exclusive fullscreen");
eprintln!(" (F) Toggle borderless fullscreen"); eprintln!(" (F) Toggle borderless fullscreen");
eprintln!(" (P) Toggle borderless fullscreen on system's preffered monitor");
eprintln!(" (M) Toggle minimized"); eprintln!(" (M) Toggle minimized");
eprintln!(" (Q) Quit event loop"); eprintln!(" (Q) Quit event loop");
eprintln!(" (V) Toggle visibility"); eprintln!(" (V) Toggle visibility");
@ -85,10 +86,17 @@ fn main() {
if window.fullscreen().is_some() { if window.fullscreen().is_some() {
window.set_fullscreen(None); window.set_fullscreen(None);
} else { } else {
let monitor = window.current_monitor().unwrap(); let monitor = window.current_monitor();
window.set_fullscreen(Some(Fullscreen::Borderless(monitor))); window.set_fullscreen(Some(Fullscreen::Borderless(monitor)));
} }
} }
VirtualKeyCode::P => {
if window.fullscreen().is_some() {
window.set_fullscreen(None);
} else {
window.set_fullscreen(Some(Fullscreen::Borderless(None)));
}
}
VirtualKeyCode::M => { VirtualKeyCode::M => {
minimized = !minimized; minimized = !minimized;
window.set_minimized(minimized); window.set_minimized(minimized);

View file

@ -519,7 +519,15 @@ pub unsafe fn create_window(
msg_send![window, setScreen:video_mode.monitor().ui_screen()] msg_send![window, setScreen:video_mode.monitor().ui_screen()]
} }
Some(Fullscreen::Borderless(ref monitor)) => { Some(Fullscreen::Borderless(ref monitor)) => {
msg_send![window, setScreen:monitor.ui_screen()] let uiscreen: id = match &monitor {
Some(monitor) => monitor.ui_screen() as id,
None => {
let uiscreen: id = msg_send![window, screen];
uiscreen
}
};
msg_send![window, setScreen: uiscreen]
} }
None => (), None => (),
} }

View file

@ -196,7 +196,9 @@ impl Inner {
let () = msg_send![uiscreen, setCurrentMode: video_mode.video_mode.screen_mode]; let () = msg_send![uiscreen, setCurrentMode: video_mode.video_mode.screen_mode];
uiscreen uiscreen
} }
Some(Fullscreen::Borderless(monitor)) => monitor.ui_screen() as id, Some(Fullscreen::Borderless(monitor)) => monitor
.unwrap_or_else(|| self.current_monitor_inner())
.ui_screen() as id,
None => { None => {
warn!("`Window::set_fullscreen(None)` ignored on iOS"); warn!("`Window::set_fullscreen(None)` ignored on iOS");
return; return;
@ -235,7 +237,7 @@ impl Inner {
&& screen_space_bounds.size.width == screen_bounds.size.width && screen_space_bounds.size.width == screen_bounds.size.width
&& screen_space_bounds.size.height == screen_bounds.size.height && screen_space_bounds.size.height == screen_bounds.size.height
{ {
Some(Fullscreen::Borderless(monitor)) Some(Fullscreen::Borderless(Some(monitor)))
} else { } else {
None None
} }
@ -353,8 +355,10 @@ impl Window {
Some(Fullscreen::Exclusive(ref video_mode)) => { Some(Fullscreen::Exclusive(ref video_mode)) => {
video_mode.video_mode.monitor.ui_screen() as id video_mode.video_mode.monitor.ui_screen() as id
} }
Some(Fullscreen::Borderless(ref monitor)) => monitor.ui_screen() as id, Some(Fullscreen::Borderless(Some(ref monitor))) => monitor.inner.ui_screen(),
None => monitor::main_uiscreen().ui_screen(), Some(Fullscreen::Borderless(None)) | None => {
monitor::main_uiscreen().ui_screen() as id
}
}; };
let screen_bounds: CGRect = msg_send![screen, bounds]; let screen_bounds: CGRect = msg_send![screen, bounds];

View file

@ -154,11 +154,16 @@ impl Window {
Some(Fullscreen::Exclusive(_)) => { Some(Fullscreen::Exclusive(_)) => {
panic!("Wayland doesn't support exclusive fullscreen") panic!("Wayland doesn't support exclusive fullscreen")
} }
Some(Fullscreen::Borderless(RootMonitorHandle { Some(Fullscreen::Borderless(monitor)) => {
inner: PlatformMonitorHandle::Wayland(ref monitor_id), let monitor =
})) => frame.set_fullscreen(Some(&monitor_id.proxy)), monitor.and_then(|RootMonitorHandle { inner: monitor }| match monitor {
PlatformMonitorHandle::Wayland(monitor) => Some(monitor.proxy),
#[cfg(feature = "x11")] #[cfg(feature = "x11")]
Some(Fullscreen::Borderless(_)) => unreachable!(), PlatformMonitorHandle::X(_) => None,
});
frame.set_fullscreen(monitor.as_ref())
}
None => { None => {
if attributes.maximized { if attributes.maximized {
frame.set_maximized(); frame.set_maximized();
@ -333,11 +338,13 @@ impl Window {
pub fn fullscreen(&self) -> Option<Fullscreen> { pub fn fullscreen(&self) -> Option<Fullscreen> {
if *(self.fullscreen.lock().unwrap()) { if *(self.fullscreen.lock().unwrap()) {
// If the monitor cannot be determined, we cannot report any fullscreen mode. let current_monitor = self
let current_monitor = self.current_monitor()?; .current_monitor()
Some(Fullscreen::Borderless(RootMonitorHandle { .map(|current_monitor| RootMonitorHandle {
inner: PlatformMonitorHandle::Wayland(current_monitor), inner: PlatformMonitorHandle::Wayland(current_monitor),
})) });
Some(Fullscreen::Borderless(current_monitor))
} else { } else {
None None
} }
@ -348,16 +355,16 @@ impl Window {
Some(Fullscreen::Exclusive(_)) => { Some(Fullscreen::Exclusive(_)) => {
panic!("Wayland doesn't support exclusive fullscreen") panic!("Wayland doesn't support exclusive fullscreen")
} }
Some(Fullscreen::Borderless(RootMonitorHandle { Some(Fullscreen::Borderless(monitor)) => {
inner: PlatformMonitorHandle::Wayland(ref monitor_id), let monitor =
})) => { monitor.and_then(|RootMonitorHandle { inner: monitor }| match monitor {
self.frame PlatformMonitorHandle::Wayland(monitor) => Some(monitor.proxy),
.lock()
.unwrap()
.set_fullscreen(Some(&monitor_id.proxy));
}
#[cfg(feature = "x11")] #[cfg(feature = "x11")]
Some(Fullscreen::Borderless(_)) => unreachable!(), PlatformMonitorHandle::X(_) => None,
});
self.frame.lock().unwrap().set_fullscreen(monitor.as_ref());
}
None => self.frame.lock().unwrap().unset_fullscreen(), None => self.frame.lock().unwrap().unset_fullscreen(),
} }
} }

View file

@ -649,10 +649,11 @@ impl UnownedWindow {
let (video_mode, monitor) = match fullscreen { let (video_mode, monitor) = match fullscreen {
Fullscreen::Exclusive(RootVideoMode { Fullscreen::Exclusive(RootVideoMode {
video_mode: PlatformVideoMode::X(ref video_mode), video_mode: PlatformVideoMode::X(ref video_mode),
}) => (Some(video_mode), video_mode.monitor.as_ref().unwrap()), }) => (Some(video_mode), video_mode.monitor.clone().unwrap()),
Fullscreen::Borderless(RootMonitorHandle { Fullscreen::Borderless(Some(RootMonitorHandle {
inner: PlatformMonitorHandle::X(ref monitor), inner: PlatformMonitorHandle::X(monitor),
}) => (None, monitor), })) => (None, monitor),
Fullscreen::Borderless(None) => (None, self.current_monitor()),
#[cfg(feature = "wayland")] #[cfg(feature = "wayland")]
_ => unreachable!(), _ => unreachable!(),
}; };

View file

@ -142,13 +142,14 @@ fn create_window(
unsafe { unsafe {
let pool = NSAutoreleasePool::new(nil); let pool = NSAutoreleasePool::new(nil);
let screen = match attrs.fullscreen { let screen = match attrs.fullscreen {
Some(Fullscreen::Borderless(RootMonitorHandle { inner: ref monitor })) Some(Fullscreen::Borderless(Some(RootMonitorHandle { inner: ref monitor })))
| Some(Fullscreen::Exclusive(RootVideoMode { | Some(Fullscreen::Exclusive(RootVideoMode {
video_mode: VideoMode { ref monitor, .. }, video_mode: VideoMode { ref monitor, .. },
})) => { })) => {
let monitor_screen = monitor.ns_screen(); let monitor_screen = monitor.ns_screen();
Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil))) Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil)))
} }
Some(Fullscreen::Borderless(None)) => Some(appkit::NSScreen::mainScreen(nil)),
None => None, None => None,
}; };
let frame = match screen { let frame = match screen {
@ -755,10 +756,15 @@ impl UnownedWindow {
// does not take a screen parameter, but uses the current screen) // does not take a screen parameter, but uses the current screen)
if let Some(ref fullscreen) = fullscreen { if let Some(ref fullscreen) = fullscreen {
let new_screen = match fullscreen { let new_screen = match fullscreen {
Fullscreen::Borderless(RootMonitorHandle { inner: ref monitor }) => monitor, Fullscreen::Borderless(borderless) => {
let RootMonitorHandle { inner: monitor } = borderless
.clone()
.unwrap_or_else(|| self.current_monitor_inner());
monitor
}
Fullscreen::Exclusive(RootVideoMode { Fullscreen::Exclusive(RootVideoMode {
video_mode: VideoMode { ref monitor, .. }, video_mode: VideoMode { ref monitor, .. },
}) => monitor, }) => monitor.clone(),
} }
.ns_screen() .ns_screen()
.unwrap(); .unwrap();

View file

@ -450,7 +450,7 @@ extern "C" fn window_will_enter_fullscreen(this: &Object, _: Sel, _: id) {
// Otherwise, we must've reached fullscreen by the user clicking // Otherwise, we must've reached fullscreen by the user clicking
// on the green fullscreen button. Update state! // on the green fullscreen button. Update state!
None => { None => {
let current_monitor = window.current_monitor_inner(); let current_monitor = Some(window.current_monitor_inner());
shared_state.fullscreen = Some(Fullscreen::Borderless(current_monitor)) shared_state.fullscreen = Some(Fullscreen::Borderless(current_monitor))
} }
} }

View file

@ -233,7 +233,7 @@ impl Window {
#[inline] #[inline]
pub fn fullscreen(&self) -> Option<Fullscreen> { pub fn fullscreen(&self) -> Option<Fullscreen> {
if self.canvas.borrow().is_fullscreen() { if self.canvas.borrow().is_fullscreen() {
Some(Fullscreen::Borderless(self.current_monitor_inner())) Some(Fullscreen::Borderless(Some(self.current_monitor_inner())))
} else { } else {
None None
} }

View file

@ -853,8 +853,11 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
winuser::MonitorFromRect(&new_rect, winuser::MONITOR_DEFAULTTONULL); winuser::MonitorFromRect(&new_rect, winuser::MONITOR_DEFAULTTONULL);
match fullscreen { match fullscreen {
Fullscreen::Borderless(ref mut fullscreen_monitor) => { Fullscreen::Borderless(ref mut fullscreen_monitor) => {
if new_monitor != fullscreen_monitor.inner.hmonitor() if new_monitor != ptr::null_mut()
&& new_monitor != ptr::null_mut() && fullscreen_monitor
.as_ref()
.map(|monitor| new_monitor != monitor.inner.hmonitor())
.unwrap_or(true)
{ {
if let Ok(new_monitor_info) = monitor::get_monitor_info(new_monitor) { if let Ok(new_monitor_info) = monitor::get_monitor_info(new_monitor) {
let new_monitor_rect = new_monitor_info.rcMonitor; let new_monitor_rect = new_monitor_info.rcMonitor;
@ -863,9 +866,9 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
window_pos.cx = new_monitor_rect.right - new_monitor_rect.left; window_pos.cx = new_monitor_rect.right - new_monitor_rect.left;
window_pos.cy = new_monitor_rect.bottom - new_monitor_rect.top; window_pos.cy = new_monitor_rect.bottom - new_monitor_rect.top;
} }
*fullscreen_monitor = crate::monitor::MonitorHandle { *fullscreen_monitor = Some(crate::monitor::MonitorHandle {
inner: MonitorHandle::new(new_monitor), inner: MonitorHandle::new(new_monitor),
}; });
} }
} }
Fullscreen::Exclusive(ref video_mode) => { Fullscreen::Exclusive(ref video_mode) => {

View file

@ -496,9 +496,12 @@ impl Window {
// Update window bounds // Update window bounds
match &fullscreen { match &fullscreen {
Some(fullscreen) => { Some(fullscreen) => {
let monitor = match fullscreen { let monitor = match &fullscreen {
Fullscreen::Exclusive(ref video_mode) => video_mode.monitor(), Fullscreen::Exclusive(video_mode) => video_mode.monitor(),
Fullscreen::Borderless(ref monitor) => monitor.clone(), Fullscreen::Borderless(Some(monitor)) => monitor.clone(),
Fullscreen::Borderless(None) => RootMonitorHandle {
inner: monitor::current_monitor(window.0),
},
}; };
let position: (i32, i32) = monitor.position().into(); let position: (i32, i32) = monitor.position().into();

View file

@ -628,6 +628,7 @@ impl Window {
/// ///
/// - **iOS:** Can only be called on the main thread. /// - **iOS:** Can only be called on the main thread.
/// - **Android:** Will always return `None`. /// - **Android:** Will always return `None`.
/// - **Wayland:** Can return `Borderless(None)` when there are no monitors.
#[inline] #[inline]
pub fn fullscreen(&self) -> Option<Fullscreen> { pub fn fullscreen(&self) -> Option<Fullscreen> {
self.window.fullscreen() self.window.fullscreen()
@ -850,10 +851,13 @@ impl Default for CursorIcon {
} }
} }
/// Fullscreen modes.
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]
pub enum Fullscreen { pub enum Fullscreen {
Exclusive(VideoMode), Exclusive(VideoMode),
Borderless(MonitorHandle),
/// Providing `None` to `Borderless` will fullscreen on the current monitor.
Borderless(Option<MonitorHandle>),
} }
#[derive(Clone, Debug, PartialEq)] #[derive(Clone, Debug, PartialEq)]