anvil: remove several Rc and RefCell

This commit is contained in:
Victor Berger 2021-05-31 21:06:58 +02:00 committed by Victor Berger
parent 85440840c8
commit 327321612d
5 changed files with 68 additions and 103 deletions

View File

@ -14,6 +14,9 @@ use smithay::{
}, },
}; };
#[cfg(feature = "udev")]
use smithay::backend::session::Session;
impl<Backend> AnvilState<Backend> { impl<Backend> AnvilState<Backend> {
fn keyboard_key_to_action<B: InputBackend>(&mut self, evt: B::KeyboardKeyEvent) -> KeyAction { fn keyboard_key_to_action<B: InputBackend>(&mut self, evt: B::KeyboardKeyEvent) -> KeyAction {
let keycode = evt.key_code(); let keycode = evt.key_code();
@ -40,48 +43,6 @@ impl<Backend> AnvilState<Backend> {
return KeyAction::None; return KeyAction::None;
} }
return action; return action;
/*
match action {
KeyAction::Quit => {
info!(self.log, "Quitting.");
self.running.store(false, Ordering::SeqCst);
}
#[cfg(feature = "udev")]
KeyAction::VtSwitch(vt) => {
if let Some(ref mut session) = self.session {
info!(log, "Trying to switch to vt {}", vt);
if let Err(err) = session.change_vt(vt) {
error!(log, "Error switching to vt {}: {}", vt, err);
}
}
}
KeyAction::Run(cmd) => {
info!(self.log, "Starting program"; "cmd" => cmd.clone());
if let Err(e) = Command::new(&cmd).spawn() {
error!(log,
"Failed to start program";
"cmd" => cmd,
"err" => format!("{:?}", e)
);
}
}
#[cfg(feature = "udev")]
KeyAction::Screen(num) => {
let output_map = self.output_map.as_ref().unwrap();
let outputs = output_map.borrow();
if let Some(output) = outputs.get(num) {
let x = outputs
.iter()
.take(num)
.fold(0, |acc, output| acc + output.size.0) as f64
+ (output.size.0 as f64 / 2.0);
let y = output.size.1 as f64 / 2.0;
*self.pointer_location.borrow_mut() = (x as f64, y as f64)
}
}
_ => (),
}
*/
} }
fn on_pointer_button<B: InputBackend>(&mut self, evt: B::PointerButtonEvent) { fn on_pointer_button<B: InputBackend>(&mut self, evt: B::PointerButtonEvent) {
@ -99,7 +60,7 @@ impl<Backend> AnvilState<Backend> {
let under = self let under = self
.window_map .window_map
.borrow_mut() .borrow_mut()
.get_surface_and_bring_to_top(*self.pointer_location.borrow()); .get_surface_and_bring_to_top(self.pointer_location);
self.keyboard self.keyboard
.set_focus(under.as_ref().map(|&(ref s, _)| s), serial); .set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
} }
@ -153,7 +114,7 @@ impl AnvilState<WinitData> {
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) { pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
match event { match event {
InputEvent::Keyboard { event, .. } => match self.keyboard_key_to_action::<B>(event) { InputEvent::Keyboard { event, .. } => match self.keyboard_key_to_action::<B>(event) {
KeyAction::None => {} KeyAction::None | KeyAction::Forward => {}
KeyAction::Quit => { KeyAction::Quit => {
info!(self.log, "Quitting."); info!(self.log, "Quitting.");
self.running.store(false, Ordering::SeqCst); self.running.store(false, Ordering::SeqCst);
@ -184,7 +145,7 @@ impl AnvilState<WinitData> {
fn on_pointer_move_absolute<B: InputBackend>(&mut self, evt: B::PointerMotionAbsoluteEvent) { fn on_pointer_move_absolute<B: InputBackend>(&mut self, evt: B::PointerMotionAbsoluteEvent) {
// different cases depending on the context: // different cases depending on the context:
let (x, y) = evt.position(); let (x, y) = evt.position();
*self.pointer_location.borrow_mut() = (x, y); self.pointer_location = (x, y);
let serial = SCOUNTER.next_serial(); let serial = SCOUNTER.next_serial();
let under = self.window_map.borrow().get_surface_under((x as f64, y as f64)); let under = self.window_map.borrow().get_surface_under((x as f64, y as f64));
self.pointer.motion((x, y), under, serial, evt.time()); self.pointer.motion((x, y), under, serial, evt.time());
@ -196,11 +157,18 @@ impl AnvilState<UdevData> {
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) { pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
match event { match event {
InputEvent::Keyboard { event, .. } => match self.keyboard_key_to_action::<B>(event) { InputEvent::Keyboard { event, .. } => match self.keyboard_key_to_action::<B>(event) {
KeyAction::None => {} KeyAction::None | KeyAction::Forward => {}
KeyAction::Quit => { KeyAction::Quit => {
info!(self.log, "Quitting."); info!(self.log, "Quitting.");
self.running.store(false, Ordering::SeqCst); self.running.store(false, Ordering::SeqCst);
} }
#[cfg(feature = "udev")]
KeyAction::VtSwitch(vt) => {
info!(self.log, "Trying to switch to vt {}", vt);
if let Err(err) = self.backend_data.session.change_vt(vt) {
error!(self.log, "Error switching to vt {}: {}", vt, err);
}
}
KeyAction::Run(cmd) => { KeyAction::Run(cmd) => {
info!(self.log, "Starting program"; "cmd" => cmd.clone()); info!(self.log, "Starting program"; "cmd" => cmd.clone());
if let Err(e) = Command::new(&cmd).spawn() { if let Err(e) = Command::new(&cmd).spawn() {
@ -211,8 +179,19 @@ impl AnvilState<UdevData> {
); );
} }
} }
action => { KeyAction::Screen(num) => {
warn!(self.log, "Key action {:?} unsupported on winit backend.", action); if let Some(output) = self.backend_data.output_map.get(num) {
let x = self
.backend_data
.output_map
.iter()
.take(num)
.fold(0, |acc, output| acc + output.size.0)
as f64
+ (output.size.0 as f64 / 2.0);
let y = output.size.1 as f64 / 2.0;
self.pointer_location = (x as f64, y as f64)
}
} }
}, },
InputEvent::PointerMotion { event, .. } => self.on_pointer_move::<B>(event), InputEvent::PointerMotion { event, .. } => self.on_pointer_move::<B>(event),
@ -227,31 +206,30 @@ impl AnvilState<UdevData> {
fn on_pointer_move<B: InputBackend>(&mut self, evt: B::PointerMotionEvent) { fn on_pointer_move<B: InputBackend>(&mut self, evt: B::PointerMotionEvent) {
let (x, y) = (evt.delta_x(), evt.delta_y()); let (x, y) = (evt.delta_x(), evt.delta_y());
let serial = SCOUNTER.next_serial(); let serial = SCOUNTER.next_serial();
let mut location = self.pointer_location.borrow_mut(); self.pointer_location.0 += x as f64;
location.0 += x as f64; self.pointer_location.1 += y as f64;
location.1 += y as f64;
// clamp to screen limits // clamp to screen limits
// this event is never generated by winit // this event is never generated by winit
*location = self.clamp_coords(*location); self.pointer_location = self.clamp_coords(self.pointer_location);
let under = self let under = self.window_map.borrow().get_surface_under(self.pointer_location);
.window_map self.pointer
.borrow() .motion(self.pointer_location, under, serial, evt.time());
.get_surface_under((location.0, location.1));
self.pointer.motion(*location, under, serial, evt.time());
} }
fn clamp_coords(&self, pos: (f64, f64)) -> (f64, f64) { fn clamp_coords(&self, pos: (f64, f64)) -> (f64, f64) {
let outputs = self.backend_data.output_map.borrow(); if self.backend_data.output_map.len() == 0 {
if outputs.len() == 0 {
return pos; return pos;
} }
let (mut x, mut y) = pos; let (mut x, mut y) = pos;
// max_x is the sum of the width of all outputs // max_x is the sum of the width of all outputs
let max_x = outputs.iter().fold(0u32, |acc, output| acc + output.size.0); let max_x = self
.backend_data
.output_map
.iter()
.fold(0u32, |acc, output| acc + output.size.0);
x = x.max(0.0).min(max_x as f64); x = x.max(0.0).min(max_x as f64);
// max y depends on the current output // max y depends on the current output
@ -262,9 +240,8 @@ impl AnvilState<UdevData> {
} }
fn current_output_idx(&self, x: f64) -> usize { fn current_output_idx(&self, x: f64) -> usize {
let outputs = self.backend_data.output_map.borrow(); self.backend_data
.output_map
outputs
.iter() .iter()
// map each output to their x position // map each output to their x position
.scan(0u32, |acc, output| { .scan(0u32, |acc, output| {
@ -278,12 +255,11 @@ impl AnvilState<UdevData> {
.find(|(_idx, x_pos)| *x_pos as f64 > x) .find(|(_idx, x_pos)| *x_pos as f64 > x)
// the previous output is the one we are on // the previous output is the one we are on
.map(|(idx, _)| idx - 1) .map(|(idx, _)| idx - 1)
.unwrap_or(outputs.len() - 1) .unwrap_or(self.backend_data.output_map.len() - 1)
} }
fn current_output_size(&self, x: f64) -> (u32, u32) { fn current_output_size(&self, x: f64) -> (u32, u32) {
let outputs = self.backend_data.output_map.borrow(); self.backend_data.output_map[self.current_output_idx(x)].size
outputs[self.current_output_idx(x)].size
} }
} }

View File

@ -311,11 +311,7 @@ pub struct ShellHandles {
pub window_map: Rc<RefCell<MyWindowMap>>, pub window_map: Rc<RefCell<MyWindowMap>>,
} }
pub fn init_shell<Backend: 'static>( pub fn init_shell<Backend: 'static>(display: &mut Display, log: ::slog::Logger) -> ShellHandles {
display: &mut Display,
#[cfg(feature = "egl")] egl_reader: Rc<RefCell<Option<EGLBufferReader>>>,
log: ::slog::Logger,
) -> ShellHandles {
// Create the compositor // Create the compositor
let (compositor_token, _, _) = compositor_init( let (compositor_token, _, _) = compositor_init(
display, display,
@ -325,7 +321,7 @@ pub fn init_shell<Backend: 'static>(
let window_map = anvil_state.window_map.as_ref(); let window_map = anvil_state.window_map.as_ref();
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
{ {
surface_commit(&surface, ctoken, egl_reader.borrow().as_ref(), &*window_map) surface_commit(&surface, ctoken, anvil_state.egl_reader.as_ref(), &*window_map)
} }
#[cfg(not(feature = "egl"))] #[cfg(not(feature = "egl"))]
{ {

View File

@ -42,12 +42,12 @@ pub struct AnvilState<BackendData> {
// input-related fields // input-related fields
pub pointer: PointerHandle, pub pointer: PointerHandle,
pub keyboard: KeyboardHandle, pub keyboard: KeyboardHandle,
pub pointer_location: Rc<RefCell<(f64, f64)>>, pub pointer_location: (f64, f64),
pub cursor_status: Arc<Mutex<CursorImageStatus>>, pub cursor_status: Arc<Mutex<CursorImageStatus>>,
pub seat_name: String, pub seat_name: String,
pub start_time: std::time::Instant, pub start_time: std::time::Instant,
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
pub egl_reader: Rc<RefCell<Option<EGLBufferReader>>>, pub egl_reader: Option<EGLBufferReader>,
// things we must keep alive // things we must keep alive
#[cfg(feature = "xwayland")] #[cfg(feature = "xwayland")]
_xwayland: XWayland<XWm<BackendData>>, _xwayland: XWayland<XWm<BackendData>>,
@ -58,7 +58,7 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
display: Rc<RefCell<Display>>, display: Rc<RefCell<Display>>,
handle: LoopHandle<'static, AnvilState<BackendData>>, handle: LoopHandle<'static, AnvilState<BackendData>>,
backend_data: BackendData, backend_data: BackendData,
#[cfg(feature = "egl")] egl_reader: Rc<RefCell<Option<EGLBufferReader>>>, #[cfg(feature = "egl")] egl_reader: Option<EGLBufferReader>,
log: slog::Logger, log: slog::Logger,
) -> AnvilState<BackendData> { ) -> AnvilState<BackendData> {
// init the wayland connection // init the wayland connection
@ -85,8 +85,7 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
init_shm_global(&mut (*display).borrow_mut(), vec![], log.clone()); init_shm_global(&mut (*display).borrow_mut(), vec![], log.clone());
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
let shell_handles = let shell_handles = init_shell::<BackendData>(&mut display.borrow_mut(), log.clone());
init_shell::<BackendData>(&mut display.borrow_mut(), egl_reader.clone(), log.clone());
#[cfg(not(feature = "egl"))] #[cfg(not(feature = "egl"))]
let shell_handles = init_shell(&mut display.borrow_mut(), log.clone()); let shell_handles = init_shell(&mut display.borrow_mut(), log.clone());
@ -168,7 +167,7 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
pointer, pointer,
keyboard, keyboard,
cursor_status, cursor_status,
pointer_location: Rc::new(RefCell::new((0.0, 0.0))), pointer_location: (0.0, 0.0),
seat_name, seat_name,
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
egl_reader, egl_reader,

View File

@ -71,7 +71,7 @@ impl AsRawFd for SessionFd {
} }
pub struct UdevData { pub struct UdevData {
pub output_map: Rc<RefCell<Vec<MyOutput>>>, pub output_map: Vec<MyOutput>,
pub session: AutoSession, pub session: AutoSession,
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
primary_gpu: Option<PathBuf>, primary_gpu: Option<PathBuf>,
@ -100,12 +100,6 @@ pub fn run_udev(
.unwrap(); .unwrap();
info!(log, "Listening on wayland socket"; "name" => name.clone()); info!(log, "Listening on wayland socket"; "name" => name.clone());
::std::env::set_var("WAYLAND_DISPLAY", name); ::std::env::set_var("WAYLAND_DISPLAY", name);
#[cfg(feature = "egl")]
let egl_buffer_reader = Rc::new(RefCell::new(None));
let output_map = Rc::new(RefCell::new(Vec::new()));
/* /*
* Initialize session * Initialize session
*/ */
@ -123,7 +117,7 @@ pub fn run_udev(
let data = UdevData { let data = UdevData {
session, session,
output_map: output_map.clone(), output_map: Vec::new(),
primary_gpu, primary_gpu,
backends: HashMap::new(), backends: HashMap::new(),
signaler: session_signal.clone(), signaler: session_signal.clone(),
@ -135,7 +129,7 @@ pub fn run_udev(
event_loop.handle(), event_loop.handle(),
data, data,
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
egl_buffer_reader.clone(), None,
log.clone(), log.clone(),
); );
@ -446,7 +440,7 @@ impl AnvilState<UdevData> {
{ {
if is_primary { if is_primary {
info!(self.log, "Initializing EGL Hardware Acceleration via {:?}", path); info!(self.log, "Initializing EGL Hardware Acceleration via {:?}", path);
*self.egl_reader.borrow_mut() = egl.bind_wl_display(&*self.display.borrow()).ok(); self.egl_reader = egl.bind_wl_display(&*self.display.borrow()).ok();
} }
} }
@ -467,7 +461,7 @@ impl AnvilState<UdevData> {
&egl, &egl,
&context, &context,
&mut *self.display.borrow_mut(), &mut *self.display.borrow_mut(),
&mut *self.backend_data.output_map.borrow_mut(), &mut self.backend_data.output_map,
&self.backend_data.signaler, &self.backend_data.signaler,
&self.log, &self.log,
))); )));
@ -533,9 +527,10 @@ impl AnvilState<UdevData> {
let logger = self.log.clone(); let logger = self.log.clone();
let loop_handle = self.handle.clone(); let loop_handle = self.handle.clone();
let mut display = self.display.borrow_mut(); let mut display = self.display.borrow_mut();
let mut output_map = self.backend_data.output_map.borrow_mut();
let signaler = self.backend_data.signaler.clone(); let signaler = self.backend_data.signaler.clone();
output_map.retain(|output| output.device_id != device); self.backend_data
.output_map
.retain(|output| output.device_id != device);
let mut source = backend_data.event_dispatcher.as_source_mut(); let mut source = backend_data.event_dispatcher.as_source_mut();
let mut backends = backend_data.surfaces.borrow_mut(); let mut backends = backend_data.surfaces.borrow_mut();
@ -545,7 +540,7 @@ impl AnvilState<UdevData> {
&backend_data.egl, &backend_data.egl,
&backend_data.context, &backend_data.context,
&mut *display, &mut *display,
&mut *output_map, &mut self.backend_data.output_map,
&signaler, &signaler,
&logger, &logger,
); );
@ -567,7 +562,6 @@ impl AnvilState<UdevData> {
// clear outputs // clear outputs
self.backend_data self.backend_data
.output_map .output_map
.borrow_mut()
.retain(|output| output.device_id != device); .retain(|output| output.device_id != device);
let _device = self.handle.remove(backend_data.registration_token); let _device = self.handle.remove(backend_data.registration_token);
@ -579,7 +573,7 @@ impl AnvilState<UdevData> {
if _device.dev_path().and_then(|path| path.canonicalize().ok()) if _device.dev_path().and_then(|path| path.canonicalize().ok())
== self.backend_data.primary_gpu == self.backend_data.primary_gpu
{ {
*self.egl_reader.borrow_mut() = None; self.egl_reader = None;
} }
} }
debug!(self.log, "Dropping device"); debug!(self.log, "Dropping device");
@ -615,13 +609,13 @@ impl AnvilState<UdevData> {
let result = render_surface( let result = render_surface(
&mut *surface.borrow_mut(), &mut *surface.borrow_mut(),
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
self.egl_reader.borrow().as_ref(), self.egl_reader.as_ref(),
device_backend.dev_id, device_backend.dev_id,
crtc, crtc,
&mut *self.window_map.borrow_mut(), &mut *self.window_map.borrow_mut(),
&mut *self.backend_data.output_map.borrow_mut(), &mut self.backend_data.output_map,
&self.ctoken, &self.ctoken,
&*self.pointer_location.borrow(), &self.pointer_location,
&device_backend.pointer_image, &device_backend.pointer_image,
&*self.dnd_icon.lock().unwrap(), &*self.dnd_icon.lock().unwrap(),
&mut *self.cursor_status.lock().unwrap(), &mut *self.cursor_status.lock().unwrap(),

View File

@ -56,7 +56,7 @@ pub fn run_winit(
event_loop.handle(), event_loop.handle(),
WinitData, WinitData,
#[cfg(feature = "egl")] #[cfg(feature = "egl")]
Rc::new(RefCell::new(reader.clone())), reader,
log.clone(), log.clone(),
); );
@ -114,14 +114,14 @@ pub fn run_winit(
draw_windows( draw_windows(
renderer, renderer,
frame, frame,
reader.as_ref(), state.egl_reader.as_ref(),
&*state.window_map.borrow(), &*state.window_map.borrow(),
None, None,
state.ctoken, state.ctoken,
&log, &log,
)?; )?;
let (x, y) = *state.pointer_location.borrow(); let (x, y) = state.pointer_location;
// draw the dnd icon if any // draw the dnd icon if any
{ {
let guard = state.dnd_icon.lock().unwrap(); let guard = state.dnd_icon.lock().unwrap();
@ -131,7 +131,7 @@ pub fn run_winit(
renderer, renderer,
frame, frame,
surface, surface,
reader.as_ref(), state.egl_reader.as_ref(),
(x as i32, y as i32), (x as i32, y as i32),
state.ctoken, state.ctoken,
&log, &log,
@ -158,7 +158,7 @@ pub fn run_winit(
renderer, renderer,
frame, frame,
surface, surface,
reader.as_ref(), state.egl_reader.as_ref(),
(x as i32, y as i32), (x as i32, y as i32),
state.ctoken, state.ctoken,
&log, &log,