Skip to content

Commit

Permalink
Wayland: Fix panic when calling set_cursor_grab from a different thre…
Browse files Browse the repository at this point in the history
…ad than evlp's one.

This commit also start following X11 behavior on cursor icon update when
cursor is invisible.

Fixes regression introdced in 5ced36e
  • Loading branch information
kchibisov committed Oct 14, 2019
1 parent 34dce80 commit 6ac885c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
32 changes: 27 additions & 5 deletions src/platform_impl/linux/wayland/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,11 @@ impl CursorManager {
}

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.set_cursor_icon_impl(cursor);
if self.cursor_visible {
self.set_cursor_icon_impl(cursor);
}
}
}

Expand Down Expand Up @@ -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(..) {
locked_pointer.destroy();
}
Expand Down Expand Up @@ -230,6 +235,8 @@ pub struct EventLoop<T: 'static> {
// Our sink, shared with some handlers, buffering the events
sink: Arc<Mutex<WindowEventsSink<T>>>,
pending_user_events: Rc<RefCell<VecDeque<T>>>,
// The cursor manager
cursor_manager: Arc<Mutex<CursorManager>>,
// Utility for grabbing the cursor and changing visibility
_user_source: ::calloop::Source<::calloop::channel::Channel<T>>,
user_sender: ::calloop::channel::Sender<T>,
Expand Down Expand Up @@ -416,6 +423,7 @@ impl<T: 'static> EventLoop<T> {
outputs: env.outputs.clone(),
_user_source: user_source,
user_sender,
cursor_manager,
_kbd_source: kbd_source,
window_target: RootELW {
p: crate::platform_impl::EventLoopWindowTarget::Wayland(EventLoopWindowTarget {
Expand Down Expand Up @@ -654,7 +662,16 @@ impl<T> EventLoop<T> {
}
// process pending resize/refresh
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((w, h)) = newsize {
frame.resize(w, h);
Expand Down Expand Up @@ -684,6 +701,11 @@ impl<T> EventLoop<T> {
if closed {
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);
}
},
)
}
Expand Down
16 changes: 10 additions & 6 deletions src/platform_impl/linux/wayland/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub struct Window {
need_frame_refresh: Arc<Mutex<bool>>,
need_refresh: Arc<Mutex<bool>>,
fullscreen: Arc<Mutex<bool>>,
cursor_grab_changed: Arc<Mutex<Option<bool>>>, // Update grab state
}

impl Window {
Expand Down Expand Up @@ -143,13 +144,15 @@ impl Window {
let need_frame_refresh = Arc::new(Mutex::new(true));
let frame = Arc::new(Mutex::new(frame));
let need_refresh = Arc::new(Mutex::new(true));
let cursor_grab_changed = Arc::new(Mutex::new(None));

evlp.store.lock().unwrap().windows.push(InternalWindow {
closed: false,
newsize: None,
size: size.clone(),
need_refresh: need_refresh.clone(),
fullscreen: fullscreen.clone(),
cursor_grab_changed: cursor_grab_changed.clone(),
need_frame_refresh: need_frame_refresh.clone(),
surface: surface.clone(),
kill_switch: kill_switch.clone(),
Expand All @@ -170,6 +173,7 @@ impl Window {
need_refresh,
cursor_manager,
fullscreen,
cursor_grab_changed,
})
}

Expand Down Expand Up @@ -309,12 +313,7 @@ impl Window {

#[inline]
pub fn set_cursor_grab(&self, grab: bool) -> Result<(), ExternalError> {
let mut cursor_manager = self.cursor_manager.lock().unwrap();
if grab {
cursor_manager.grab_pointer(Some(&self.surface));
} else {
cursor_manager.grab_pointer(None);
}
*self.cursor_grab_changed.lock().unwrap() = Some(grab);
Ok(())
}

Expand Down Expand Up @@ -374,6 +373,7 @@ struct InternalWindow {
need_refresh: Arc<Mutex<bool>>,
fullscreen: Arc<Mutex<bool>>,
need_frame_refresh: Arc<Mutex<bool>>,
cursor_grab_changed: Arc<Mutex<Option<bool>>>,
closed: bool,
kill_switch: Arc<Mutex<bool>>,
frame: Weak<Mutex<SWindow<ConceptFrame>>>,
Expand Down Expand Up @@ -441,6 +441,8 @@ impl WindowStore {
bool,
bool,
bool,
Option<bool>,
&wl_surface::WlSurface,
WindowId,
Option<&mut SWindow<ConceptFrame>>,
),
Expand All @@ -455,6 +457,8 @@ impl WindowStore {
replace(&mut *window.need_refresh.lock().unwrap(), false),
replace(&mut *window.need_frame_refresh.lock().unwrap(), false),
window.closed,
window.cursor_grab_changed.lock().unwrap().take(),
&window.surface,
make_wid(&window.surface),
opt_mutex_lock.as_mut().map(|m| &mut **m),
);
Expand Down

0 comments on commit 6ac885c

Please sign in to comment.