api: make VideoModeHandle into VideoMode
The video mode is generally a static data and not a reference to some video mode. This changes the exclusive fullscreen API to match that an accept a monitor now.
This commit is contained in:
parent
5462f27dda
commit
ee245c569d
28 changed files with 247 additions and 475 deletions
|
|
@ -1,12 +1,12 @@
|
|||
use std::num::{NonZeroU16, NonZeroU32};
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
use x11rb::connection::RequestConnection;
|
||||
use x11rb::protocol::randr::{self, ConnectionExt as _};
|
||||
use x11rb::protocol::xproto;
|
||||
|
||||
use super::{util, X11Error, XConnection};
|
||||
use crate::dpi::{PhysicalPosition, PhysicalSize};
|
||||
use crate::platform_impl::VideoModeHandle as PlatformVideoModeHandle;
|
||||
use crate::dpi::PhysicalPosition;
|
||||
use crate::monitor::VideoMode;
|
||||
|
||||
// Used for testing. This should always be committed as false.
|
||||
const DISABLE_MONITOR_LIST_CACHING: bool = false;
|
||||
|
|
@ -21,32 +21,14 @@ impl XConnection {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct VideoModeHandle {
|
||||
pub(crate) current: bool,
|
||||
pub(crate) size: (u32, u32),
|
||||
pub(crate) bit_depth: Option<NonZeroU16>,
|
||||
pub(crate) refresh_rate_millihertz: Option<NonZeroU32>,
|
||||
pub(crate) mode: VideoMode,
|
||||
pub(crate) native_mode: randr::Mode,
|
||||
pub(crate) monitor: Option<MonitorHandle>,
|
||||
}
|
||||
|
||||
impl VideoModeHandle {
|
||||
#[inline]
|
||||
pub fn size(&self) -> PhysicalSize<u32> {
|
||||
self.size.into()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bit_depth(&self) -> Option<NonZeroU16> {
|
||||
self.bit_depth
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn refresh_rate_millihertz(&self) -> Option<NonZeroU32> {
|
||||
self.refresh_rate_millihertz
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn monitor(&self) -> MonitorHandle {
|
||||
self.monitor.clone().unwrap()
|
||||
impl From<VideoModeHandle> for VideoMode {
|
||||
fn from(handle: VideoModeHandle) -> Self {
|
||||
handle.mode
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +47,7 @@ pub struct MonitorHandle {
|
|||
/// Used to determine which windows are on this monitor
|
||||
pub(crate) rect: util::AaRect,
|
||||
/// Supported video modes on this monitor
|
||||
video_modes: Vec<VideoModeHandle>,
|
||||
pub(crate) video_modes: Vec<VideoModeHandle>,
|
||||
}
|
||||
|
||||
impl PartialEq for MonitorHandle {
|
||||
|
|
@ -159,17 +141,13 @@ impl MonitorHandle {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn current_video_mode(&self) -> Option<PlatformVideoModeHandle> {
|
||||
self.video_modes.iter().find(|mode| mode.current).cloned().map(PlatformVideoModeHandle::X)
|
||||
pub fn current_video_mode(&self) -> Option<VideoMode> {
|
||||
self.video_modes.iter().find(|mode| mode.current).cloned().map(Into::into)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn video_modes(&self) -> impl Iterator<Item = PlatformVideoModeHandle> {
|
||||
let monitor = self.clone();
|
||||
self.video_modes.clone().into_iter().map(move |mut x| {
|
||||
x.monitor = Some(monitor.clone());
|
||||
PlatformVideoModeHandle::X(x)
|
||||
})
|
||||
pub fn video_modes(&self) -> impl Iterator<Item = VideoMode> {
|
||||
self.video_modes.clone().into_iter().map(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use x11rb::protocol::randr::{self, ConnectionExt as _};
|
|||
|
||||
use super::*;
|
||||
use crate::dpi::validate_scale_factor;
|
||||
use crate::monitor::VideoMode;
|
||||
use crate::platform_impl::platform::x11::{monitor, VideoModeHandle};
|
||||
|
||||
/// Represents values of `WINIT_HIDPI_FACTOR`.
|
||||
|
|
@ -85,9 +86,11 @@ impl XConnection {
|
|||
.map(|mode| {
|
||||
VideoModeHandle {
|
||||
current: mode.id == current_mode,
|
||||
size: (mode.width.into(), mode.height.into()),
|
||||
refresh_rate_millihertz: monitor::mode_refresh_rate_millihertz(mode),
|
||||
bit_depth: NonZeroU16::new(bit_depth as u16),
|
||||
mode: VideoMode {
|
||||
size: (mode.width as u32, mode.height as u32).into(),
|
||||
refresh_rate_millihertz: monitor::mode_refresh_rate_millihertz(mode),
|
||||
bit_depth: NonZeroU16::new(bit_depth as u16),
|
||||
},
|
||||
native_mode: mode.id,
|
||||
// This is populated in `MonitorHandle::video_modes` as the
|
||||
// video mode is returned to the user
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ use crate::platform_impl::x11::{
|
|||
};
|
||||
use crate::platform_impl::{
|
||||
common, Fullscreen, MonitorHandle as PlatformMonitorHandle, PlatformCustomCursor, PlatformIcon,
|
||||
VideoModeHandle as PlatformVideoModeHandle,
|
||||
};
|
||||
use crate::window::{
|
||||
CursorGrabMode, ImePurpose, ResizeDirection, Theme, UserAttentionType, Window as CoreWindow,
|
||||
|
|
@ -327,7 +326,7 @@ impl Drop for Window {
|
|||
let xconn = &window.xconn;
|
||||
|
||||
// Restore the video mode on drop.
|
||||
if let Some(Fullscreen::Exclusive(_)) = window.fullscreen() {
|
||||
if let Some(Fullscreen::Exclusive(..)) = window.fullscreen() {
|
||||
window.set_fullscreen(None);
|
||||
}
|
||||
|
||||
|
|
@ -1035,20 +1034,17 @@ impl UnownedWindow {
|
|||
// fullscreen, so we can restore it upon exit, as XRandR does not
|
||||
// provide a mechanism to set this per app-session or restore this
|
||||
// to the desktop video mode as macOS and Windows do
|
||||
(&None, &Some(Fullscreen::Exclusive(PlatformVideoModeHandle::X(ref video_mode))))
|
||||
| (
|
||||
&Some(Fullscreen::Borderless(_)),
|
||||
&Some(Fullscreen::Exclusive(PlatformVideoModeHandle::X(ref video_mode))),
|
||||
) => {
|
||||
let monitor = video_mode.monitor.as_ref().unwrap();
|
||||
(&None, &Some(Fullscreen::Exclusive(ref monitor, _)))
|
||||
| (&Some(Fullscreen::Borderless(_)), &Some(Fullscreen::Exclusive(ref monitor, _))) => {
|
||||
let id = monitor.native_identifier();
|
||||
shared_state_lock.desktop_video_mode = Some((
|
||||
monitor.id,
|
||||
self.xconn.get_crtc_mode(monitor.id).expect("Failed to get desktop video mode"),
|
||||
id,
|
||||
self.xconn.get_crtc_mode(id).expect("Failed to get desktop video mode"),
|
||||
));
|
||||
},
|
||||
// Restore desktop video mode upon exiting exclusive fullscreen
|
||||
(&Some(Fullscreen::Exclusive(_)), &None)
|
||||
| (&Some(Fullscreen::Exclusive(_)), &Some(Fullscreen::Borderless(_))) => {
|
||||
(&Some(Fullscreen::Exclusive(..)), &None)
|
||||
| (&Some(Fullscreen::Exclusive(..)), &Some(Fullscreen::Borderless(_))) => {
|
||||
let (monitor_id, mode_id) = shared_state_lock.desktop_video_mode.take().unwrap();
|
||||
self.xconn
|
||||
.set_crtc_config(monitor_id, mode_id)
|
||||
|
|
@ -1072,8 +1068,8 @@ impl UnownedWindow {
|
|||
},
|
||||
Some(fullscreen) => {
|
||||
let (video_mode, monitor) = match fullscreen {
|
||||
Fullscreen::Exclusive(PlatformVideoModeHandle::X(ref video_mode)) => {
|
||||
(Some(video_mode), video_mode.monitor.clone().unwrap())
|
||||
Fullscreen::Exclusive(PlatformMonitorHandle::X(monitor), video_mode) => {
|
||||
(Some(video_mode), monitor.clone())
|
||||
},
|
||||
Fullscreen::Borderless(Some(PlatformMonitorHandle::X(monitor))) => {
|
||||
(None, monitor)
|
||||
|
|
@ -1090,7 +1086,15 @@ impl UnownedWindow {
|
|||
return Ok(None);
|
||||
}
|
||||
|
||||
if let Some(video_mode) = video_mode {
|
||||
if let Some(native_mode) = video_mode.and_then(|requested| {
|
||||
monitor.video_modes.iter().find_map(|mode| {
|
||||
if mode.mode == requested {
|
||||
Some(mode.native_mode)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}) {
|
||||
// FIXME: this is actually not correct if we're setting the
|
||||
// video mode to a resolution higher than the current
|
||||
// desktop resolution, because XRandR does not automatically
|
||||
|
|
@ -1117,7 +1121,7 @@ impl UnownedWindow {
|
|||
// this will make someone unhappy, but it's very unusual for
|
||||
// games to want to do this anyway).
|
||||
self.xconn
|
||||
.set_crtc_config(monitor.id, video_mode.native_mode)
|
||||
.set_crtc_config(monitor.id, native_mode)
|
||||
.expect("failed to set video mode");
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue