mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-24 06:11:30 +11:00
X11 - Move event insertion from interrupt to proxy wakeup.
This commit is contained in:
parent
2b55b2e0ef
commit
38856b1c60
|
@ -42,6 +42,8 @@ pub struct EventsLoop {
|
||||||
|
|
||||||
pub struct EventsLoopProxy {
|
pub struct EventsLoopProxy {
|
||||||
pending_wakeup: Weak<AtomicBool>,
|
pending_wakeup: Weak<AtomicBool>,
|
||||||
|
display: Weak<XConnection>,
|
||||||
|
root: ffi::Window,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventsLoop {
|
impl EventsLoop {
|
||||||
|
@ -111,29 +113,13 @@ impl EventsLoop {
|
||||||
pub fn create_proxy(&self) -> EventsLoopProxy {
|
pub fn create_proxy(&self) -> EventsLoopProxy {
|
||||||
EventsLoopProxy {
|
EventsLoopProxy {
|
||||||
pending_wakeup: Arc::downgrade(&self.pending_wakeup),
|
pending_wakeup: Arc::downgrade(&self.pending_wakeup),
|
||||||
|
display: Arc::downgrade(&self.display),
|
||||||
|
root: self.root,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interrupt(&self) {
|
pub fn interrupt(&self) {
|
||||||
self.interrupted.store(true, atomic::Ordering::Relaxed);
|
self.interrupted.store(true, atomic::Ordering::Relaxed);
|
||||||
|
|
||||||
// Push an event on the X event queue so that methods like run_forever will advance.
|
|
||||||
let mut xev = ffi::XClientMessageEvent {
|
|
||||||
type_: ffi::ClientMessage,
|
|
||||||
window: self.root,
|
|
||||||
format: 32,
|
|
||||||
message_type: 0,
|
|
||||||
serial: 0,
|
|
||||||
send_event: 0,
|
|
||||||
display: self.display.display,
|
|
||||||
data: unsafe { mem::zeroed() },
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
(self.display.xlib.XSendEvent)(self.display.display, self.root, 0, 0, mem::transmute(&mut xev));
|
|
||||||
(self.display.xlib.XFlush)(self.display.display);
|
|
||||||
self.display.check_errors().expect("Failed to call XSendEvent after wakeup");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_events<F>(&self, mut callback: F)
|
pub fn poll_events<F>(&self, mut callback: F)
|
||||||
|
@ -165,6 +151,7 @@ impl EventsLoop {
|
||||||
where F: FnMut(Event)
|
where F: FnMut(Event)
|
||||||
{
|
{
|
||||||
self.interrupted.store(false, atomic::Ordering::Relaxed);
|
self.interrupted.store(false, atomic::Ordering::Relaxed);
|
||||||
|
self.pending_wakeup.store(false, atomic::Ordering::Relaxed);
|
||||||
|
|
||||||
let xlib = &self.display.xlib;
|
let xlib = &self.display.xlib;
|
||||||
|
|
||||||
|
@ -172,6 +159,12 @@ impl EventsLoop {
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
unsafe { (xlib.XNextEvent)(self.display.display, &mut xev) }; // Blocks as necessary
|
unsafe { (xlib.XNextEvent)(self.display.display, &mut xev) }; // Blocks as necessary
|
||||||
|
|
||||||
|
if self.pending_wakeup.load(atomic::Ordering::Relaxed) {
|
||||||
|
self.pending_wakeup.store(false, atomic::Ordering::Relaxed);
|
||||||
|
callback(Event::Awakened);
|
||||||
|
}
|
||||||
|
|
||||||
self.process_event(&mut xev, &mut callback);
|
self.process_event(&mut xev, &mut callback);
|
||||||
if self.interrupted.load(atomic::Ordering::Relaxed) {
|
if self.interrupted.load(atomic::Ordering::Relaxed) {
|
||||||
break;
|
break;
|
||||||
|
@ -539,13 +532,33 @@ impl EventsLoop {
|
||||||
impl EventsLoopProxy {
|
impl EventsLoopProxy {
|
||||||
pub fn wakeup(&self) -> Result<(), EventsLoopClosed> {
|
pub fn wakeup(&self) -> Result<(), EventsLoopClosed> {
|
||||||
// Update the `EventsLoop`'s `pending_wakeup` flag.
|
// Update the `EventsLoop`'s `pending_wakeup` flag.
|
||||||
match self.pending_wakeup.upgrade() {
|
let display = match (self.pending_wakeup.upgrade(), self.display.upgrade()) {
|
||||||
Some(wakeup) => Ok(wakeup.store(true, atomic::Ordering::Relaxed)),
|
(Some(wakeup), Some(display)) => {
|
||||||
None => Err(EventsLoopClosed),
|
wakeup.store(true, atomic::Ordering::Relaxed);
|
||||||
|
display
|
||||||
|
},
|
||||||
|
_ => return Err(EventsLoopClosed),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Push an event on the X event queue so that methods like run_forever will advance.
|
||||||
|
let mut xev = ffi::XClientMessageEvent {
|
||||||
|
type_: ffi::ClientMessage,
|
||||||
|
window: self.root,
|
||||||
|
format: 32,
|
||||||
|
message_type: 0,
|
||||||
|
serial: 0,
|
||||||
|
send_event: 0,
|
||||||
|
display: display.display,
|
||||||
|
data: unsafe { mem::zeroed() },
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
(display.xlib.XSendEvent)(display.display, self.root, 0, 0, mem::transmute(&mut xev));
|
||||||
|
(display.xlib.XFlush)(display.display);
|
||||||
|
display.check_errors().expect("Failed to call XSendEvent after wakeup");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
Ok(())
|
||||||
// Cause the `EventsLoop` to break if it is currently blocked.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue