X11: Fix panic when dropping window before running event loop (#694)

Fixes #691

Dropping a window before running the `EventsLoop` results in events
still being queued when `XDestroyWindow` is called, so events like
`XI_Enter` (the culprit in this case) will still be processed.
Simply checking that the window still exists before calling
`query_pointer` was enough to solve the problem.
This commit is contained in:
Francesca Plebani 2018-11-10 13:54:50 -05:00 committed by GitHub
parent dd52364d33
commit 917db35a84
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 9 deletions

View file

@ -1,5 +1,7 @@
# Unreleased # Unreleased
- On X11, fixed panic caused by dropping the window before running the event loop.
# Version 0.18.0 (2018-11-07) # Version 0.18.0 (2018-11-07)
- **Breaking:** `image` crate upgraded to 0.20. This is exposed as part of the `icon_loading` API. - **Breaking:** `image` crate upgraded to 0.20. This is exposed as part of the `icon_loading` API.

View file

@ -864,20 +864,26 @@ impl EventsLoop {
event: CursorEntered { device_id }, event: CursorEntered { device_id },
}); });
// The mods field on this event isn't actually populated, so query the if let Some(dpi_factor) = self.with_window(xev.event, |window| {
// pointer device. In the future, we can likely remove this round-trip by
// relying on Xkb for modifier values.
let modifiers = self.xconn.query_pointer(xev.event, xev.deviceid)
.expect("Failed to query pointer device").get_modifier_state();
let dpi_factor = self.with_window(xev.event, |window| {
window.get_hidpi_factor() window.get_hidpi_factor()
}); }) {
if let Some(dpi_factor) = dpi_factor {
let position = LogicalPosition::from_physical( let position = LogicalPosition::from_physical(
(xev.event_x as f64, xev.event_y as f64), (xev.event_x as f64, xev.event_y as f64),
dpi_factor, dpi_factor,
); );
// The mods field on this event isn't actually populated, so query the
// pointer device. In the future, we can likely remove this round-trip by
// relying on `Xkb` for modifier values.
//
// This needs to only be done after confirming the window still exists,
// since otherwise we risk getting a `BadWindow` error if the window was
// dropped with queued events.
let modifiers = self.xconn
.query_pointer(xev.event, xev.deviceid)
.expect("Failed to query pointer device")
.get_modifier_state();
callback(Event::WindowEvent { callback(Event::WindowEvent {
window_id, window_id,
event: CursorMoved { event: CursorMoved {