mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2025-02-24 00:37:43 +11:00
X11: Check if XRRGetOutputInfo
returned NULL
(#709)
* X11: Check if XRRGetOutputInfo returned NULL Fixes #693 * Change X11 error logging to actually use log
This commit is contained in:
parent
3ba808e3c6
commit
3c59283b3f
4 changed files with 23 additions and 11 deletions
|
@ -5,6 +5,7 @@
|
||||||
- On Windows, catch panics in event loop child thread and forward them to the parent thread. This prevents an invocation of undefined behavior due to unwinding into foreign code.
|
- On Windows, catch panics in event loop child thread and forward them to the parent thread. This prevents an invocation of undefined behavior due to unwinding into foreign code.
|
||||||
- On Windows, fix issue where resizing or moving window combined with grabbing the cursor would freeze program.
|
- On Windows, fix issue where resizing or moving window combined with grabbing the cursor would freeze program.
|
||||||
- On Windows, fix issue where resizing or moving window would eat `Awakened` events.
|
- On Windows, fix issue where resizing or moving window would eat `Awakened` events.
|
||||||
|
- On X11, fixed a segfault when using virtual monitors with XRandR.
|
||||||
|
|
||||||
# Version 0.18.0 (2018-11-07)
|
# Version 0.18.0 (2018-11-07)
|
||||||
|
|
||||||
|
|
|
@ -382,7 +382,7 @@ unsafe extern "C" fn x_error_callback(
|
||||||
minor_code: (*event).minor_code,
|
minor_code: (*event).minor_code,
|
||||||
};
|
};
|
||||||
|
|
||||||
eprintln!("[winit X11 error] {:#?}", error);
|
error!("X11 error: {:#?}", error);
|
||||||
|
|
||||||
*xconn.latest_error.lock() = Some(error);
|
*xconn.latest_error.lock() = Some(error);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,11 +65,11 @@ impl MonitorId {
|
||||||
id: u32,
|
id: u32,
|
||||||
repr: util::MonitorRepr,
|
repr: util::MonitorRepr,
|
||||||
primary: bool,
|
primary: bool,
|
||||||
) -> Self {
|
) -> Option<Self> {
|
||||||
let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr) };
|
let (name, hidpi_factor) = unsafe { xconn.get_output_info(resources, &repr)? };
|
||||||
let (dimensions, position) = unsafe { (repr.get_dimensions(), repr.get_position()) };
|
let (dimensions, position) = unsafe { (repr.get_dimensions(), repr.get_position()) };
|
||||||
let rect = util::AaRect::new(position, dimensions);
|
let rect = util::AaRect::new(position, dimensions);
|
||||||
MonitorId {
|
Some(MonitorId {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
hidpi_factor,
|
hidpi_factor,
|
||||||
|
@ -77,7 +77,7 @@ impl MonitorId {
|
||||||
position,
|
position,
|
||||||
primary,
|
primary,
|
||||||
rect,
|
rect,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_name(&self) -> Option<String> {
|
pub fn get_name(&self) -> Option<String> {
|
||||||
|
@ -153,13 +153,13 @@ impl XConnection {
|
||||||
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;
|
has_primary |= is_primary;
|
||||||
available.push(MonitorId::from_repr(
|
MonitorId::from_repr(
|
||||||
self,
|
self,
|
||||||
resources,
|
resources,
|
||||||
monitor_index as u32,
|
monitor_index as u32,
|
||||||
monitor.into(),
|
monitor.into(),
|
||||||
is_primary,
|
is_primary,
|
||||||
));
|
).map(|monitor_id| available.push(monitor_id));
|
||||||
}
|
}
|
||||||
(xrandr_1_5.XRRFreeMonitors)(monitors);
|
(xrandr_1_5.XRRFreeMonitors)(monitors);
|
||||||
} else {
|
} else {
|
||||||
|
@ -176,13 +176,13 @@ impl XConnection {
|
||||||
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;
|
has_primary |= is_primary;
|
||||||
available.push(MonitorId::from_repr(
|
MonitorId::from_repr(
|
||||||
self,
|
self,
|
||||||
resources,
|
resources,
|
||||||
crtc_id as u32,
|
crtc_id as u32,
|
||||||
crtc,
|
crtc,
|
||||||
is_primary,
|
is_primary,
|
||||||
));
|
).map(|monitor_id| available.push(monitor_id));
|
||||||
}
|
}
|
||||||
(self.xrandr.XRRFreeCrtcInfo)(crtc);
|
(self.xrandr.XRRFreeCrtcInfo)(crtc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,12 +79,23 @@ impl From<*mut ffi::XRRCrtcInfo> for MonitorRepr {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl XConnection {
|
impl XConnection {
|
||||||
pub unsafe fn get_output_info(&self, resources: *mut ffi::XRRScreenResources, repr: &MonitorRepr) -> (String, f64) {
|
pub unsafe fn get_output_info(
|
||||||
|
&self,
|
||||||
|
resources: *mut ffi::XRRScreenResources,
|
||||||
|
repr: &MonitorRepr,
|
||||||
|
) -> Option<(String, f64)> {
|
||||||
let output_info = (self.xrandr.XRRGetOutputInfo)(
|
let output_info = (self.xrandr.XRRGetOutputInfo)(
|
||||||
self.display,
|
self.display,
|
||||||
resources,
|
resources,
|
||||||
repr.get_output(),
|
repr.get_output(),
|
||||||
);
|
);
|
||||||
|
if output_info.is_null() {
|
||||||
|
// When calling `XRRGetOutputInfo` on a virtual monitor (versus a physical display)
|
||||||
|
// it's possible for it to return null.
|
||||||
|
// https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=816596
|
||||||
|
let _ = self.check_errors(); // discard `BadRROutput` error
|
||||||
|
return None;
|
||||||
|
}
|
||||||
let name_slice = slice::from_raw_parts(
|
let name_slice = slice::from_raw_parts(
|
||||||
(*output_info).name as *mut u8,
|
(*output_info).name as *mut u8,
|
||||||
(*output_info).nameLen as usize,
|
(*output_info).nameLen as usize,
|
||||||
|
@ -95,6 +106,6 @@ impl XConnection {
|
||||||
((*output_info).mm_width as u64, (*output_info).mm_height as u64),
|
((*output_info).mm_width as u64, (*output_info).mm_height as u64),
|
||||||
);
|
);
|
||||||
(self.xrandr.XRRFreeOutputInfo)(output_info);
|
(self.xrandr.XRRFreeOutputInfo)(output_info);
|
||||||
(name, hidpi_factor)
|
Some((name, hidpi_factor))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue