mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-25 06:41:31 +11:00
Wayland: Fix panic when calling set_cursor_grab from a different thread than evlp's one. (#1206)
This commit also start following X11 behavior on cursor icon update when
cursor is invisible.
Fixes regression introdced in 5ced36e319
This commit is contained in:
parent
34dce8069f
commit
765225d918
|
@ -132,12 +132,13 @@ impl CursorManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_cursor_icon(&mut self, cursor: CursorIcon) {
|
pub fn set_cursor_icon(&mut self, cursor: CursorIcon) {
|
||||||
if self.cursor_visible && cursor != self.current_cursor {
|
if cursor != self.current_cursor {
|
||||||
self.current_cursor = cursor;
|
self.current_cursor = cursor;
|
||||||
|
if self.cursor_visible {
|
||||||
self.set_cursor_icon_impl(cursor);
|
self.set_cursor_icon_impl(cursor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn set_cursor_icon_impl(&mut self, cursor: CursorIcon) {
|
fn set_cursor_icon_impl(&mut self, cursor: CursorIcon) {
|
||||||
let cursor = match cursor {
|
let cursor = match cursor {
|
||||||
|
@ -191,7 +192,11 @@ impl CursorManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn grab_pointer(&mut self, surface: Option<&WlSurface>) {
|
// This function can only be called from a thread on which `pointer_constraints_proxy` event
|
||||||
|
// queue is located, so calling it directly from a Window doesn't work well, in case
|
||||||
|
// you've sent your window to another thread, so we need to pass cursor grab updates to
|
||||||
|
// the event loop and call this function from there.
|
||||||
|
fn grab_pointer(&mut self, surface: Option<&WlSurface>) {
|
||||||
for locked_pointer in self.locked_pointers.drain(..) {
|
for locked_pointer in self.locked_pointers.drain(..) {
|
||||||
locked_pointer.destroy();
|
locked_pointer.destroy();
|
||||||
}
|
}
|
||||||
|
@ -230,6 +235,8 @@ pub struct EventLoop<T: 'static> {
|
||||||
// Our sink, shared with some handlers, buffering the events
|
// Our sink, shared with some handlers, buffering the events
|
||||||
sink: Arc<Mutex<WindowEventsSink<T>>>,
|
sink: Arc<Mutex<WindowEventsSink<T>>>,
|
||||||
pending_user_events: Rc<RefCell<VecDeque<T>>>,
|
pending_user_events: Rc<RefCell<VecDeque<T>>>,
|
||||||
|
// The cursor manager
|
||||||
|
cursor_manager: Arc<Mutex<CursorManager>>,
|
||||||
// Utility for grabbing the cursor and changing visibility
|
// Utility for grabbing the cursor and changing visibility
|
||||||
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
|
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
|
||||||
user_sender: ::calloop::channel::Sender<T>,
|
user_sender: ::calloop::channel::Sender<T>,
|
||||||
|
@ -416,6 +423,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
outputs: env.outputs.clone(),
|
outputs: env.outputs.clone(),
|
||||||
_user_source: user_source,
|
_user_source: user_source,
|
||||||
user_sender,
|
user_sender,
|
||||||
|
cursor_manager,
|
||||||
_kbd_source: kbd_source,
|
_kbd_source: kbd_source,
|
||||||
window_target: RootELW {
|
window_target: RootELW {
|
||||||
p: crate::platform_impl::EventLoopWindowTarget::Wayland(EventLoopWindowTarget {
|
p: crate::platform_impl::EventLoopWindowTarget::Wayland(EventLoopWindowTarget {
|
||||||
|
@ -654,7 +662,16 @@ impl<T> EventLoop<T> {
|
||||||
}
|
}
|
||||||
// process pending resize/refresh
|
// process pending resize/refresh
|
||||||
window_target.store.lock().unwrap().for_each(
|
window_target.store.lock().unwrap().for_each(
|
||||||
|newsize, size, new_dpi, refresh, frame_refresh, closed, wid, frame| {
|
|newsize,
|
||||||
|
size,
|
||||||
|
new_dpi,
|
||||||
|
refresh,
|
||||||
|
frame_refresh,
|
||||||
|
closed,
|
||||||
|
grab_cursor,
|
||||||
|
surface,
|
||||||
|
wid,
|
||||||
|
frame| {
|
||||||
if let Some(frame) = frame {
|
if let Some(frame) = frame {
|
||||||
if let Some((w, h)) = newsize {
|
if let Some((w, h)) = newsize {
|
||||||
frame.resize(w, h);
|
frame.resize(w, h);
|
||||||
|
@ -684,6 +701,11 @@ impl<T> EventLoop<T> {
|
||||||
if closed {
|
if closed {
|
||||||
sink.send_window_event(crate::event::WindowEvent::CloseRequested, wid);
|
sink.send_window_event(crate::event::WindowEvent::CloseRequested, wid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(grab_cursor) = grab_cursor {
|
||||||
|
let surface = if grab_cursor { Some(surface) } else { None };
|
||||||
|
self.cursor_manager.lock().unwrap().grab_pointer(surface);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ pub struct Window {
|
||||||
need_frame_refresh: Arc<Mutex<bool>>,
|
need_frame_refresh: Arc<Mutex<bool>>,
|
||||||
need_refresh: Arc<Mutex<bool>>,
|
need_refresh: Arc<Mutex<bool>>,
|
||||||
fullscreen: Arc<Mutex<bool>>,
|
fullscreen: Arc<Mutex<bool>>,
|
||||||
|
cursor_grab_changed: Arc<Mutex<Option<bool>>>, // Update grab state
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -143,6 +144,7 @@ impl Window {
|
||||||
let need_frame_refresh = Arc::new(Mutex::new(true));
|
let need_frame_refresh = Arc::new(Mutex::new(true));
|
||||||
let frame = Arc::new(Mutex::new(frame));
|
let frame = Arc::new(Mutex::new(frame));
|
||||||
let need_refresh = Arc::new(Mutex::new(true));
|
let need_refresh = Arc::new(Mutex::new(true));
|
||||||
|
let cursor_grab_changed = Arc::new(Mutex::new(None));
|
||||||
|
|
||||||
evlp.store.lock().unwrap().windows.push(InternalWindow {
|
evlp.store.lock().unwrap().windows.push(InternalWindow {
|
||||||
closed: false,
|
closed: false,
|
||||||
|
@ -150,6 +152,7 @@ impl Window {
|
||||||
size: size.clone(),
|
size: size.clone(),
|
||||||
need_refresh: need_refresh.clone(),
|
need_refresh: need_refresh.clone(),
|
||||||
fullscreen: fullscreen.clone(),
|
fullscreen: fullscreen.clone(),
|
||||||
|
cursor_grab_changed: cursor_grab_changed.clone(),
|
||||||
need_frame_refresh: need_frame_refresh.clone(),
|
need_frame_refresh: need_frame_refresh.clone(),
|
||||||
surface: surface.clone(),
|
surface: surface.clone(),
|
||||||
kill_switch: kill_switch.clone(),
|
kill_switch: kill_switch.clone(),
|
||||||
|
@ -170,6 +173,7 @@ impl Window {
|
||||||
need_refresh,
|
need_refresh,
|
||||||
cursor_manager,
|
cursor_manager,
|
||||||
fullscreen,
|
fullscreen,
|
||||||
|
cursor_grab_changed,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,12 +313,7 @@ impl Window {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
|
||||||
let mut cursor_manager = self.cursor_manager.lock().unwrap();
|
*self.cursor_grab_changed.lock().unwrap() = Some(grab);
|
||||||
if grab {
|
|
||||||
cursor_manager.grab_pointer(Some(&self.surface));
|
|
||||||
} else {
|
|
||||||
cursor_manager.grab_pointer(None);
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -374,6 +373,7 @@ struct InternalWindow {
|
||||||
need_refresh: Arc<Mutex<bool>>,
|
need_refresh: Arc<Mutex<bool>>,
|
||||||
fullscreen: Arc<Mutex<bool>>,
|
fullscreen: Arc<Mutex<bool>>,
|
||||||
need_frame_refresh: Arc<Mutex<bool>>,
|
need_frame_refresh: Arc<Mutex<bool>>,
|
||||||
|
cursor_grab_changed: Arc<Mutex<Option<bool>>>,
|
||||||
closed: bool,
|
closed: bool,
|
||||||
kill_switch: Arc<Mutex<bool>>,
|
kill_switch: Arc<Mutex<bool>>,
|
||||||
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
|
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
|
||||||
|
@ -441,6 +441,8 @@ impl WindowStore {
|
||||||
bool,
|
bool,
|
||||||
bool,
|
bool,
|
||||||
bool,
|
bool,
|
||||||
|
Option<bool>,
|
||||||
|
&wl_surface::WlSurface,
|
||||||
WindowId,
|
WindowId,
|
||||||
Option<&mut SWindow<ConceptFrame>>,
|
Option<&mut SWindow<ConceptFrame>>,
|
||||||
),
|
),
|
||||||
|
@ -455,6 +457,8 @@ impl WindowStore {
|
||||||
replace(&mut *window.need_refresh.lock().unwrap(), false),
|
replace(&mut *window.need_refresh.lock().unwrap(), false),
|
||||||
replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
|
replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
|
||||||
window.closed,
|
window.closed,
|
||||||
|
window.cursor_grab_changed.lock().unwrap().take(),
|
||||||
|
&window.surface,
|
||||||
make_wid(&window.surface),
|
make_wid(&window.surface),
|
||||||
opt_mutex_lock.as_mut().map(|m| &mut **m),
|
opt_mutex_lock.as_mut().map(|m| &mut **m),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue