mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 14:21:31 +11:00
X11: Fix panic when no monitors are available (#1158)
* X11: Fix panic when no monitors are available * Set dummy monitor's dimensions to `(1, 1)` * X11: Avoid panicking when there are no monitors in Window::new
This commit is contained in:
parent
c0a7900341
commit
472eddcc1b
|
@ -17,6 +17,7 @@
|
||||||
- On macOS, fix events not being emitted during modal loops, such as when windows are being resized
|
- On macOS, fix events not being emitted during modal loops, such as when windows are being resized
|
||||||
by the user.
|
by the user.
|
||||||
- On Windows, fix hovering the mouse over the active window creating an endless stream of CursorMoved events.
|
- On Windows, fix hovering the mouse over the active window creating an endless stream of CursorMoved events.
|
||||||
|
- On X11, return dummy monitor data to avoid panicking when no monitors exist.
|
||||||
- On X11, prevent stealing input focus when creating a new window.
|
- On X11, prevent stealing input focus when creating a new window.
|
||||||
Only steal input focus when entering fullscreen mode.
|
Only steal input focus when entering fullscreen mode.
|
||||||
|
|
||||||
|
|
|
@ -389,7 +389,11 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
let window_rect = util::AaRect::new(new_outer_position, new_inner_size);
|
let window_rect = util::AaRect::new(new_outer_position, new_inner_size);
|
||||||
monitor = wt.xconn.get_monitor_for_window(Some(window_rect));
|
monitor = wt.xconn.get_monitor_for_window(Some(window_rect));
|
||||||
let new_hidpi_factor = monitor.hidpi_factor;
|
let new_hidpi_factor = monitor.hidpi_factor;
|
||||||
shared_state_lock.last_monitor = Some(monitor.clone());
|
|
||||||
|
// Avoid caching an invalid dummy monitor handle
|
||||||
|
if monitor.id != 0 {
|
||||||
|
shared_state_lock.last_monitor = Some(monitor.clone());
|
||||||
|
}
|
||||||
new_hidpi_factor
|
new_hidpi_factor
|
||||||
};
|
};
|
||||||
if last_hidpi_factor != new_hidpi_factor {
|
if last_hidpi_factor != new_hidpi_factor {
|
||||||
|
|
|
@ -130,6 +130,19 @@ impl MonitorHandle {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn dummy() -> Self {
|
||||||
|
MonitorHandle {
|
||||||
|
id: 0,
|
||||||
|
name: "<dummy monitor>".into(),
|
||||||
|
hidpi_factor: 1.0,
|
||||||
|
dimensions: (1, 1),
|
||||||
|
position: (0, 0),
|
||||||
|
primary: true,
|
||||||
|
rect: util::AaRect::new((0, 0), (1, 1)),
|
||||||
|
video_modes: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> Option<String> {
|
pub fn name(&self) -> Option<String> {
|
||||||
Some(self.name.clone())
|
Some(self.name.clone())
|
||||||
}
|
}
|
||||||
|
@ -167,9 +180,13 @@ impl MonitorHandle {
|
||||||
impl XConnection {
|
impl XConnection {
|
||||||
pub fn get_monitor_for_window(&self, window_rect: Option<util::AaRect>) -> MonitorHandle {
|
pub fn get_monitor_for_window(&self, window_rect: Option<util::AaRect>) -> MonitorHandle {
|
||||||
let monitors = self.available_monitors();
|
let monitors = self.available_monitors();
|
||||||
let default = monitors
|
|
||||||
.get(0)
|
if monitors.is_empty() {
|
||||||
.expect("[winit] Failed to find any monitors using XRandR.");
|
// Return a dummy monitor to avoid panicking
|
||||||
|
return MonitorHandle::dummy();
|
||||||
|
}
|
||||||
|
|
||||||
|
let default = monitors.get(0).unwrap();
|
||||||
|
|
||||||
let window_rect = match window_rect {
|
let window_rect = match window_rect {
|
||||||
Some(rect) => rect,
|
Some(rect) => rect,
|
||||||
|
@ -259,7 +276,7 @@ impl XConnection {
|
||||||
self.available_monitors()
|
self.available_monitors()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|monitor| monitor.primary)
|
.find(|monitor| monitor.primary)
|
||||||
.expect("[winit] Failed to find any monitors using XRandR.")
|
.unwrap_or_else(MonitorHandle::dummy)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_xrandr_input(&self, root: Window) -> Result<c_int, XError> {
|
pub fn select_xrandr_input(&self, root: Window) -> Result<c_int, XError> {
|
||||||
|
|
|
@ -119,7 +119,7 @@ impl UnownedWindow {
|
||||||
.unwrap_or(1.0)
|
.unwrap_or(1.0)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
return Err(os_error!(OsError::XMisc("No monitors were detected.")));
|
1.0
|
||||||
};
|
};
|
||||||
|
|
||||||
info!("Guessed window DPI factor: {}", dpi_factor);
|
info!("Guessed window DPI factor: {}", dpi_factor);
|
||||||
|
@ -637,6 +637,11 @@ impl UnownedWindow {
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Don't set fullscreen on an invalid dummy monitor handle
|
||||||
|
if monitor.id == 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(video_mode) = video_mode {
|
if let Some(video_mode) = video_mode {
|
||||||
// FIXME: this is actually not correct if we're setting the
|
// FIXME: this is actually not correct if we're setting the
|
||||||
// video mode to a resolution higher than the current
|
// video mode to a resolution higher than the current
|
||||||
|
@ -704,11 +709,11 @@ impl UnownedWindow {
|
||||||
pub fn current_monitor(&self) -> X11MonitorHandle {
|
pub fn current_monitor(&self) -> X11MonitorHandle {
|
||||||
let monitor = self.shared_state.lock().last_monitor.as_ref().cloned();
|
let monitor = self.shared_state.lock().last_monitor.as_ref().cloned();
|
||||||
monitor.unwrap_or_else(|| {
|
monitor.unwrap_or_else(|| {
|
||||||
let monitor = self
|
let monitor = self.xconn.get_monitor_for_window(Some(self.get_rect()));
|
||||||
.xconn
|
// Avoid caching an invalid dummy monitor handle
|
||||||
.get_monitor_for_window(Some(self.get_rect()))
|
if monitor.id != 0 {
|
||||||
.to_owned();
|
self.shared_state.lock().last_monitor = Some(monitor.clone());
|
||||||
self.shared_state.lock().last_monitor = Some(monitor.clone());
|
}
|
||||||
monitor
|
monitor
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue