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.
- **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.
- **Breaking:** `Fullscreen` enum now uses `Borderless(Option<MonitorHandle>)` instead of `Borderless(MonitorHandle)` to allow picking the current monitor.
# 0.22.2 (2020-05-16)

View file

@ -19,7 +19,7 @@ fn main() {
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)),
2 => Fullscreen::Borderless(Some(prompt_for_monitor(&event_loop))),
_ => panic!("Please enter a valid number"),
});

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -142,13 +142,14 @@ fn create_window(
unsafe {
let pool = NSAutoreleasePool::new(nil);
let screen = match attrs.fullscreen {
Some(Fullscreen::Borderless(RootMonitorHandle { inner: ref monitor }))
Some(Fullscreen::Borderless(Some(RootMonitorHandle { inner: ref monitor })))
| Some(Fullscreen::Exclusive(RootVideoMode {
video_mode: VideoMode { ref monitor, .. },
})) => {
let monitor_screen = monitor.ns_screen();
Some(monitor_screen.unwrap_or(appkit::NSScreen::mainScreen(nil)))
}
Some(Fullscreen::Borderless(None)) => Some(appkit::NSScreen::mainScreen(nil)),
None => None,
};
let frame = match screen {
@ -755,10 +756,15 @@ impl UnownedWindow {
// does not take a screen parameter, but uses the current screen)
if let Some(ref fullscreen) = 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 {
video_mode: VideoMode { ref monitor, .. },
}) => monitor,
}) => monitor.clone(),
}
.ns_screen()
.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
// on the green fullscreen button. Update state!
None => {
let current_monitor = window.current_monitor_inner();
let current_monitor = Some(window.current_monitor_inner());
shared_state.fullscreen = Some(Fullscreen::Borderless(current_monitor))
}
}

View file

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

View file

@ -853,8 +853,11 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
winuser::MonitorFromRect(&new_rect, winuser::MONITOR_DEFAULTTONULL);
match fullscreen {
Fullscreen::Borderless(ref mut fullscreen_monitor) => {
if new_monitor != fullscreen_monitor.inner.hmonitor()
&& new_monitor != ptr::null_mut()
if 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) {
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.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),
};
});
}
}
Fullscreen::Exclusive(ref video_mode) => {

View file

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

View file

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