X11: Fix deadlock on window state with certain window events (#1369)

This commit is contained in:
Murarth 2020-01-06 20:54:22 -07:00 committed by Freya Gentz
parent 6a330a2894
commit 6b0875728c
2 changed files with 21 additions and 9 deletions

View file

@ -1,6 +1,7 @@
# Unreleased # Unreleased
- On Windows, fix bug where `RedrawRequested` would only get emitted every other iteration of the event loop. - On Windows, fix bug where `RedrawRequested` would only get emitted every other iteration of the event loop.
- On X11, fix deadlock on window state when handling certain window events.
# 0.20.0 (2020-01-05) # 0.20.0 (2020-01-05)

View file

@ -2,6 +2,8 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc, slice, sync::Arc};
use libc::{c_char, c_int, c_long, c_uint, c_ulong}; use libc::{c_char, c_int, c_long, c_uint, c_ulong};
use parking_lot::MutexGuard;
use super::{ use super::{
events, ffi, get_xtarget, mkdid, mkwid, monitor, util, Device, DeviceId, DeviceInfo, Dnd, events, ffi, get_xtarget, mkdid, mkwid, monitor, util, Device, DeviceId, DeviceInfo, Dnd,
DndState, GenericEventCookie, ImeReceiver, ScrollOrientation, UnownedWindow, WindowId, DndState, GenericEventCookie, ImeReceiver, ScrollOrientation, UnownedWindow, WindowId,
@ -384,10 +386,13 @@ impl<T: 'static> EventProcessor<T> {
.inner_pos_to_outer(new_inner_position.0, new_inner_position.1); .inner_pos_to_outer(new_inner_position.0, new_inner_position.1);
shared_state_lock.position = Some(outer); shared_state_lock.position = Some(outer);
if moved { if moved {
// Temporarily unlock shared state to prevent deadlock
MutexGuard::unlocked(&mut shared_state_lock, || {
callback(Event::WindowEvent { callback(Event::WindowEvent {
window_id, window_id,
event: WindowEvent::Moved(outer.into()), event: WindowEvent::Moved(outer.into()),
}); });
});
} }
outer outer
} else { } else {
@ -426,6 +431,8 @@ impl<T: 'static> EventProcessor<T> {
let old_inner_size = PhysicalSize::new(width, height); let old_inner_size = PhysicalSize::new(width, height);
let mut new_inner_size = PhysicalSize::new(new_width, new_height); let mut new_inner_size = PhysicalSize::new(new_width, new_height);
// Temporarily unlock shared state to prevent deadlock
MutexGuard::unlocked(&mut shared_state_lock, || {
callback(Event::WindowEvent { callback(Event::WindowEvent {
window_id, window_id,
event: WindowEvent::ScaleFactorChanged { event: WindowEvent::ScaleFactorChanged {
@ -433,6 +440,7 @@ impl<T: 'static> EventProcessor<T> {
new_inner_size: &mut new_inner_size, new_inner_size: &mut new_inner_size,
}, },
}); });
});
if new_inner_size != old_inner_size { if new_inner_size != old_inner_size {
window.set_inner_size_physical( window.set_inner_size_physical(
@ -461,6 +469,9 @@ impl<T: 'static> EventProcessor<T> {
} }
if resized { if resized {
// Drop the shared state lock to prevent deadlock
drop(shared_state_lock);
callback(Event::WindowEvent { callback(Event::WindowEvent {
window_id, window_id,
event: WindowEvent::Resized(new_inner_size.into()), event: WindowEvent::Resized(new_inner_size.into()),