diff --git a/anvil/src/input_handler.rs b/anvil/src/input_handler.rs index 798e295..2657982 100644 --- a/anvil/src/input_handler.rs +++ b/anvil/src/input_handler.rs @@ -1,17 +1,9 @@ -use std::{ - cell::RefCell, - process::Command, - rc::Rc, - sync::{ - atomic::{AtomicBool, Ordering}, - Arc, - }, -}; +use std::{process::Command, sync::atomic::Ordering}; -use slog::Logger; +use crate::AnvilState; #[cfg(feature = "udev")] -use smithay::backend::session::{auto::AutoSession, Session}; +use smithay::backend::session::Session; use smithay::{ backend::input::{ self, Event, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, @@ -19,66 +11,13 @@ use smithay::{ }, reexports::wayland_server::protocol::wl_pointer, wayland::{ - seat::{keysyms as xkb, AxisFrame, KeyboardHandle, Keysym, ModifiersState, PointerHandle}, + seat::{keysyms as xkb, AxisFrame, Keysym, ModifiersState}, SERIAL_COUNTER as SCOUNTER, }, }; -use crate::shell::MyWindowMap; - -pub struct AnvilInputHandler { - log: Logger, - pointer: PointerHandle, - keyboard: KeyboardHandle, - window_map: Rc>, - pointer_location: Rc>, - screen_size: (u32, u32), - #[cfg(feature = "udev")] - session: Option, - running: Arc, -} - -pub struct InputInitData { - pub pointer: PointerHandle, - pub keyboard: KeyboardHandle, - pub window_map: Rc>, - pub screen_size: (u32, u32), - pub running: Arc, - pub pointer_location: Rc>, -} - -impl AnvilInputHandler { - pub fn new(log: Logger, data: InputInitData) -> AnvilInputHandler { - AnvilInputHandler { - log, - pointer: data.pointer, - keyboard: data.keyboard, - window_map: data.window_map, - screen_size: data.screen_size, - running: data.running, - pointer_location: data.pointer_location, - #[cfg(feature = "udev")] - session: None, - } - } - - #[cfg(feature = "udev")] - pub fn new_with_session(log: Logger, data: InputInitData, session: AutoSession) -> AnvilInputHandler { - AnvilInputHandler { - log, - pointer: data.pointer, - keyboard: data.keyboard, - window_map: data.window_map, - screen_size: data.screen_size, - running: data.running, - pointer_location: data.pointer_location, - session: Some(session), - } - } -} - -impl AnvilInputHandler { - pub fn process_event(&mut self, event: InputEvent) { +impl AnvilState { + pub fn process_input_event(&mut self, event: InputEvent) { match event { InputEvent::Keyboard { event, .. } => self.on_keyboard_key::(event), InputEvent::PointerMotion { event, .. } => self.on_pointer_move::(event), diff --git a/anvil/src/state.rs b/anvil/src/state.rs index 0b2d1d0..0ee6433 100644 --- a/anvil/src/state.rs +++ b/anvil/src/state.rs @@ -8,6 +8,7 @@ use std::{ }; use smithay::{ + backend::session::auto::AutoSession, reexports::{ calloop::{ generic::{Fd, Generic}, @@ -17,11 +18,15 @@ use smithay::{ }, wayland::{ compositor::CompositorToken, - data_device::{default_action_chooser, init_data_device, DataDeviceEvent}, + data_device::{default_action_chooser, init_data_device, set_data_device_focus, DataDeviceEvent}, + seat::{CursorImageStatus, KeyboardHandle, PointerHandle, Seat, XkbConfig}, shm::init_shm_global, }, }; +#[cfg(feature = "udev")] +use smithay::backend::session::Session; + use crate::{buffer_utils::BufferUtils, shell::init_shell}; pub struct AnvilState { @@ -33,6 +38,15 @@ pub struct AnvilState { pub window_map: Rc>>, pub dnd_icon: Arc>>, pub log: slog::Logger, + // input-related fields + pub pointer: PointerHandle, + pub keyboard: KeyboardHandle, + pub pointer_location: Rc>, + pub cursor_status: Arc>, + pub screen_size: (u32, u32), + pub seat_name: String, + #[cfg(feature = "udev")] + pub session: Option, // things we must keep alive _wayland_event_source: Source>, } @@ -42,6 +56,8 @@ impl AnvilState { display: Rc>, handle: LoopHandle, buffer_utils: BufferUtils, + #[cfg(feature = "udev")] session: Option, + #[cfg(not(feature = "udev"))] _session: Option<()>, log: slog::Logger, ) -> AnvilState { // init the wayland connection @@ -102,6 +118,37 @@ impl AnvilState { log.clone(), ); + // init input + #[cfg(feature = "udev")] + let seat_name = if let Some(ref session) = session { + session.seat() + } else { + "anvil".into() + }; + #[cfg(not(feature = "udev"))] + let seat_name = "anvil".into(); + + let (mut seat, _) = Seat::new( + &mut display.borrow_mut(), + seat_name.clone(), + shell_handles.token, + log.clone(), + ); + + let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default)); + + let cursor_status2 = cursor_status.clone(); + let pointer = seat.add_pointer(shell_handles.token.clone(), move |new_status| { + // TODO: hide winit system cursor when relevant + *cursor_status2.lock().unwrap() = new_status + }); + + let keyboard = seat + .add_keyboard(XkbConfig::default(), 200, 25, |seat, focus| { + set_data_device_focus(seat, focus.and_then(|s| s.as_ref().client())) + }) + .expect("Failed to initialize the keyboard"); + AnvilState { running: Arc::new(AtomicBool::new(true)), display, @@ -111,6 +158,14 @@ impl AnvilState { dnd_icon, log, socket_name, + pointer, + keyboard, + cursor_status, + pointer_location: Rc::new(RefCell::new((0.0, 0.0))), + screen_size: (1920, 1080), + seat_name, + #[cfg(feature = "udev")] + session, _wayland_event_source, } } diff --git a/anvil/src/udev.rs b/anvil/src/udev.rs index 4cdc311..008c44a 100644 --- a/anvil/src/udev.rs +++ b/anvil/src/udev.rs @@ -50,16 +50,14 @@ use smithay::{ }, wayland::{ compositor::CompositorToken, - data_device::set_data_device_focus, output::{Mode, Output, PhysicalProperties}, - seat::{CursorImageStatus, Seat, XkbConfig}, + seat::CursorImageStatus, SERIAL_COUNTER as SCOUNTER, }, }; use crate::buffer_utils::BufferUtils; use crate::glium_drawer::GliumDrawer; -use crate::input_handler::{AnvilInputHandler, InputInitData}; use crate::shell::{MyWindowMap, Roles}; use crate::state::AnvilState; @@ -100,11 +98,6 @@ pub fn run_udev( #[cfg(not(feature = "egl"))] let buffer_utils = BufferUtils::new(log.clone()); - /* - * Initialize the compositor - */ - let mut state = AnvilState::init(display.clone(), event_loop.handle(), buffer_utils, log.clone()); - /* * Initialize session */ @@ -112,56 +105,43 @@ pub fn run_udev( let (udev_observer, udev_notifier) = notify_multiplexer(); let udev_session_id = notifier.register(udev_observer); - let pointer_location = Rc::new(RefCell::new((0.0, 0.0))); - let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default)); + /* + * Initialize the compositor + */ + let mut state = AnvilState::init( + display.clone(), + event_loop.handle(), + buffer_utils, + Some(session), + log.clone(), + ); /* * Initialize the udev backend */ - let seat = session.seat(); - - let primary_gpu = primary_gpu(&seat).unwrap_or_default(); + let primary_gpu = primary_gpu(&state.seat_name).unwrap_or_default(); let bytes = include_bytes!("../resources/cursor2.rgba"); - let udev_backend = UdevBackend::new(seat.clone(), log.clone()).map_err(|_| ())?; + let udev_backend = UdevBackend::new(state.seat_name.clone(), log.clone()).map_err(|_| ())?; let mut udev_handler = UdevHandlerImpl { compositor_token: state.ctoken, #[cfg(feature = "egl")] egl_buffer_reader, - session: session.clone(), + session: state.session.clone().unwrap(), backends: HashMap::new(), display: display.clone(), primary_gpu, window_map: state.window_map.clone(), - pointer_location: pointer_location.clone(), + pointer_location: state.pointer_location.clone(), pointer_image: ImageBuffer::from_raw(64, 64, bytes.to_vec()).unwrap(), - cursor_status: cursor_status.clone(), + cursor_status: state.cursor_status.clone(), dnd_icon: state.dnd_icon.clone(), loop_handle: event_loop.handle(), notifier: udev_notifier, logger: log.clone(), }; - /* - * Initialize wayland input object - */ - let (mut w_seat, _) = Seat::new( - &mut display.borrow_mut(), - session.seat(), - state.ctoken, - log.clone(), - ); - - let pointer = w_seat.add_pointer(state.ctoken.clone(), move |new_status| { - *cursor_status.lock().unwrap() = new_status; - }); - let keyboard = w_seat - .add_keyboard(XkbConfig::default(), 200, 25, |seat, focus| { - set_data_device_focus(seat, focus.and_then(|s| s.as_ref().client())) - }) - .expect("Failed to initialize the keyboard"); - /* * Initialize a fake output (we render one screen to every device in this example) */ @@ -197,31 +177,20 @@ pub fn run_udev( /* * Initialize libinput backend */ - let mut libinput_context = - Libinput::new_with_udev::>(session.clone().into()); - let libinput_session_id = notifier.register(libinput_context.observer()); - libinput_context.udev_assign_seat(&seat).unwrap(); - let libinput_backend = LibinputInputBackend::new(libinput_context, log.clone()); - let mut input_handler = AnvilInputHandler::new_with_session( - log.clone(), - InputInitData { - pointer, - keyboard, - window_map: state.window_map.clone(), - screen_size: (w, h), - running: state.running.clone(), - pointer_location, - }, - session, + let mut libinput_context = Libinput::new_with_udev::>( + state.session.clone().unwrap().into(), ); + let libinput_session_id = notifier.register(libinput_context.observer()); + libinput_context.udev_assign_seat(&state.seat_name).unwrap(); + let libinput_backend = LibinputInputBackend::new(libinput_context, log.clone()); /* * Bind all our objects that get driven by the event loop */ let libinput_event_source = event_loop .handle() - .insert_source(libinput_backend, move |event, _, _anvil_state| { - input_handler.process_event(event) + .insert_source(libinput_backend, move |event, _, anvil_state| { + anvil_state.process_input_event(event) }) .unwrap(); let session_event_source = auto_session_bind(notifier, event_loop.handle()) diff --git a/anvil/src/winit.rs b/anvil/src/winit.rs index 0ac9fc3..bd2d549 100644 --- a/anvil/src/winit.rs +++ b/anvil/src/winit.rs @@ -1,9 +1,4 @@ -use std::{ - cell::RefCell, - rc::Rc, - sync::{atomic::Ordering, Arc, Mutex}, - time::Duration, -}; +use std::{cell::RefCell, rc::Rc, sync::atomic::Ordering, time::Duration}; use smithay::{ backend::{egl::EGLGraphicsBackend, graphics::gl::GLGraphicsBackend, input::InputBackend, winit}, @@ -12,9 +7,8 @@ use smithay::{ wayland_server::{protocol::wl_output, Display}, }, wayland::{ - data_device::set_data_device_focus, output::{Mode, Output, PhysicalProperties}, - seat::{CursorImageStatus, Seat, XkbConfig}, + seat::CursorImageStatus, SERIAL_COUNTER as SCOUNTER, }, }; @@ -23,7 +17,6 @@ use slog::Logger; use crate::buffer_utils::BufferUtils; use crate::glium_drawer::GliumDrawer; -use crate::input_handler::{AnvilInputHandler, InputInitData}; use crate::state::AnvilState; pub fn run_winit( @@ -60,29 +53,14 @@ pub fn run_winit( * Initialize the globals */ - let mut state = AnvilState::init(display.clone(), event_loop.handle(), buffer_utils, log.clone()); - - let (mut seat, _) = Seat::new( - &mut display.borrow_mut(), - "winit".into(), - state.ctoken, + let mut state = AnvilState::init( + display.clone(), + event_loop.handle(), + buffer_utils, + None, log.clone(), ); - let cursor_status = Arc::new(Mutex::new(CursorImageStatus::Default)); - - let cursor_status2 = cursor_status.clone(); - let pointer = seat.add_pointer(state.ctoken.clone(), move |new_status| { - // TODO: hide winit system cursor when relevant - *cursor_status2.lock().unwrap() = new_status - }); - - let keyboard = seat - .add_keyboard(XkbConfig::default(), 200, 25, |seat, focus| { - set_data_device_focus(seat, focus.and_then(|s| s.as_ref().client())) - }) - .expect("Failed to initialize the keyboard"); - let (output, _) = Output::new( &mut display.borrow_mut(), "Winit".into(), @@ -111,25 +89,11 @@ pub fn run_winit( refresh: 60_000, }); - let pointer_location = Rc::new(RefCell::new((0.0, 0.0))); - - let mut input_handler = AnvilInputHandler::new( - log.clone(), - InputInitData { - pointer, - keyboard, - window_map: state.window_map.clone(), - screen_size: (0, 0), - running: state.running.clone(), - pointer_location: pointer_location.clone(), - }, - ); - info!(log, "Initialization completed, starting the main loop."); while state.running.load(Ordering::SeqCst) { input - .dispatch_new_events(|event, _| input_handler.process_event(event)) + .dispatch_new_events(|event, _| state.process_input_event(event)) .unwrap(); // drawing logic @@ -141,7 +105,7 @@ pub fn run_winit( // draw the windows drawer.draw_windows(&mut frame, &*state.window_map.borrow(), state.ctoken); - let (x, y) = *pointer_location.borrow(); + let (x, y) = *state.pointer_location.borrow(); // draw the dnd icon if any { let guard = state.dnd_icon.lock().unwrap(); @@ -153,7 +117,7 @@ pub fn run_winit( } // draw the cursor as relevant { - let mut guard = cursor_status.lock().unwrap(); + let mut guard = state.cursor_status.lock().unwrap(); // reset the cursor if the surface is no longer alive let mut reset = false; if let CursorImageStatus::Image(ref surface) = *guard {