seat: Make render-related state thread-safe

This commit is contained in:
Victoria Brekenfeld 2024-06-07 19:26:23 +02:00 committed by Victoria Brekenfeld
parent bd58481d19
commit c7d50e7c5b
11 changed files with 137 additions and 112 deletions

View file

@ -24,7 +24,7 @@ use smithay::{
}, },
wayland::compositor::{get_role, with_states}, wayland::compositor::{get_role, with_states},
}; };
use std::{cell::RefCell, collections::HashMap, io::Read, sync::Mutex, time::Duration}; use std::{collections::HashMap, io::Read, sync::Mutex, time::Duration};
use tracing::warn; use tracing::warn;
use xcursor::{ use xcursor::{
parser::{parse_xcursor, Image}, parser::{parse_xcursor, Image},
@ -221,16 +221,17 @@ where
) )
} }
pub struct CursorState { pub type CursorState = Mutex<CursorStateInner>;
current_cursor: RefCell<CursorShape>, pub struct CursorStateInner {
current_cursor: CursorShape,
pub cursors: HashMap<CursorShape, Cursor>, pub cursors: HashMap<CursorShape, Cursor>,
current_image: RefCell<Option<Image>>, current_image: Option<Image>,
image_cache: RefCell<Vec<(Image, MemoryRenderBuffer)>>, //image_cache: Vec<(Image, MemoryRenderBuffer)>,
} }
impl CursorState { impl CursorStateInner {
pub fn set_shape(&self, shape: CursorShape) { pub fn set_shape(&mut self, shape: CursorShape) {
*self.current_cursor.borrow_mut() = shape; self.current_cursor = shape;
} }
} }
@ -245,11 +246,11 @@ pub fn load_cursor_theme() -> (CursorTheme, u32) {
(CursorTheme::load(&name), size) (CursorTheme::load(&name), size)
} }
impl Default for CursorState { impl Default for CursorStateInner {
fn default() -> CursorState { fn default() -> CursorStateInner {
let (theme, size) = load_cursor_theme(); let (theme, size) = load_cursor_theme();
CursorState { CursorStateInner {
current_cursor: RefCell::new(CursorShape::Default), current_cursor: CursorShape::Default,
cursors: { cursors: {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert( map.insert(
@ -302,8 +303,7 @@ impl Default for CursorState {
); );
map map
}, },
current_image: RefCell::new(None), current_image: None,
image_cache: RefCell::new(Vec::new()),
} }
} }
} }
@ -325,9 +325,9 @@ where
// reset the cursor if the surface is no longer alive // reset the cursor if the surface is no longer alive
let cursor_status = seat let cursor_status = seat
.user_data() .user_data()
.get::<RefCell<CursorImageStatus>>() .get::<Mutex<CursorImageStatus>>()
.map(|cell| { .map(|lock| {
let mut cursor_status = cell.borrow_mut(); let mut cursor_status = lock.lock().unwrap();
if let CursorImageStatus::Surface(ref surface) = *cursor_status { if let CursorImageStatus::Surface(ref surface) = *cursor_status {
if !surface.alive() { if !surface.alive() {
*cursor_status = CursorImageStatus::default_named(); *cursor_status = CursorImageStatus::default_named();
@ -344,26 +344,24 @@ where
let integer_scale = scale.x.max(scale.y).ceil() as u32; let integer_scale = scale.x.max(scale.y).ceil() as u32;
let seat_userdata = seat.user_data(); let seat_userdata = seat.user_data();
let state = seat_userdata.get::<CursorState>().unwrap(); let mut state = seat_userdata.get::<CursorState>().unwrap().lock().unwrap();
let frame = state let frame = state.cursors.get(&state.current_cursor).unwrap().get_image(
.cursors integer_scale,
.get(&*state.current_cursor.borrow()) Into::<Duration>::into(time).as_millis() as u32,
.unwrap() );
.get_image(
integer_scale,
Into::<Duration>::into(time).as_millis() as u32,
);
let mut pointer_images = state.image_cache.borrow_mut(); /*
let mut pointer_images = &mut state.image_cache;
let maybe_image = let maybe_image =
pointer_images pointer_images
.iter() .iter()
.find_map(|(image, texture)| if image == &frame { Some(texture) } else { None }); .find_map(|(image, texture)| if image == &frame { Some(texture) } else { None });
let pointer_image = match maybe_image { */
let pointer_image = /*match maybe_image {
Some(image) => image, Some(image) => image,
None => { None => {
let buffer = MemoryRenderBuffer::from_slice( let buffer =*/ MemoryRenderBuffer::from_slice(
&frame.pixels_rgba, &frame.pixels_rgba,
Fourcc::Argb8888, Fourcc::Argb8888,
(frame.width as i32, frame.height as i32), (frame.width as i32, frame.height as i32),
@ -371,20 +369,21 @@ where
Transform::Normal, Transform::Normal,
None, None,
); );
/*
pointer_images.push((frame.clone(), buffer)); pointer_images.push((frame.clone(), buffer));
pointer_images.last().map(|(_, i)| i).unwrap() pointer_images.last().map(|(_, i)| i).unwrap()
} }
}; };*/
let hotspot = Point::<i32, BufferCoords>::from((frame.xhot as i32, frame.yhot as i32)); let hotspot = Point::<i32, BufferCoords>::from((frame.xhot as i32, frame.yhot as i32));
*state.current_image.borrow_mut() = Some(frame); state.current_image = Some(frame);
return vec![( return vec![(
CursorRenderElement::Static( CursorRenderElement::Static(
MemoryRenderBufferRenderElement::from_buffer( MemoryRenderBufferRenderElement::from_buffer(
renderer, renderer,
location.to_physical(scale), location.to_physical(scale),
pointer_image, &pointer_image,
None, None,
None, None,
None, None,

View file

@ -58,6 +58,7 @@ use smithay::{
}, },
}, },
desktop::{layer_map_for_output, PopupManager}, desktop::{layer_map_for_output, PopupManager},
input::Seat,
output::{Output, OutputNoMode}, output::{Output, OutputNoMode},
utils::{IsAlive, Logical, Monotonic, Point, Rectangle, Scale, Time, Transform}, utils::{IsAlive, Logical, Monotonic, Point, Rectangle, Scale, Time, Transform},
wayland::{ wayland::{
@ -388,9 +389,9 @@ pub enum CursorMode {
} }
#[profiling::function] #[profiling::function]
pub fn cursor_elements<'frame, R>( pub fn cursor_elements<'a, 'frame, R>(
renderer: &mut R, renderer: &mut R,
shell: &Shell, seats: impl Iterator<Item = &'a Seat<State>>,
theme: &Theme, theme: &Theme,
now: Time<Monotonic>, now: Time<Monotonic>,
output: &Output, output: &Output,
@ -405,7 +406,7 @@ where
let scale = output.current_scale().fractional_scale(); let scale = output.current_scale().fractional_scale();
let mut elements = Vec::new(); let mut elements = Vec::new();
for seat in shell.seats.iter() { for seat in seats {
let pointer = match seat.get_pointer() { let pointer = match seat.get_pointer() {
Some(ptr) => ptr, Some(ptr) => ptr,
None => continue, None => continue,
@ -416,7 +417,7 @@ where
elements.extend( elements.extend(
cursor::draw_cursor( cursor::draw_cursor(
renderer, renderer,
seat, &seat,
location, location,
scale.into(), scale.into(),
now, now,
@ -434,7 +435,7 @@ where
} }
if !exclude_dnd_icon { if !exclude_dnd_icon {
if let Some(wl_surface) = get_dnd_icon(seat) { if let Some(wl_surface) = get_dnd_icon(&seat) {
elements.extend( elements.extend(
cursor::draw_dnd_icon(renderer, &wl_surface, location.to_i32_round(), scale) cursor::draw_dnd_icon(renderer, &wl_surface, location.to_i32_round(), scale)
.into_iter() .into_iter()
@ -448,7 +449,8 @@ where
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.unwrap() .unwrap()
.borrow() .lock()
.unwrap()
.as_ref() .as_ref()
.map(|state| state.render::<CosmicElement<R>, R>(renderer, output, theme)) .map(|state| state.render::<CosmicElement<R>, R>(renderer, output, theme))
{ {
@ -459,7 +461,8 @@ where
.user_data() .user_data()
.get::<SeatMenuGrabState>() .get::<SeatMenuGrabState>()
.unwrap() .unwrap()
.borrow() .lock()
.unwrap()
.as_ref() .as_ref()
.map(|state| state.render::<CosmicMappedRenderElement<R>, R>(renderer, output)) .map(|state| state.render::<CosmicMappedRenderElement<R>, R>(renderer, output))
{ {
@ -492,9 +495,15 @@ where
CosmicMappedRenderElement<R>: RenderElement<R>, CosmicMappedRenderElement<R>: RenderElement<R>,
WorkspaceRenderElement<R>: RenderElement<R>, WorkspaceRenderElement<R>: RenderElement<R>,
{ {
let seats = shell
.seats
.iter()
.cloned()
.collect::<Vec<_>>();
let mut elements = cursor_elements( let mut elements = cursor_elements(
renderer, renderer,
shell, seats.iter(),
theme, theme,
now, now,
output, output,
@ -556,13 +565,13 @@ where
overview.0, overview.0,
overview.1.map(|indicator| (indicator, swap_tree)), overview.1.map(|indicator| (indicator, swap_tree)),
); );
let last_active_seat = shell.seats.last_active(); let last_active_seat = shell.seats.last_active();
let move_active = last_active_seat let move_active = last_active_seat
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.unwrap() .unwrap()
.borrow() .lock()
.unwrap()
.is_some(); .is_some();
let active_output = last_active_seat.active_output(); let active_output = last_active_seat.active_output();
let output_size = output.geometry().size; let output_size = output.geometry().size;

View file

@ -1197,13 +1197,15 @@ impl PointerTarget<State> for CosmicStack {
}; };
let _old_focus = p.swap_focus(Some(next)); let _old_focus = p.swap_focus(Some(next));
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let mut cursor_state = seat
cursor_state.set_shape(next.cursor_shape());
let cursor_status = seat
.user_data() .user_data()
.get::<RefCell<CursorImageStatus>>() .get::<CursorState>()
.unwrap()
.lock()
.unwrap(); .unwrap();
*cursor_status.borrow_mut() = CursorImageStatus::default_named(); cursor_state.set_shape(next.cursor_shape());
let cursor_status = seat.user_data().get::<Mutex<CursorImageStatus>>().unwrap();
*cursor_status.lock().unwrap() = CursorImageStatus::default_named();
}); });
event.location -= self.0.with_program(|p| { event.location -= self.0.with_program(|p| {
@ -1225,13 +1227,15 @@ impl PointerTarget<State> for CosmicStack {
}; };
let _previous = p.swap_focus(Some(next)); let _previous = p.swap_focus(Some(next));
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let mut cursor_state = seat
cursor_state.set_shape(next.cursor_shape());
let cursor_status = seat
.user_data() .user_data()
.get::<RefCell<CursorImageStatus>>() .get::<CursorState>()
.unwrap()
.lock()
.unwrap(); .unwrap();
*cursor_status.borrow_mut() = CursorImageStatus::default_named(); cursor_state.set_shape(next.cursor_shape());
let cursor_status = seat.user_data().get::<Mutex<CursorImageStatus>>().unwrap();
*cursor_status.lock().unwrap() = CursorImageStatus::default_named();
}); });
let active_window_geo = self.0.with_program(|p| { let active_window_geo = self.0.with_program(|p| {
@ -1322,7 +1326,12 @@ impl PointerTarget<State> for CosmicStack {
fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) { fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) {
self.0.with_program(|p| { self.0.with_program(|p| {
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let mut cursor_state = seat
.user_data()
.get::<CursorState>()
.unwrap()
.lock()
.unwrap();
cursor_state.set_shape(CursorShape::Default); cursor_state.set_shape(CursorShape::Default);
let _previous = p.swap_focus(None); let _previous = p.swap_focus(None);
}); });

View file

@ -46,7 +46,6 @@ use smithay::{
}; };
use std::{ use std::{
borrow::Cow, borrow::Cow,
cell::RefCell,
fmt, fmt,
hash::Hash, hash::Hash,
sync::{ sync::{
@ -686,12 +685,9 @@ impl PointerTarget<State> for CosmicWindow {
assert_eq!(old_focus, None); assert_eq!(old_focus, None);
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let cursor_state = seat.user_data().get::<CursorState>().unwrap();
cursor_state.set_shape(next.cursor_shape()); cursor_state.lock().unwrap().set_shape(next.cursor_shape());
let cursor_status = seat let cursor_status = seat.user_data().get::<Mutex<CursorImageStatus>>().unwrap();
.user_data() *cursor_status.lock().unwrap() = CursorImageStatus::default_named();
.get::<RefCell<CursorImageStatus>>()
.unwrap();
*cursor_status.borrow_mut() = CursorImageStatus::default_named();
} }
}); });
@ -709,12 +705,9 @@ impl PointerTarget<State> for CosmicWindow {
let _previous = p.swap_focus(Some(next)); let _previous = p.swap_focus(Some(next));
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let cursor_state = seat.user_data().get::<CursorState>().unwrap();
cursor_state.set_shape(next.cursor_shape()); cursor_state.lock().unwrap().set_shape(next.cursor_shape());
let cursor_status = seat let cursor_status = seat.user_data().get::<Mutex<CursorImageStatus>>().unwrap();
.user_data() *cursor_status.lock().unwrap() = CursorImageStatus::default_named();
.get::<RefCell<CursorImageStatus>>()
.unwrap();
*cursor_status.borrow_mut() = CursorImageStatus::default_named();
} }
}); });
@ -794,7 +787,7 @@ impl PointerTarget<State> for CosmicWindow {
fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) { fn leave(&self, seat: &Seat<State>, data: &mut State, serial: Serial, time: u32) {
self.0.with_program(|p| { self.0.with_program(|p| {
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let cursor_state = seat.user_data().get::<CursorState>().unwrap();
cursor_state.set_shape(CursorShape::Default); cursor_state.lock().unwrap().set_shape(CursorShape::Default);
let _previous = p.swap_focus(None); let _previous = p.swap_focus(None);
}); });
PointerTarget::leave(&self.0, seat, data, serial, time) PointerTarget::leave(&self.0, seat, data, serial, time)

View file

@ -18,7 +18,7 @@ use smithay::{
shell::wlr_layer::{KeyboardInteractivity, Layer}, shell::wlr_layer::{KeyboardInteractivity, Layer},
}, },
}; };
use std::{borrow::Cow, cell::RefCell}; use std::{borrow::Cow, sync::Mutex};
use tracing::{debug, trace}; use tracing::{debug, trace};
use self::target::{KeyboardFocusTarget, WindowGroup}; use self::target::{KeyboardFocusTarget, WindowGroup};
@ -77,27 +77,28 @@ impl<'a> FocusStackMut<'a> {
} }
} }
pub struct ActiveFocus(RefCell<Option<KeyboardFocusTarget>>); pub struct ActiveFocus(Mutex<Option<KeyboardFocusTarget>>);
impl ActiveFocus { impl ActiveFocus {
fn set(seat: &Seat<State>, target: Option<KeyboardFocusTarget>) { fn set(seat: &Seat<State>, target: Option<KeyboardFocusTarget>) {
if !seat if !seat
.user_data() .user_data()
.insert_if_missing(|| ActiveFocus(RefCell::new(target.clone()))) .insert_if_missing_threadsafe(|| ActiveFocus(Mutex::new(target.clone())))
{ {
*seat *seat
.user_data() .user_data()
.get::<ActiveFocus>() .get::<ActiveFocus>()
.unwrap() .unwrap()
.0 .0
.borrow_mut() = target; .lock()
.unwrap() = target;
} }
} }
fn get(seat: &Seat<State>) -> Option<KeyboardFocusTarget> { fn get(seat: &Seat<State>) -> Option<KeyboardFocusTarget> {
seat.user_data() seat.user_data()
.get::<ActiveFocus>() .get::<ActiveFocus>()
.and_then(|a| a.0.borrow().clone()) .and_then(|a| a.0.lock().unwrap().clone())
} }
} }

View file

@ -1,9 +1,6 @@
use std::{ use std::sync::{
cell::RefCell, atomic::{AtomicBool, Ordering},
sync::{ Arc, Mutex,
atomic::{AtomicBool, Ordering},
Arc, Mutex,
},
}; };
use calloop::LoopHandle; use calloop::LoopHandle;
@ -57,7 +54,7 @@ pub use self::default::*;
pub struct MenuGrabState { pub struct MenuGrabState {
elements: Arc<Mutex<Vec<Element>>>, elements: Arc<Mutex<Vec<Element>>>,
} }
pub type SeatMenuGrabState = RefCell<Option<MenuGrabState>>; pub type SeatMenuGrabState = Mutex<Option<MenuGrabState>>;
impl MenuGrabState { impl MenuGrabState {
pub fn render<I, R>(&self, renderer: &mut R, output: &Output) -> Vec<I> pub fn render<I, R>(&self, renderer: &mut R, output: &Output) -> Vec<I>
@ -228,7 +225,8 @@ impl Program for ContextMenu {
.user_data() .user_data()
.get::<SeatMenuGrabState>() .get::<SeatMenuGrabState>()
.unwrap() .unwrap()
.borrow_mut(); .lock()
.unwrap();
if let Some(grab_state) = &*grab_state { if let Some(grab_state) = &*grab_state {
let mut elements = grab_state.elements.lock().unwrap(); let mut elements = grab_state.elements.lock().unwrap();
@ -320,7 +318,8 @@ impl Program for ContextMenu {
.user_data() .user_data()
.get::<SeatMenuGrabState>() .get::<SeatMenuGrabState>()
.unwrap() .unwrap()
.borrow_mut(); .lock()
.unwrap();
if let Some(grab_state) = &*grab_state { if let Some(grab_state) = &*grab_state {
let mut elements = grab_state.elements.lock().unwrap(); let mut elements = grab_state.elements.lock().unwrap();
@ -713,7 +712,8 @@ impl MenuGrab {
.user_data() .user_data()
.get::<SeatMenuGrabState>() .get::<SeatMenuGrabState>()
.unwrap() .unwrap()
.borrow_mut() = Some(grab_state); .lock()
.unwrap() = Some(grab_state);
MenuGrab { MenuGrab {
elements, elements,
@ -729,7 +729,8 @@ impl Drop for MenuGrab {
.user_data() .user_data()
.get::<SeatMenuGrabState>() .get::<SeatMenuGrabState>()
.unwrap() .unwrap()
.borrow_mut() .lock()
.unwrap()
.take(); .take();
} }
} }

View file

@ -44,11 +44,15 @@ use smithay::{
output::Output, output::Output,
utils::{IsAlive, Logical, Point, Rectangle, Scale, Serial, SERIAL_COUNTER}, utils::{IsAlive, Logical, Point, Rectangle, Scale, Serial, SERIAL_COUNTER},
}; };
use std::{cell::RefCell, collections::HashSet, sync::atomic::Ordering, time::Instant}; use std::{
collections::HashSet,
sync::{atomic::Ordering, Mutex},
time::Instant,
};
use super::{GrabStartData, ReleaseMode}; use super::{GrabStartData, ReleaseMode};
pub type SeatMoveGrabState = RefCell<Option<MoveGrabState>>; pub type SeatMoveGrabState = Mutex<Option<MoveGrabState>>;
const RESCALE_ANIMATION_DURATION: f64 = 150.0; const RESCALE_ANIMATION_DURATION: f64 = 150.0;
@ -363,7 +367,7 @@ impl MoveGrab {
.seat .seat
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.map(|s| s.borrow_mut()); .map(|s| s.lock().unwrap());
if let Some(grab_state) = borrow.as_mut().and_then(|s| s.as_mut()) { if let Some(grab_state) = borrow.as_mut().and_then(|s| s.as_mut()) {
grab_state.location = location; grab_state.location = location;
grab_state.cursor_output = self.cursor_output.clone(); grab_state.cursor_output = self.cursor_output.clone();
@ -698,11 +702,12 @@ impl MoveGrab {
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.unwrap() .unwrap()
.borrow_mut() = Some(grab_state); .lock()
.unwrap() = Some(grab_state);
{ {
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let cursor_state = seat.user_data().get::<CursorState>().unwrap();
cursor_state.set_shape(CursorShape::Grab); cursor_state.lock().unwrap().set_shape(CursorShape::Grab);
} }
MoveGrab { MoveGrab {
@ -743,7 +748,7 @@ impl Drop for MoveGrab {
let position: Option<(CosmicMapped, Point<i32, Global>)> = if let Some(grab_state) = let position: Option<(CosmicMapped, Point<i32, Global>)> = if let Some(grab_state) =
seat.user_data() seat.user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.and_then(|s| s.borrow_mut().take()) .and_then(|s| s.lock().unwrap().take())
{ {
if grab_state.window.alive() { if grab_state.window.alive() {
let window_location = let window_location =
@ -842,7 +847,7 @@ impl Drop for MoveGrab {
{ {
let cursor_state = seat.user_data().get::<CursorState>().unwrap(); let cursor_state = seat.user_data().get::<CursorState>().unwrap();
cursor_state.set_shape(CursorShape::Default); cursor_state.lock().unwrap().set_shape(CursorShape::Default);
} }
if let Some((mapped, position)) = position { if let Some((mapped, position)) = position {

View file

@ -50,10 +50,13 @@ impl PointerTarget<State> for ResizeForkTarget {
fn enter(&self, seat: &Seat<State>, _data: &mut State, _event: &MotionEvent) { fn enter(&self, seat: &Seat<State>, _data: &mut State, _event: &MotionEvent) {
let user_data = seat.user_data(); let user_data = seat.user_data();
let cursor_state = user_data.get::<CursorState>().unwrap(); let cursor_state = user_data.get::<CursorState>().unwrap();
cursor_state.set_shape(match self.orientation { cursor_state
Orientation::Horizontal => CursorShape::RowResize, .lock()
Orientation::Vertical => CursorShape::ColResize, .unwrap()
}); .set_shape(match self.orientation {
Orientation::Horizontal => CursorShape::RowResize,
Orientation::Vertical => CursorShape::ColResize,
});
} }
fn leave( fn leave(
@ -65,7 +68,7 @@ impl PointerTarget<State> for ResizeForkTarget {
) { ) {
let user_data = seat.user_data(); let user_data = seat.user_data();
let cursor_state = user_data.get::<CursorState>().unwrap(); let cursor_state = user_data.get::<CursorState>().unwrap();
cursor_state.set_shape(CursorShape::Default) cursor_state.lock().unwrap().set_shape(CursorShape::Default)
} }
fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) { fn button(&self, seat: &Seat<State>, data: &mut State, event: &ButtonEvent) {

View file

@ -155,7 +155,7 @@ impl Drop for SeatId {
#[repr(transparent)] #[repr(transparent)]
struct SeatId(pub usize); struct SeatId(pub usize);
struct ActiveOutput(pub RefCell<Output>); struct ActiveOutput(pub Mutex<Output>);
pub fn create_seat( pub fn create_seat(
dh: &DisplayHandle, dh: &DisplayHandle,
@ -166,15 +166,15 @@ pub fn create_seat(
) -> Seat<State> { ) -> Seat<State> {
let mut seat = seat_state.new_wl_seat(dh, name); let mut seat = seat_state.new_wl_seat(dh, name);
let userdata = seat.user_data(); let userdata = seat.user_data();
userdata.insert_if_missing(SeatId::default); userdata.insert_if_missing_threadsafe(SeatId::default);
userdata.insert_if_missing(Devices::default); userdata.insert_if_missing(Devices::default);
userdata.insert_if_missing(SupressedKeys::default); userdata.insert_if_missing(SupressedKeys::default);
userdata.insert_if_missing(ModifiersShortcutQueue::default); userdata.insert_if_missing(ModifiersShortcutQueue::default);
userdata.insert_if_missing(SeatMoveGrabState::default); userdata.insert_if_missing_threadsafe(SeatMoveGrabState::default);
userdata.insert_if_missing(SeatMenuGrabState::default); userdata.insert_if_missing_threadsafe(SeatMenuGrabState::default);
userdata.insert_if_missing(CursorState::default); userdata.insert_if_missing_threadsafe(CursorState::default);
userdata.insert_if_missing(|| ActiveOutput(RefCell::new(output.clone()))); userdata.insert_if_missing_threadsafe(|| ActiveOutput(Mutex::new(output.clone())));
userdata.insert_if_missing(|| RefCell::new(CursorImageStatus::default_named())); userdata.insert_if_missing_threadsafe(|| Mutex::new(CursorImageStatus::default_named()));
// A lot of clients bind keyboard and pointer unconditionally once on launch.. // A lot of clients bind keyboard and pointer unconditionally once on launch..
// Initial clients might race the compositor on adding periheral and // Initial clients might race the compositor on adding periheral and
@ -232,7 +232,7 @@ impl SeatExt for Seat<State> {
fn active_output(&self) -> Output { fn active_output(&self) -> Output {
self.user_data() self.user_data()
.get::<ActiveOutput>() .get::<ActiveOutput>()
.map(|x| x.0.borrow().clone()) .map(|x| x.0.lock().unwrap().clone())
.unwrap() .unwrap()
} }
@ -242,7 +242,8 @@ impl SeatExt for Seat<State> {
.get::<ActiveOutput>() .get::<ActiveOutput>()
.unwrap() .unwrap()
.0 .0
.borrow_mut() = output.clone(); .lock()
.unwrap() = output.clone();
} }
fn devices(&self) -> &Devices { fn devices(&self) -> &Devices {
@ -266,9 +267,9 @@ impl SeatExt for Seat<State> {
let cursor_status = self let cursor_status = self
.user_data() .user_data()
.get::<RefCell<CursorImageStatus>>() .get::<Mutex<CursorImageStatus>>()
.map(|cell| { .map(|lock| {
let mut cursor_status = cell.borrow_mut(); let mut cursor_status = lock.lock().unwrap();
if let CursorImageStatus::Surface(ref surface) = *cursor_status { if let CursorImageStatus::Surface(ref surface) = *cursor_status {
if !surface.alive() { if !surface.alive() {
*cursor_status = CursorImageStatus::default_named(); *cursor_status = CursorImageStatus::default_named();
@ -298,9 +299,11 @@ impl SeatExt for Seat<State> {
} }
CursorImageStatus::Named(CursorIcon::Default) => { CursorImageStatus::Named(CursorIcon::Default) => {
let seat_userdata = self.user_data(); let seat_userdata = self.user_data();
seat_userdata.insert_if_missing(CursorState::default); seat_userdata.insert_if_missing_threadsafe(CursorState::default);
let state = seat_userdata.get::<CursorState>().unwrap(); let state = seat_userdata.get::<CursorState>().unwrap();
let frame = state let frame = state
.lock()
.unwrap()
.cursors .cursors
.get(&CursorShape::Default) .get(&CursorShape::Default)
.unwrap() .unwrap()

View file

@ -172,7 +172,8 @@ impl CompositorHandler for State {
.user_data() .user_data()
.get::<SeatMoveGrabState>() .get::<SeatMoveGrabState>()
.unwrap() .unwrap()
.borrow() .lock()
.unwrap()
.as_ref() .as_ref()
.and_then(|state| { .and_then(|state| {
state state

View file

@ -9,7 +9,7 @@ use smithay::{
delegate_seat, delegate_seat,
input::{keyboard::LedState, pointer::CursorImageStatus, SeatHandler, SeatState}, input::{keyboard::LedState, pointer::CursorImageStatus, SeatHandler, SeatState},
}; };
use std::cell::RefCell; use std::sync::Mutex;
impl SeatHandler for State { impl SeatHandler for State {
type KeyboardFocus = KeyboardFocusTarget; type KeyboardFocus = KeyboardFocusTarget;
@ -27,9 +27,10 @@ impl SeatHandler for State {
) { ) {
*seat *seat
.user_data() .user_data()
.get::<RefCell<CursorImageStatus>>() .get::<Mutex<CursorImageStatus>>()
.unwrap() .unwrap()
.borrow_mut() = image; .lock()
.unwrap() = image;
} }
fn focus_changed( fn focus_changed(