mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 22:31:30 +11:00
X11: Fix primary monitor fallback regression (#532)
This commit is contained in:
parent
a34147b602
commit
17373a4e91
|
@ -19,7 +19,20 @@ const FORCE_RANDR_COMPAT: bool = false;
|
||||||
const DISABLE_MONITOR_LIST_CACHING: bool = false;
|
const DISABLE_MONITOR_LIST_CACHING: bool = false;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref MONITORS: Mutex<Option<Vec<MonitorId>>> = Mutex::new(None);
|
static ref XRANDR_VERSION: Mutex<Option<(c_int, c_int)>> = Mutex::default();
|
||||||
|
static ref MONITORS: Mutex<Option<Vec<MonitorId>>> = Mutex::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn version_is_at_least(major: c_int, minor: c_int) -> bool {
|
||||||
|
if let Some((avail_major, avail_minor)) = *XRANDR_VERSION.lock() {
|
||||||
|
if avail_major == major {
|
||||||
|
avail_minor >= minor
|
||||||
|
} else {
|
||||||
|
avail_major > major
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn invalidate_cached_monitor_list() -> Option<Vec<MonitorId>> {
|
pub fn invalidate_cached_monitor_list() -> Option<Vec<MonitorId>> {
|
||||||
|
@ -128,17 +141,20 @@ fn query_monitor_list(xconn: &Arc<XConnection>) -> Vec<MonitorId> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut available;
|
let mut available;
|
||||||
|
let mut has_primary = false;
|
||||||
|
|
||||||
if xconn.xrandr_1_5.is_some() && !FORCE_RANDR_COMPAT {
|
if xconn.xrandr_1_5.is_some() && version_is_at_least(1, 5) && !FORCE_RANDR_COMPAT {
|
||||||
// We're in XRandR >= 1.5, enumerate monitors. This supports things like MST and
|
// We're in XRandR >= 1.5, enumerate monitors. This supports things like MST and
|
||||||
// videowalls.
|
// videowalls.
|
||||||
let xrandr_1_5 = xconn.xrandr_1_5.as_ref().unwrap();
|
let xrandr_1_5 = xconn.xrandr_1_5.as_ref().unwrap();
|
||||||
let mut monitor_count = 0;
|
let mut monitor_count = 0;
|
||||||
let monitors = (xrandr_1_5.XRRGetMonitors)(xconn.display, root, 1, &mut monitor_count);
|
let monitors = (xrandr_1_5.XRRGetMonitors)(xconn.display, root, 1, &mut monitor_count);
|
||||||
|
assert!(monitor_count >= 0);
|
||||||
available = Vec::with_capacity(monitor_count as usize);
|
available = Vec::with_capacity(monitor_count as usize);
|
||||||
for monitor_index in 0..monitor_count {
|
for monitor_index in 0..monitor_count {
|
||||||
let monitor = monitors.offset(monitor_index as isize);
|
let monitor = monitors.offset(monitor_index as isize);
|
||||||
let is_primary = (*monitor).primary != 0;
|
let is_primary = (*monitor).primary != 0;
|
||||||
|
has_primary |= is_primary;
|
||||||
available.push(MonitorId::from_repr(
|
available.push(MonitorId::from_repr(
|
||||||
xconn,
|
xconn,
|
||||||
resources,
|
resources,
|
||||||
|
@ -161,6 +177,7 @@ fn query_monitor_list(xconn: &Arc<XConnection>) -> Vec<MonitorId> {
|
||||||
if is_active {
|
if is_active {
|
||||||
let crtc = util::MonitorRepr::from(crtc);
|
let crtc = util::MonitorRepr::from(crtc);
|
||||||
let is_primary = crtc.get_output() == primary;
|
let is_primary = crtc.get_output() == primary;
|
||||||
|
has_primary |= is_primary;
|
||||||
available.push(MonitorId::from_repr(
|
available.push(MonitorId::from_repr(
|
||||||
xconn,
|
xconn,
|
||||||
resources,
|
resources,
|
||||||
|
@ -173,6 +190,14 @@ fn query_monitor_list(xconn: &Arc<XConnection>) -> Vec<MonitorId> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If no monitors were detected as being primary, we just pick one ourselves!
|
||||||
|
if !has_primary {
|
||||||
|
if let Some(ref mut fallback) = available.first_mut() {
|
||||||
|
// Setting this here will come in handy if we ever add an `is_primary` method.
|
||||||
|
fallback.primary = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(xconn.xrandr.XRRFreeScreenResources)(resources);
|
(xconn.xrandr.XRRFreeScreenResources)(resources);
|
||||||
available
|
available
|
||||||
}
|
}
|
||||||
|
@ -194,27 +219,31 @@ pub fn get_available_monitors(xconn: &Arc<XConnection>) -> Vec<MonitorId> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_primary_monitor(x: &Arc<XConnection>) -> MonitorId {
|
pub fn get_primary_monitor(xconn: &Arc<XConnection>) -> MonitorId {
|
||||||
let mut available_monitors = get_available_monitors(x).into_iter();
|
get_available_monitors(xconn)
|
||||||
available_monitors
|
.into_iter()
|
||||||
.find(|m| m.primary)
|
.find(|monitor| monitor.primary)
|
||||||
// If no monitors were detected as being primary, we just pick one ourselves!
|
|
||||||
.or_else(|| available_monitors.next())
|
|
||||||
.expect("[winit] Failed to find any monitors using XRandR.")
|
.expect("[winit] Failed to find any monitors using XRandR.")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_input(xconn: &Arc<XConnection>, root: Window) -> Result<c_int, XError> {
|
pub fn select_input(xconn: &Arc<XConnection>, root: Window) -> Result<c_int, XError> {
|
||||||
let mut major = 0;
|
{
|
||||||
let mut minor = 0;
|
let mut version_lock = XRANDR_VERSION.lock();
|
||||||
let has_extension = unsafe {
|
if version_lock.is_none() {
|
||||||
(xconn.xrandr.XRRQueryExtension)(
|
let mut major = 0;
|
||||||
xconn.display,
|
let mut minor = 0;
|
||||||
&mut major,
|
let has_extension = unsafe {
|
||||||
&mut minor,
|
(xconn.xrandr.XRRQueryVersion)(
|
||||||
)
|
xconn.display,
|
||||||
};
|
&mut major,
|
||||||
if has_extension != True {
|
&mut minor,
|
||||||
panic!("[winit] XRandR extension not available.");
|
)
|
||||||
|
};
|
||||||
|
if has_extension != True {
|
||||||
|
panic!("[winit] XRandR extension not available.");
|
||||||
|
}
|
||||||
|
*version_lock = Some((major, minor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut event_offset = 0;
|
let mut event_offset = 0;
|
||||||
|
|
Loading…
Reference in a new issue