mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
X11: Fix request_redraw
not waking the event loop (#1756)
This commit is contained in:
parent
3a077ff211
commit
45e4fd6ec1
|
@ -9,6 +9,7 @@
|
|||
- On Windows, fix use after free crash during window destruction.
|
||||
- On Web, fix `WindowEvent::ReceivedCharacter` never being sent on key input.
|
||||
- On macOS, fix compilation when targeting aarch64
|
||||
- On X11, fix `Window::request_redraw` not waking the event loop.
|
||||
|
||||
# 0.23.0 (2020-10-02)
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ pub use self::{
|
|||
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::{HashMap, HashSet},
|
||||
collections::HashMap,
|
||||
ffi::CStr,
|
||||
mem::{self, MaybeUninit},
|
||||
ops::Deref,
|
||||
|
@ -32,7 +32,7 @@ use std::{
|
|||
ptr,
|
||||
rc::Rc,
|
||||
slice,
|
||||
sync::{mpsc, Arc, Mutex, Weak},
|
||||
sync::{mpsc, Arc, Weak},
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
|
||||
|
@ -58,6 +58,7 @@ use crate::{
|
|||
|
||||
const X_TOKEN: Token = Token(0);
|
||||
const USER_TOKEN: Token = Token(1);
|
||||
const REDRAW_TOKEN: Token = Token(2);
|
||||
|
||||
pub struct EventLoopWindowTarget<T> {
|
||||
xconn: Arc<XConnection>,
|
||||
|
@ -67,13 +68,14 @@ pub struct EventLoopWindowTarget<T> {
|
|||
root: ffi::Window,
|
||||
ime: RefCell<Ime>,
|
||||
windows: RefCell<HashMap<WindowId, Weak<UnownedWindow>>>,
|
||||
pending_redraws: Arc<Mutex<HashSet<WindowId>>>,
|
||||
redraw_sender: Sender<WindowId>,
|
||||
_marker: ::std::marker::PhantomData<T>,
|
||||
}
|
||||
|
||||
pub struct EventLoop<T: 'static> {
|
||||
poll: Poll,
|
||||
event_processor: EventProcessor<T>,
|
||||
redraw_channel: Receiver<WindowId>,
|
||||
user_channel: Receiver<T>,
|
||||
user_sender: Sender<T>,
|
||||
target: Rc<RootELW<T>>,
|
||||
|
@ -174,32 +176,16 @@ impl<T: 'static> EventLoop<T> {
|
|||
|
||||
xconn.update_cached_wm_info(root);
|
||||
|
||||
let pending_redraws: Arc<Mutex<HashSet<WindowId>>> = Default::default();
|
||||
|
||||
let mut mod_keymap = ModifierKeymap::new();
|
||||
mod_keymap.reset_from_x_connection(&xconn);
|
||||
|
||||
let target = Rc::new(RootELW {
|
||||
p: super::EventLoopWindowTarget::X(EventLoopWindowTarget {
|
||||
ime,
|
||||
root,
|
||||
windows: Default::default(),
|
||||
_marker: ::std::marker::PhantomData,
|
||||
ime_sender,
|
||||
xconn,
|
||||
wm_delete_window,
|
||||
net_wm_ping,
|
||||
pending_redraws: pending_redraws.clone(),
|
||||
}),
|
||||
_marker: ::std::marker::PhantomData,
|
||||
});
|
||||
|
||||
let poll = Poll::new().unwrap();
|
||||
|
||||
let (user_sender, user_channel) = channel();
|
||||
let (redraw_sender, redraw_channel) = channel();
|
||||
|
||||
poll.register(
|
||||
&EventedFd(&get_xtarget(&target).xconn.x11_fd),
|
||||
&EventedFd(&xconn.x11_fd),
|
||||
X_TOKEN,
|
||||
Ready::readable(),
|
||||
PollOpt::level(),
|
||||
|
@ -214,6 +200,29 @@ impl<T: 'static> EventLoop<T> {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
poll.register(
|
||||
&redraw_channel,
|
||||
REDRAW_TOKEN,
|
||||
Ready::readable(),
|
||||
PollOpt::level(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let target = Rc::new(RootELW {
|
||||
p: super::EventLoopWindowTarget::X(EventLoopWindowTarget {
|
||||
ime,
|
||||
root,
|
||||
windows: Default::default(),
|
||||
_marker: ::std::marker::PhantomData,
|
||||
ime_sender,
|
||||
xconn,
|
||||
wm_delete_window,
|
||||
net_wm_ping,
|
||||
redraw_sender,
|
||||
}),
|
||||
_marker: ::std::marker::PhantomData,
|
||||
});
|
||||
|
||||
let event_processor = EventProcessor {
|
||||
target: target.clone(),
|
||||
dnd,
|
||||
|
@ -239,6 +248,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
|
||||
let result = EventLoop {
|
||||
poll,
|
||||
redraw_channel,
|
||||
user_channel,
|
||||
user_sender,
|
||||
event_processor,
|
||||
|
@ -277,8 +287,6 @@ impl<T: 'static> EventLoop<T> {
|
|||
// Process all pending events
|
||||
self.drain_events(&mut callback, &mut control_flow);
|
||||
|
||||
let wt = get_xtarget(&self.target);
|
||||
|
||||
// Empty the user event buffer
|
||||
{
|
||||
while let Ok(event) = self.user_channel.try_recv() {
|
||||
|
@ -301,12 +309,10 @@ impl<T: 'static> EventLoop<T> {
|
|||
}
|
||||
// Empty the redraw requests
|
||||
{
|
||||
// Release the lock to prevent deadlock
|
||||
let windows: Vec<_> = wt.pending_redraws.lock().unwrap().drain().collect();
|
||||
|
||||
for wid in windows {
|
||||
while let Ok(window_id) = self.redraw_channel.try_recv() {
|
||||
let window_id = crate::window::WindowId(super::WindowId::X(window_id));
|
||||
sticky_exit_callback(
|
||||
Event::RedrawRequested(crate::window::WindowId(super::WindowId::X(wid))),
|
||||
Event::RedrawRequested(window_id),
|
||||
&self.target,
|
||||
&mut control_flow,
|
||||
&mut callback,
|
||||
|
@ -408,7 +414,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
super::WindowId::X(wid),
|
||||
)) = event
|
||||
{
|
||||
wt.pending_redraws.lock().unwrap().insert(wid);
|
||||
wt.redraw_sender.send(wid).unwrap();
|
||||
} else {
|
||||
callback(event, window_target, control_flow);
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use raw_window_handle::unix::XlibHandle;
|
||||
use std::{
|
||||
cmp,
|
||||
collections::HashSet,
|
||||
env,
|
||||
cmp, env,
|
||||
ffi::CString,
|
||||
mem::{self, replace, MaybeUninit},
|
||||
os::raw::*,
|
||||
|
@ -12,6 +10,7 @@ use std::{
|
|||
};
|
||||
|
||||
use libc;
|
||||
use mio_extras::channel::Sender;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use crate::{
|
||||
|
@ -104,7 +103,7 @@ pub struct UnownedWindow {
|
|||
cursor_visible: Mutex<bool>,
|
||||
ime_sender: Mutex<ImeSender>,
|
||||
pub shared_state: Mutex<SharedState>,
|
||||
pending_redraws: Arc<::std::sync::Mutex<HashSet<WindowId>>>,
|
||||
redraw_sender: Sender<WindowId>,
|
||||
}
|
||||
|
||||
impl UnownedWindow {
|
||||
|
@ -249,7 +248,7 @@ impl UnownedWindow {
|
|||
cursor_visible: Mutex::new(true),
|
||||
ime_sender: Mutex::new(event_loop.ime_sender.clone()),
|
||||
shared_state: SharedState::new(guessed_monitor, window_attrs.visible),
|
||||
pending_redraws: event_loop.pending_redraws.clone(),
|
||||
redraw_sender: event_loop.redraw_sender.clone(),
|
||||
};
|
||||
|
||||
// Title must be set before mapping. Some tiling window managers (i.e. i3) use the window
|
||||
|
@ -1314,10 +1313,7 @@ impl UnownedWindow {
|
|||
|
||||
#[inline]
|
||||
pub fn request_redraw(&self) {
|
||||
self.pending_redraws
|
||||
.lock()
|
||||
.unwrap()
|
||||
.insert(WindowId(self.xwindow));
|
||||
self.redraw_sender.send(WindowId(self.xwindow)).unwrap();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
Loading…
Reference in a new issue