anvil: Fuse InputHandler into AnvilState
This commit is contained in:
parent
8f543eb597
commit
b708f88da6
|
@ -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<RefCell<MyWindowMap>>,
|
||||
pointer_location: Rc<RefCell<(f64, f64)>>,
|
||||
screen_size: (u32, u32),
|
||||
#[cfg(feature = "udev")]
|
||||
session: Option<AutoSession>,
|
||||
running: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
pub struct InputInitData {
|
||||
pub pointer: PointerHandle,
|
||||
pub keyboard: KeyboardHandle,
|
||||
pub window_map: Rc<RefCell<MyWindowMap>>,
|
||||
pub screen_size: (u32, u32),
|
||||
pub running: Arc<AtomicBool>,
|
||||
pub pointer_location: Rc<RefCell<(f64, f64)>>,
|
||||
}
|
||||
|
||||
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<B: InputBackend>(&mut self, event: InputEvent<B>) {
|
||||
impl AnvilState {
|
||||
pub fn process_input_event<B: InputBackend>(&mut self, event: InputEvent<B>) {
|
||||
match event {
|
||||
InputEvent::Keyboard { event, .. } => self.on_keyboard_key::<B>(event),
|
||||
InputEvent::PointerMotion { event, .. } => self.on_pointer_move::<B>(event),
|
||||
|
|
|
@ -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<RefCell<crate::window_map::WindowMap<crate::shell::Roles>>>,
|
||||
pub dnd_icon: Arc<Mutex<Option<WlSurface>>>,
|
||||
pub log: slog::Logger,
|
||||
// input-related fields
|
||||
pub pointer: PointerHandle,
|
||||
pub keyboard: KeyboardHandle,
|
||||
pub pointer_location: Rc<RefCell<(f64, f64)>>,
|
||||
pub cursor_status: Arc<Mutex<CursorImageStatus>>,
|
||||
pub screen_size: (u32, u32),
|
||||
pub seat_name: String,
|
||||
#[cfg(feature = "udev")]
|
||||
pub session: Option<AutoSession>,
|
||||
// things we must keep alive
|
||||
_wayland_event_source: Source<Generic<Fd>>,
|
||||
}
|
||||
|
@ -42,6 +56,8 @@ impl AnvilState {
|
|||
display: Rc<RefCell<Display>>,
|
||||
handle: LoopHandle<AnvilState>,
|
||||
buffer_utils: BufferUtils,
|
||||
#[cfg(feature = "udev")] session: Option<AutoSession>,
|
||||
#[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,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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::<LibinputSessionInterface<AutoSession>>(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::<LibinputSessionInterface<AutoSession>>(
|
||||
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())
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue