anvil: factor the input backend code
This commit is contained in:
parent
ae1395fb32
commit
6ee6fd6890
|
@ -0,0 +1,321 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::process::Command;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
use slog::Logger;
|
||||||
|
|
||||||
|
#[cfg(feature = "tty_launch")]
|
||||||
|
use smithay::backend::session::auto::AutoSession;
|
||||||
|
use smithay::backend::input::{self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent,
|
||||||
|
PointerAxisEvent, PointerButtonEvent, PointerMotionAbsoluteEvent,
|
||||||
|
PointerMotionEvent};
|
||||||
|
use smithay::wayland::seat::{keysyms as xkb, KeyboardHandle, Keysym, ModifiersState, PointerHandle};
|
||||||
|
use smithay::wayland_server::protocol::wl_pointer;
|
||||||
|
|
||||||
|
use 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),
|
||||||
|
serial: u32,
|
||||||
|
#[cfg(feature = "tty_launch")]
|
||||||
|
session: Option<AutoSession>,
|
||||||
|
running: Arc<AtomicBool>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AnvilInputHandler {
|
||||||
|
pub fn new(
|
||||||
|
log: Logger,
|
||||||
|
pointer: PointerHandle,
|
||||||
|
keyboard: KeyboardHandle,
|
||||||
|
window_map: Rc<RefCell<MyWindowMap>>,
|
||||||
|
screen_size: (u32, u32),
|
||||||
|
running: Arc<AtomicBool>,
|
||||||
|
pointer_location: Rc<RefCell<(f64, f64)>>,
|
||||||
|
) -> AnvilInputHandler {
|
||||||
|
AnvilInputHandler {
|
||||||
|
log,
|
||||||
|
pointer,
|
||||||
|
keyboard,
|
||||||
|
window_map,
|
||||||
|
screen_size,
|
||||||
|
running,
|
||||||
|
pointer_location,
|
||||||
|
serial: 1,
|
||||||
|
#[cfg(feature = "tty_launch")]
|
||||||
|
session: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "tty_launch")]
|
||||||
|
pub fn new_with_session(
|
||||||
|
log: Logger,
|
||||||
|
pointer: PointerHandle,
|
||||||
|
keyboard: KeyboardHandle,
|
||||||
|
window_map: Rc<RefCell<MyWindowMap>>,
|
||||||
|
screen_size: (u32, u32),
|
||||||
|
running: Arc<AtomicBool>,
|
||||||
|
pointer_location: Rc<RefCell<(f64, f64)>>,
|
||||||
|
session: AutoSession,
|
||||||
|
) -> AnvilInputHandler {
|
||||||
|
AnvilInputHandler {
|
||||||
|
log,
|
||||||
|
pointer,
|
||||||
|
keyboard,
|
||||||
|
window_map,
|
||||||
|
screen_size,
|
||||||
|
running,
|
||||||
|
pointer_location,
|
||||||
|
serial: 1,
|
||||||
|
session: Some(session),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_serial(&mut self) -> u32 {
|
||||||
|
self.serial += 1;
|
||||||
|
self.serial
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B: InputBackend> InputHandler<B> for AnvilInputHandler {
|
||||||
|
fn on_seat_created(&mut self, _: &input::Seat) {
|
||||||
|
/* currently we just create a single static one */
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_seat_destroyed(&mut self, _: &input::Seat) {
|
||||||
|
/* currently we just create a single static one */
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_seat_changed(&mut self, _: &input::Seat) {
|
||||||
|
/* currently we just create a single static one */
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_keyboard_key(&mut self, _: &input::Seat, evt: B::KeyboardKeyEvent) {
|
||||||
|
let keycode = evt.key_code();
|
||||||
|
let state = evt.state();
|
||||||
|
debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
|
||||||
|
let serial = self.next_serial();
|
||||||
|
let log = &self.log;
|
||||||
|
let time = Event::time(&evt);
|
||||||
|
let mut action = KeyAction::None;
|
||||||
|
self.keyboard
|
||||||
|
.input(keycode, state, serial, time, |modifiers, keysym| {
|
||||||
|
debug!(log, "keysym";
|
||||||
|
"state" => format!("{:?}", state),
|
||||||
|
"mods" => format!("{:?}", modifiers),
|
||||||
|
"keysym" => ::xkbcommon::xkb::keysym_get_name(keysym)
|
||||||
|
);
|
||||||
|
action = process_keyboard_shortcut(modifiers, keysym);
|
||||||
|
// forward to client only if action == KeyAction::Forward
|
||||||
|
// both for pressed and released, to avoid inconsistencies
|
||||||
|
if let KeyAction::Forward = action {
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if let KeyState::Released = state {
|
||||||
|
// only process special actions on key press, not release
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
match action {
|
||||||
|
KeyAction::Quit => {
|
||||||
|
info!(self.log, "Quitting.");
|
||||||
|
self.running.store(false, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
#[cfg(feature = "tty_lauch")]
|
||||||
|
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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_pointer_move(&mut self, _: &input::Seat, evt: B::PointerMotionEvent) {
|
||||||
|
let (x, y) = (evt.delta_x(), evt.delta_y());
|
||||||
|
let serial = self.next_serial();
|
||||||
|
let mut location = self.pointer_location.borrow_mut();
|
||||||
|
location.0 += x as f64;
|
||||||
|
location.1 += y as f64;
|
||||||
|
// clamp to screen limits
|
||||||
|
// this event is never generated by winit so self.screen_size is relevant
|
||||||
|
location.0 = (location.0).max(0.0).min(self.screen_size.0 as f64);
|
||||||
|
location.1 = (location.1).max(0.0).min(self.screen_size.1 as f64);
|
||||||
|
let under = self.window_map
|
||||||
|
.borrow()
|
||||||
|
.get_surface_under((location.0, location.1));
|
||||||
|
self.pointer.motion(
|
||||||
|
under.as_ref().map(|&(ref s, (x, y))| (s, x, y)),
|
||||||
|
serial,
|
||||||
|
evt.time(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_pointer_move_absolute(&mut self, _: &input::Seat, evt: B::PointerMotionAbsoluteEvent) {
|
||||||
|
// different cases depending on the context:
|
||||||
|
let (x, y) = {
|
||||||
|
#[cfg(feature = "tty_launch")]
|
||||||
|
{
|
||||||
|
if self.session.is_some() {
|
||||||
|
// we are started on a tty
|
||||||
|
let (ux, uy) = evt.position_transformed(self.screen_size);
|
||||||
|
(ux as f64, uy as f64)
|
||||||
|
} else {
|
||||||
|
// we are started in winit
|
||||||
|
evt.position()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "tty_launch"))]
|
||||||
|
{
|
||||||
|
evt.position()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*self.pointer_location.borrow_mut() = (x, y);
|
||||||
|
let serial = self.next_serial();
|
||||||
|
let under = self.window_map
|
||||||
|
.borrow()
|
||||||
|
.get_surface_under((x as f64, y as f64));
|
||||||
|
self.pointer.motion(
|
||||||
|
under.as_ref().map(|&(ref s, (x, y))| (s, x, y)),
|
||||||
|
serial,
|
||||||
|
evt.time(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_pointer_button(&mut self, _: &input::Seat, evt: B::PointerButtonEvent) {
|
||||||
|
let serial = self.next_serial();
|
||||||
|
let button = match evt.button() {
|
||||||
|
input::MouseButton::Left => 0x110,
|
||||||
|
input::MouseButton::Right => 0x111,
|
||||||
|
input::MouseButton::Middle => 0x112,
|
||||||
|
input::MouseButton::Other(b) => b as u32,
|
||||||
|
};
|
||||||
|
let state = match evt.state() {
|
||||||
|
input::MouseButtonState::Pressed => {
|
||||||
|
// change the keyboard focus
|
||||||
|
let under = self.window_map
|
||||||
|
.borrow_mut()
|
||||||
|
.get_surface_and_bring_to_top(*self.pointer_location.borrow());
|
||||||
|
self.keyboard
|
||||||
|
.set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
|
||||||
|
wl_pointer::ButtonState::Pressed
|
||||||
|
}
|
||||||
|
input::MouseButtonState::Released => wl_pointer::ButtonState::Released,
|
||||||
|
};
|
||||||
|
self.pointer.button(button, state, serial, evt.time());
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_pointer_axis(&mut self, _: &input::Seat, evt: B::PointerAxisEvent) {
|
||||||
|
let source = match evt.source() {
|
||||||
|
input::AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
|
||||||
|
input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
|
||||||
|
input::AxisSource::Wheel | input::AxisSource::WheelTilt => wl_pointer::AxisSource::Wheel,
|
||||||
|
};
|
||||||
|
let horizontal_amount = evt.amount(&input::Axis::Horizontal)
|
||||||
|
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0);
|
||||||
|
let vertical_amount = evt.amount(&input::Axis::Vertical)
|
||||||
|
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Vertical).unwrap() * 3.0);
|
||||||
|
let horizontal_amount_discrete = evt.amount_discrete(&input::Axis::Horizontal);
|
||||||
|
let vertical_amount_discrete = evt.amount_discrete(&input::Axis::Vertical);
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut event = self.pointer.axis();
|
||||||
|
event.source(source);
|
||||||
|
if horizontal_amount != 0.0 {
|
||||||
|
event.value(
|
||||||
|
wl_pointer::Axis::HorizontalScroll,
|
||||||
|
horizontal_amount,
|
||||||
|
evt.time(),
|
||||||
|
);
|
||||||
|
if let Some(discrete) = horizontal_amount_discrete {
|
||||||
|
event.discrete(wl_pointer::Axis::HorizontalScroll, discrete as i32);
|
||||||
|
}
|
||||||
|
} else if source == wl_pointer::AxisSource::Finger {
|
||||||
|
event.stop(wl_pointer::Axis::HorizontalScroll, evt.time());
|
||||||
|
}
|
||||||
|
if vertical_amount != 0.0 {
|
||||||
|
event.value(
|
||||||
|
wl_pointer::Axis::VerticalScroll,
|
||||||
|
vertical_amount,
|
||||||
|
evt.time(),
|
||||||
|
);
|
||||||
|
if let Some(discrete) = vertical_amount_discrete {
|
||||||
|
event.discrete(wl_pointer::Axis::VerticalScroll, discrete as i32);
|
||||||
|
}
|
||||||
|
} else if source == wl_pointer::AxisSource::Finger {
|
||||||
|
event.stop(wl_pointer::Axis::VerticalScroll, evt.time());
|
||||||
|
}
|
||||||
|
event.done();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_touch_down(&mut self, _: &input::Seat, _: B::TouchDownEvent) {
|
||||||
|
/* not done in this example */
|
||||||
|
}
|
||||||
|
fn on_touch_motion(&mut self, _: &input::Seat, _: B::TouchMotionEvent) {
|
||||||
|
/* not done in this example */
|
||||||
|
}
|
||||||
|
fn on_touch_up(&mut self, _: &input::Seat, _: B::TouchUpEvent) {
|
||||||
|
/* not done in this example */
|
||||||
|
}
|
||||||
|
fn on_touch_cancel(&mut self, _: &input::Seat, _: B::TouchCancelEvent) {
|
||||||
|
/* not done in this example */
|
||||||
|
}
|
||||||
|
fn on_touch_frame(&mut self, _: &input::Seat, _: B::TouchFrameEvent) {
|
||||||
|
/* not done in this example */
|
||||||
|
}
|
||||||
|
fn on_input_config_changed(&mut self, _: &mut B::InputConfig) {
|
||||||
|
/* not done in this example */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Possible results of a keyboard action
|
||||||
|
enum KeyAction {
|
||||||
|
/// Quit the compositor
|
||||||
|
Quit,
|
||||||
|
/// Trigger a vt-switch
|
||||||
|
VtSwitch(i32),
|
||||||
|
/// run a command
|
||||||
|
Run(String),
|
||||||
|
/// Forward the key to the client
|
||||||
|
Forward,
|
||||||
|
/// Do nothing more
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn process_keyboard_shortcut(modifiers: &ModifiersState, keysym: Keysym) -> KeyAction {
|
||||||
|
if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace {
|
||||||
|
// ctrl+alt+backspace = quit
|
||||||
|
KeyAction::Quit
|
||||||
|
} else if modifiers.logo && keysym == xkb::KEY_q {
|
||||||
|
// logo + q = quit
|
||||||
|
KeyAction::Quit
|
||||||
|
} else if keysym >= xkb::KEY_XF86Switch_VT_1 && keysym <= xkb::KEY_XF86Switch_VT_12 {
|
||||||
|
// VTSwicth
|
||||||
|
KeyAction::VtSwitch((keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32)
|
||||||
|
} else if modifiers.logo && keysym == xkb::KEY_Return {
|
||||||
|
// run terminal
|
||||||
|
KeyAction::Run("weston-terminal".into())
|
||||||
|
} else {
|
||||||
|
KeyAction::Forward
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,6 @@ extern crate slog_term;
|
||||||
extern crate smithay;
|
extern crate smithay;
|
||||||
extern crate xkbcommon;
|
extern crate xkbcommon;
|
||||||
|
|
||||||
|
|
||||||
use slog::Drain;
|
use slog::Drain;
|
||||||
use smithay::wayland_server::Display;
|
use smithay::wayland_server::Display;
|
||||||
|
|
||||||
|
@ -20,6 +19,14 @@ mod udev;
|
||||||
mod window_map;
|
mod window_map;
|
||||||
#[cfg(feature = "winit")]
|
#[cfg(feature = "winit")]
|
||||||
mod winit;
|
mod winit;
|
||||||
|
mod input_handler;
|
||||||
|
|
||||||
|
static POSSIBLE_BACKENDS: &'static [&'static str] = &[
|
||||||
|
#[cfg(feature = "winit")]
|
||||||
|
"--winit",
|
||||||
|
#[cfg(feature = "tty_launch")]
|
||||||
|
"--tty",
|
||||||
|
];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// A logger facility, here we use the terminal here
|
// A logger facility, here we use the terminal here
|
||||||
|
@ -30,21 +37,29 @@ fn main() {
|
||||||
|
|
||||||
let (mut display, mut event_loop) = Display::new();
|
let (mut display, mut event_loop) = Display::new();
|
||||||
|
|
||||||
|
let arg = ::std::env::args().skip(1).next();
|
||||||
|
match arg.as_ref().map(|s| &s[..]) {
|
||||||
#[cfg(feature = "winit")]
|
#[cfg(feature = "winit")]
|
||||||
{
|
Some("--winit") => {
|
||||||
if let Ok(()) = winit::run_winit(&mut display, &mut event_loop, log.clone()) {
|
info!(log, "Starting anvil with winit backend");
|
||||||
return;
|
if let Err(()) = winit::run_winit(&mut display, &mut event_loop, log.clone()) {
|
||||||
|
crit!(log, "Failed to initialize winit backend.");
|
||||||
}
|
}
|
||||||
warn!(log, "Failed to initialize winit backend, skipping.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "tty_launch")]
|
#[cfg(feature = "tty_launch")]
|
||||||
{
|
Some("--tty") => {
|
||||||
if let Ok(()) = udev::run_udev(display, event_loop, log.clone()) {
|
info!(log, "Starting anvil on a tty");
|
||||||
return;
|
if let Err(()) = udev::run_udev(display, event_loop, log.clone()) {
|
||||||
|
crit!(log, "Failed to initialize tty backend.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
println!("USAGE: anvil --backend");
|
||||||
|
println!("");
|
||||||
|
println!("Possible backends are:");
|
||||||
|
for b in POSSIBLE_BACKENDS {
|
||||||
|
println!("\t{}", b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
warn!(log, "Failed to initialize udev backend, skipping.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error!(log, "Failed to initialize any backend.");
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process::Command;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
@ -23,8 +22,7 @@ use smithay::backend::drm::{DevPath, DrmBackend, DrmDevice, DrmHandler};
|
||||||
use smithay::backend::graphics::GraphicsBackend;
|
use smithay::backend::graphics::GraphicsBackend;
|
||||||
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions, Format};
|
use smithay::backend::graphics::egl::wayland::{EGLDisplay, EGLWaylandExtensions, Format};
|
||||||
use smithay::backend::input::{self, Event, InputBackend, InputHandler, KeyState, KeyboardKeyEvent,
|
use smithay::backend::input::InputBackend;
|
||||||
PointerAxisEvent, PointerButtonEvent};
|
|
||||||
use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface};
|
use smithay::backend::libinput::{libinput_bind, LibinputInputBackend, LibinputSessionInterface};
|
||||||
use smithay::backend::session::{Session, SessionNotifier};
|
use smithay::backend::session::{Session, SessionNotifier};
|
||||||
use smithay::backend::session::auto::{auto_session_bind, AutoSession};
|
use smithay::backend::session::auto::{auto_session_bind, AutoSession};
|
||||||
|
@ -32,219 +30,18 @@ use smithay::backend::udev::{primary_gpu, udev_backend_bind, SessionFdDrmDevice,
|
||||||
use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, TraversalAction};
|
use smithay::wayland::compositor::{CompositorToken, SubsurfaceRole, TraversalAction};
|
||||||
use smithay::wayland::compositor::roles::Role;
|
use smithay::wayland::compositor::roles::Role;
|
||||||
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
||||||
use smithay::wayland::seat::{KeyboardHandle, PointerHandle, Seat, keysyms as xkb};
|
use smithay::wayland::seat::Seat;
|
||||||
use smithay::wayland::shm::init_shm_global;
|
use smithay::wayland::shm::init_shm_global;
|
||||||
use smithay::wayland_server::{Display, EventLoop};
|
use smithay::wayland_server::{Display, EventLoop};
|
||||||
use smithay::wayland_server::commons::downcast_impl;
|
use smithay::wayland_server::commons::downcast_impl;
|
||||||
use smithay::wayland_server::protocol::{wl_output, wl_pointer};
|
use smithay::wayland_server::protocol::wl_output;
|
||||||
use smithay::input::{event, Device as LibinputDevice, Libinput};
|
use smithay::input::Libinput;
|
||||||
use smithay::input::event::keyboard::KeyboardEventTrait;
|
|
||||||
|
|
||||||
use glium_drawer::GliumDrawer;
|
use glium_drawer::GliumDrawer;
|
||||||
use shell::{init_shell, MyWindowMap, Buffer, Roles, SurfaceData};
|
use shell::{init_shell, Buffer, MyWindowMap, Roles, SurfaceData};
|
||||||
|
use input_handler::AnvilInputHandler;
|
||||||
struct LibinputInputHandler {
|
|
||||||
log: Logger,
|
|
||||||
pointer: PointerHandle,
|
|
||||||
keyboard: KeyboardHandle,
|
|
||||||
window_map: Rc<RefCell<MyWindowMap>>,
|
|
||||||
pointer_location: Rc<RefCell<(f64, f64)>>,
|
|
||||||
screen_size: (u32, u32),
|
|
||||||
serial: u32,
|
|
||||||
session: AutoSession,
|
|
||||||
running: Arc<AtomicBool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LibinputInputHandler {
|
|
||||||
fn next_serial(&mut self) -> u32 {
|
|
||||||
self.serial += 1;
|
|
||||||
self.serial
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputHandler<LibinputInputBackend> for LibinputInputHandler {
|
|
||||||
fn on_seat_created(&mut self, _: &input::Seat) {
|
|
||||||
/* we just create a single static one */
|
|
||||||
}
|
|
||||||
fn on_seat_destroyed(&mut self, _: &input::Seat) {
|
|
||||||
/* we just create a single static one */
|
|
||||||
}
|
|
||||||
fn on_seat_changed(&mut self, _: &input::Seat) {
|
|
||||||
/* we just create a single static one */
|
|
||||||
}
|
|
||||||
fn on_keyboard_key(&mut self, _: &input::Seat, evt: event::keyboard::KeyboardKeyEvent) {
|
|
||||||
let keycode = evt.key();
|
|
||||||
let state = evt.state();
|
|
||||||
debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
|
|
||||||
let serial = self.next_serial();
|
|
||||||
|
|
||||||
// we cannot borrow `self` into the closure, because we need self.keyboard.
|
|
||||||
// but rust does not borrow all fields separately, so we need to do that manually...
|
|
||||||
let running = &self.running;
|
|
||||||
let mut session = &mut self.session;
|
|
||||||
let log = &self.log;
|
|
||||||
let time = Event::time(&evt);
|
|
||||||
self.keyboard
|
|
||||||
.input(keycode, state, serial, time, move |modifiers, keysym| {
|
|
||||||
debug!(log, "keysym";
|
|
||||||
"state" => format!("{:?}", state),
|
|
||||||
"mods" => format!("{:?}", modifiers),
|
|
||||||
"keysym" => ::xkbcommon::xkb::keysym_get_name(keysym)
|
|
||||||
);
|
|
||||||
if modifiers.ctrl && modifiers.alt && keysym == xkb::KEY_BackSpace
|
|
||||||
&& state == KeyState::Pressed
|
|
||||||
{
|
|
||||||
info!(log, "Stopping example using Ctrl+Alt+Backspace");
|
|
||||||
running.store(false, Ordering::SeqCst);
|
|
||||||
false
|
|
||||||
} else if modifiers.logo && keysym == xkb::KEY_q {
|
|
||||||
info!(log, "Stopping example using Logo+Q");
|
|
||||||
running.store(false, Ordering::SeqCst);
|
|
||||||
false
|
|
||||||
} else if modifiers.ctrl && modifiers.alt && keysym >= xkb::KEY_XF86Switch_VT_1
|
|
||||||
&& keysym <= xkb::KEY_XF86Switch_VT_12
|
|
||||||
&& state == KeyState::Pressed
|
|
||||||
{
|
|
||||||
let vt = (keysym - xkb::KEY_XF86Switch_VT_1 + 1) as i32;
|
|
||||||
info!(log, "Trying to switch to vt {}", vt);
|
|
||||||
if let Err(err) = session.change_vt(vt) {
|
|
||||||
error!(log, "Error switching to vt {}: {}", vt, err);
|
|
||||||
}
|
|
||||||
false
|
|
||||||
} else if modifiers.logo && keysym == xkb::KEY_Return && state == KeyState::Pressed {
|
|
||||||
info!(log, "Launching terminal");
|
|
||||||
let _ = Command::new("weston-terminal").spawn();
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
fn on_pointer_move(&mut self, _: &input::Seat, evt: event::pointer::PointerMotionEvent) {
|
|
||||||
let (x, y) = (evt.dx(), evt.dy());
|
|
||||||
let serial = self.next_serial();
|
|
||||||
let mut location = self.pointer_location.borrow_mut();
|
|
||||||
location.0 += x;
|
|
||||||
location.1 += y;
|
|
||||||
let under = self.window_map
|
|
||||||
.borrow()
|
|
||||||
.get_surface_under((location.0, location.1));
|
|
||||||
self.pointer.motion(
|
|
||||||
under.as_ref().map(|&(ref s, (x, y))| (s, x, y)),
|
|
||||||
serial,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
fn on_pointer_move_absolute(&mut self, _: &input::Seat, evt: event::pointer::PointerMotionAbsoluteEvent) {
|
|
||||||
let (x, y) = (
|
|
||||||
evt.absolute_x_transformed(self.screen_size.0),
|
|
||||||
evt.absolute_y_transformed(self.screen_size.1),
|
|
||||||
);
|
|
||||||
*self.pointer_location.borrow_mut() = (x, y);
|
|
||||||
let serial = self.next_serial();
|
|
||||||
let under = self.window_map.borrow().get_surface_under((x, y));
|
|
||||||
self.pointer.motion(
|
|
||||||
under.as_ref().map(|&(ref s, (x, y))| (s, x, y)),
|
|
||||||
serial,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
fn on_pointer_button(&mut self, _: &input::Seat, evt: event::pointer::PointerButtonEvent) {
|
|
||||||
let serial = self.next_serial();
|
|
||||||
let button = evt.button();
|
|
||||||
let state = match evt.state() {
|
|
||||||
input::MouseButtonState::Pressed => {
|
|
||||||
// change the keyboard focus
|
|
||||||
let under = self.window_map
|
|
||||||
.borrow_mut()
|
|
||||||
.get_surface_and_bring_to_top(*self.pointer_location.borrow());
|
|
||||||
self.keyboard
|
|
||||||
.set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
|
|
||||||
wl_pointer::ButtonState::Pressed
|
|
||||||
}
|
|
||||||
input::MouseButtonState::Released => wl_pointer::ButtonState::Released,
|
|
||||||
};
|
|
||||||
self.pointer.button(button, state, serial, evt.time());
|
|
||||||
}
|
|
||||||
fn on_pointer_axis(&mut self, _: &input::Seat, evt: event::pointer::PointerAxisEvent) {
|
|
||||||
let source = match evt.source() {
|
|
||||||
input::AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
|
|
||||||
input::AxisSource::Finger => wl_pointer::AxisSource::Finger,
|
|
||||||
input::AxisSource::Wheel | input::AxisSource::WheelTilt => {
|
|
||||||
wl_pointer::AxisSource::Wheel
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let horizontal_amount = evt.amount(&input::Axis::Horizontal)
|
|
||||||
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0);
|
|
||||||
let vertical_amount = evt.amount(&input::Axis::Vertical)
|
|
||||||
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Vertical).unwrap() * 3.0);
|
|
||||||
let horizontal_amount_discrete = evt.amount_discrete(&input::Axis::Horizontal);
|
|
||||||
let vertical_amount_discrete = evt.amount_discrete(&input::Axis::Vertical);
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut event = self.pointer.axis();
|
|
||||||
event.source(source);
|
|
||||||
if horizontal_amount != 0.0 {
|
|
||||||
event.value(
|
|
||||||
wl_pointer::Axis::HorizontalScroll,
|
|
||||||
horizontal_amount,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
if let Some(discrete) = horizontal_amount_discrete {
|
|
||||||
event.discrete(
|
|
||||||
wl_pointer::Axis::HorizontalScroll,
|
|
||||||
discrete as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if source == wl_pointer::AxisSource::Finger {
|
|
||||||
event.stop(
|
|
||||||
wl_pointer::Axis::HorizontalScroll,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if vertical_amount != 0.0 {
|
|
||||||
event.value(
|
|
||||||
wl_pointer::Axis::VerticalScroll,
|
|
||||||
vertical_amount,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
if let Some(discrete) = vertical_amount_discrete {
|
|
||||||
event.discrete(
|
|
||||||
wl_pointer::Axis::VerticalScroll,
|
|
||||||
discrete as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else if source == wl_pointer::AxisSource::Finger {
|
|
||||||
event.stop(
|
|
||||||
wl_pointer::Axis::VerticalScroll,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
event.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn on_touch_down(&mut self, _: &input::Seat, _: event::touch::TouchDownEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_motion(&mut self, _: &input::Seat, _: event::touch::TouchMotionEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_up(&mut self, _: &input::Seat, _: event::touch::TouchUpEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_cancel(&mut self, _: &input::Seat, _: event::touch::TouchCancelEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_frame(&mut self, _: &input::Seat, _: event::touch::TouchFrameEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_input_config_changed(&mut self, _: &mut [LibinputDevice]) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log: Logger) -> Result<(),()> {
|
|
||||||
|
|
||||||
|
pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log: Logger) -> Result<(), ()> {
|
||||||
let name = display.add_socket_auto().unwrap().into_string().unwrap();
|
let name = display.add_socket_auto().unwrap().into_string().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);
|
||||||
|
@ -358,17 +155,16 @@ pub fn run_udev(mut display: Display, mut event_loop: EventLoop, log: Logger) ->
|
||||||
let libinput_session_id = notifier.register(&mut libinput_context);
|
let libinput_session_id = notifier.register(&mut libinput_context);
|
||||||
libinput_context.udev_assign_seat(&seat).unwrap();
|
libinput_context.udev_assign_seat(&seat).unwrap();
|
||||||
let mut libinput_backend = LibinputInputBackend::new(libinput_context, log.clone());
|
let mut libinput_backend = LibinputInputBackend::new(libinput_context, log.clone());
|
||||||
libinput_backend.set_handler(LibinputInputHandler {
|
libinput_backend.set_handler(AnvilInputHandler::new_with_session(
|
||||||
log: log.clone(),
|
log.clone(),
|
||||||
pointer,
|
pointer,
|
||||||
keyboard,
|
keyboard,
|
||||||
window_map: window_map.clone(),
|
window_map.clone(),
|
||||||
|
(w, h),
|
||||||
|
running.clone(),
|
||||||
pointer_location,
|
pointer_location,
|
||||||
screen_size: (w, h),
|
session,
|
||||||
serial: 0,
|
));
|
||||||
session: session,
|
|
||||||
running: running.clone(),
|
|
||||||
});
|
|
||||||
let libinput_event_source = libinput_bind(libinput_backend, event_loop.token())
|
let libinput_event_source = libinput_bind(libinput_backend, event_loop.token())
|
||||||
.map_err(|(err, _)| err)
|
.map_err(|(err, _)| err)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -1,161 +1,27 @@
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::AtomicBool;
|
||||||
|
|
||||||
use smithay::wayland::shm::init_shm_global;
|
use smithay::wayland::shm::init_shm_global;
|
||||||
use smithay::wayland::seat::{KeyboardHandle, PointerHandle, Seat};
|
use smithay::wayland::seat::Seat;
|
||||||
use smithay::wayland::compositor::{SubsurfaceRole, TraversalAction};
|
use smithay::wayland::compositor::{SubsurfaceRole, TraversalAction};
|
||||||
use smithay::wayland::compositor::roles::Role;
|
use smithay::wayland::compositor::roles::Role;
|
||||||
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
use smithay::wayland::output::{Mode, Output, PhysicalProperties};
|
||||||
use smithay::backend::input::{self, Event, InputBackend, InputHandler, KeyboardKeyEvent, PointerAxisEvent,
|
use smithay::backend::input::InputBackend;
|
||||||
PointerButtonEvent, PointerMotionAbsoluteEvent};
|
|
||||||
use smithay::backend::winit;
|
use smithay::backend::winit;
|
||||||
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
use smithay::backend::graphics::egl::EGLGraphicsBackend;
|
||||||
use smithay::backend::graphics::egl::wayland::{EGLWaylandExtensions, Format};
|
use smithay::backend::graphics::egl::wayland::{EGLWaylandExtensions, Format};
|
||||||
use smithay::wayland_server::{Display, EventLoop};
|
use smithay::wayland_server::{Display, EventLoop};
|
||||||
use smithay::wayland_server::protocol::{wl_pointer, wl_output};
|
use smithay::wayland_server::protocol::wl_output;
|
||||||
|
|
||||||
use glium::Surface;
|
use glium::Surface;
|
||||||
|
|
||||||
use slog::Logger;
|
use slog::Logger;
|
||||||
|
|
||||||
use glium_drawer::GliumDrawer;
|
use glium_drawer::GliumDrawer;
|
||||||
use shell::{init_shell, MyWindowMap, Buffer};
|
use shell::{init_shell, Buffer};
|
||||||
|
use input_handler::AnvilInputHandler;
|
||||||
struct WinitInputHandler {
|
|
||||||
log: Logger,
|
|
||||||
pointer: PointerHandle,
|
|
||||||
keyboard: KeyboardHandle,
|
|
||||||
window_map: Rc<RefCell<MyWindowMap>>,
|
|
||||||
pointer_location: (f64, f64),
|
|
||||||
serial: u32,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WinitInputHandler {
|
|
||||||
fn next_serial(&mut self) -> u32 {
|
|
||||||
self.serial += 1;
|
|
||||||
self.serial
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl InputHandler<winit::WinitInputBackend> for WinitInputHandler {
|
|
||||||
fn on_seat_created(&mut self, _: &input::Seat) {
|
|
||||||
/* never happens with winit */
|
|
||||||
}
|
|
||||||
fn on_seat_destroyed(&mut self, _: &input::Seat) {
|
|
||||||
/* never happens with winit */
|
|
||||||
}
|
|
||||||
fn on_seat_changed(&mut self, _: &input::Seat) {
|
|
||||||
/* never happens with winit */
|
|
||||||
}
|
|
||||||
fn on_keyboard_key(&mut self, _: &input::Seat, evt: winit::WinitKeyboardInputEvent) {
|
|
||||||
let keycode = evt.key_code();
|
|
||||||
let state = evt.state();
|
|
||||||
debug!(self.log, "key"; "keycode" => keycode, "state" => format!("{:?}", state));
|
|
||||||
let serial = self.next_serial();
|
|
||||||
self.keyboard
|
|
||||||
.input(keycode, state, serial, evt.time(), |_, _| true);
|
|
||||||
}
|
|
||||||
fn on_pointer_move(&mut self, _: &input::Seat, _: input::UnusedEvent) {
|
|
||||||
/* never happens with winit */
|
|
||||||
}
|
|
||||||
fn on_pointer_move_absolute(&mut self, _: &input::Seat, evt: winit::WinitMouseMovedEvent) {
|
|
||||||
// on winit, mouse events are already in pixel coordinates
|
|
||||||
let (x, y) = evt.position();
|
|
||||||
self.pointer_location = (x, y);
|
|
||||||
let serial = self.next_serial();
|
|
||||||
let under = self.window_map.borrow().get_surface_under((x, y));
|
|
||||||
self.pointer.motion(
|
|
||||||
under.as_ref().map(|&(ref s, (x, y))| (s, x, y)),
|
|
||||||
serial,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
fn on_pointer_button(&mut self, _: &input::Seat, evt: winit::WinitMouseInputEvent) {
|
|
||||||
let serial = self.next_serial();
|
|
||||||
let button = match evt.button() {
|
|
||||||
input::MouseButton::Left => 0x110,
|
|
||||||
input::MouseButton::Right => 0x111,
|
|
||||||
input::MouseButton::Middle => 0x112,
|
|
||||||
input::MouseButton::Other(b) => b as u32,
|
|
||||||
};
|
|
||||||
let state = match evt.state() {
|
|
||||||
input::MouseButtonState::Pressed => {
|
|
||||||
// change the keyboard focus
|
|
||||||
let under = self.window_map
|
|
||||||
.borrow_mut()
|
|
||||||
.get_surface_and_bring_to_top(self.pointer_location);
|
|
||||||
self.keyboard
|
|
||||||
.set_focus(under.as_ref().map(|&(ref s, _)| s), serial);
|
|
||||||
wl_pointer::ButtonState::Pressed
|
|
||||||
}
|
|
||||||
input::MouseButtonState::Released => wl_pointer::ButtonState::Released,
|
|
||||||
};
|
|
||||||
self.pointer.button(button, state, serial, evt.time());
|
|
||||||
}
|
|
||||||
fn on_pointer_axis(&mut self, _: &input::Seat, evt: winit::WinitMouseWheelEvent) {
|
|
||||||
let source = match evt.source() {
|
|
||||||
input::AxisSource::Continuous => wl_pointer::AxisSource::Continuous,
|
|
||||||
input::AxisSource::Wheel => wl_pointer::AxisSource::Wheel,
|
|
||||||
_ => unreachable!(), //winit does not have more specific sources
|
|
||||||
};
|
|
||||||
let horizontal_amount = evt.amount(&input::Axis::Horizontal)
|
|
||||||
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Horizontal).unwrap() * 3.0);
|
|
||||||
let vertical_amount = evt.amount(&input::Axis::Vertical)
|
|
||||||
.unwrap_or_else(|| evt.amount_discrete(&input::Axis::Vertical).unwrap() * 3.0);
|
|
||||||
let horizontal_amount_discrete = evt.amount_discrete(&input::Axis::Horizontal);
|
|
||||||
let vertical_amount_discrete = evt.amount_discrete(&input::Axis::Vertical);
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut event = self.pointer.axis();
|
|
||||||
event.source(source);
|
|
||||||
if horizontal_amount != 0.0 {
|
|
||||||
event.value(
|
|
||||||
wl_pointer::Axis::HorizontalScroll,
|
|
||||||
horizontal_amount,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
if let Some(discrete) = horizontal_amount_discrete {
|
|
||||||
event.discrete(
|
|
||||||
wl_pointer::Axis::HorizontalScroll,
|
|
||||||
discrete as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if vertical_amount != 0.0 {
|
|
||||||
event.value(
|
|
||||||
wl_pointer::Axis::VerticalScroll,
|
|
||||||
vertical_amount,
|
|
||||||
evt.time(),
|
|
||||||
);
|
|
||||||
if let Some(discrete) = vertical_amount_discrete {
|
|
||||||
event.discrete(
|
|
||||||
wl_pointer::Axis::VerticalScroll,
|
|
||||||
discrete as i32,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
event.done();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn on_touch_down(&mut self, _: &input::Seat, _: winit::WinitTouchStartedEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_motion(&mut self, _: &input::Seat, _: winit::WinitTouchMovedEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_up(&mut self, _: &input::Seat, _: winit::WinitTouchEndedEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_cancel(&mut self, _: &input::Seat, _: winit::WinitTouchCancelledEvent) {
|
|
||||||
/* not done in this example */
|
|
||||||
}
|
|
||||||
fn on_touch_frame(&mut self, _: &input::Seat, _: input::UnusedEvent) {
|
|
||||||
/* never happens with winit */
|
|
||||||
}
|
|
||||||
fn on_input_config_changed(&mut self, _: &mut ()) {
|
|
||||||
/* never happens with winit */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop, log: Logger) -> Result<(), ()> {
|
pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop, log: Logger) -> Result<(), ()> {
|
||||||
let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
|
let (renderer, mut input) = winit::init(log.clone()).map_err(|_| ())?;
|
||||||
|
@ -176,6 +42,8 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop, log: Logger)
|
||||||
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);
|
||||||
|
|
||||||
|
let running = Arc::new(AtomicBool::new(true));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the globals
|
* Initialize the globals
|
||||||
*/
|
*/
|
||||||
|
@ -185,12 +53,7 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop, log: Logger)
|
||||||
let (compositor_token, _, _, window_map) =
|
let (compositor_token, _, _, window_map) =
|
||||||
init_shell(display, event_loop.token(), log.clone(), egl_display);
|
init_shell(display, event_loop.token(), log.clone(), egl_display);
|
||||||
|
|
||||||
let (mut seat, _) = Seat::new(
|
let (mut seat, _) = Seat::new(display, event_loop.token(), "winit".into(), log.clone());
|
||||||
display,
|
|
||||||
event_loop.token(),
|
|
||||||
"winit".into(),
|
|
||||||
log.clone(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let pointer = seat.add_pointer();
|
let pointer = seat.add_pointer();
|
||||||
let keyboard = seat.add_keyboard("", "fr", "oss", None, 1000, 500)
|
let keyboard = seat.add_keyboard("", "fr", "oss", None, 1000, 500)
|
||||||
|
@ -225,14 +88,15 @@ pub fn run_winit(display: &mut Display, event_loop: &mut EventLoop, log: Logger)
|
||||||
refresh: 60_000,
|
refresh: 60_000,
|
||||||
});
|
});
|
||||||
|
|
||||||
input.set_handler(WinitInputHandler {
|
input.set_handler(AnvilInputHandler::new(
|
||||||
log: log.clone(),
|
log.clone(),
|
||||||
pointer,
|
pointer,
|
||||||
keyboard,
|
keyboard,
|
||||||
window_map: window_map.clone(),
|
window_map.clone(),
|
||||||
pointer_location: (0.0, 0.0),
|
(0, 0),
|
||||||
serial: 0,
|
running.clone(),
|
||||||
});
|
Rc::new(RefCell::new((0.0, 0.0))),
|
||||||
|
));
|
||||||
|
|
||||||
info!(log, "Initialization completed, starting the main loop.");
|
info!(log, "Initialization completed, starting the main loop.");
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ use std::sync::{Arc, Mutex};
|
||||||
mod keyboard;
|
mod keyboard;
|
||||||
mod pointer;
|
mod pointer;
|
||||||
|
|
||||||
pub use self::keyboard::{Error as KeyboardError, KeyboardHandle, ModifiersState, Keysym, keysyms};
|
pub use self::keyboard::{keysyms, Error as KeyboardError, KeyboardHandle, Keysym, ModifiersState};
|
||||||
pub use self::pointer::{PointerAxisHandle, PointerHandle};
|
pub use self::pointer::{PointerAxisHandle, PointerHandle};
|
||||||
use wayland_server::{Display, Global, LoopToken, NewResource, Resource};
|
use wayland_server::{Display, Global, LoopToken, NewResource, Resource};
|
||||||
use wayland_server::protocol::wl_seat;
|
use wayland_server::protocol::wl_seat;
|
||||||
|
|
Loading…
Reference in New Issue