mirror of
https://codeberg.org/waydeer/layer-shika.git
synced 2026-01-22 08:15:54 +00:00
refactor: extract input handling
This commit is contained in:
parent
d5b4953c1a
commit
4be98d3ba5
9 changed files with 533 additions and 246 deletions
90
crates/adapters/src/wayland/input/keyboard.rs
Normal file
90
crates/adapters/src/wayland/input/keyboard.rs
Normal file
|
|
@ -0,0 +1,90 @@
|
||||||
|
use crate::wayland::surfaces::keyboard_state::{KeyboardState, keysym_to_text};
|
||||||
|
use slint::{SharedString, platform::WindowEvent};
|
||||||
|
use wayland_client::{
|
||||||
|
Proxy,
|
||||||
|
backend::ObjectId,
|
||||||
|
protocol::{wl_keyboard, wl_surface::WlSurface},
|
||||||
|
};
|
||||||
|
use xkbcommon::xkb;
|
||||||
|
|
||||||
|
use super::state::KeyboardInputState;
|
||||||
|
|
||||||
|
pub trait KeyboardEventTarget {
|
||||||
|
fn dispatch_event(&self, event: WindowEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait KeyboardSurfaceResolver {
|
||||||
|
type Target: KeyboardEventTarget;
|
||||||
|
|
||||||
|
fn find_surface(&self, surface_id: &ObjectId) -> Option<&Self::Target>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_keyboard_enter<R: KeyboardSurfaceResolver>(
|
||||||
|
input_state: &mut KeyboardInputState,
|
||||||
|
resolver: &R,
|
||||||
|
surface: &WlSurface,
|
||||||
|
) -> bool {
|
||||||
|
let surface_id = surface.id();
|
||||||
|
if resolver.find_surface(&surface_id).is_some() {
|
||||||
|
input_state.set_focused_surface(Some(surface_id));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_keyboard_leave(input_state: &mut KeyboardInputState, surface: &WlSurface) -> bool {
|
||||||
|
let surface_id = surface.id();
|
||||||
|
if input_state.focused_surface_id() == Some(&surface_id) {
|
||||||
|
input_state.set_focused_surface(None);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_keyboard_key<R: KeyboardSurfaceResolver>(
|
||||||
|
input_state: &KeyboardInputState,
|
||||||
|
resolver: &R,
|
||||||
|
key: u32,
|
||||||
|
state: wl_keyboard::KeyState,
|
||||||
|
keyboard_state: &mut KeyboardState,
|
||||||
|
) -> bool {
|
||||||
|
let Some(surface_id) = input_state.focused_surface_id().cloned() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Some(target) = resolver.find_surface(&surface_id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Some(xkb_state) = keyboard_state.xkb_state.as_mut() else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
let keycode = xkb::Keycode::new(key + 8);
|
||||||
|
let direction = match state {
|
||||||
|
wl_keyboard::KeyState::Pressed => xkb::KeyDirection::Down,
|
||||||
|
wl_keyboard::KeyState::Released => xkb::KeyDirection::Up,
|
||||||
|
_ => return true,
|
||||||
|
};
|
||||||
|
|
||||||
|
xkb_state.update_key(keycode, direction);
|
||||||
|
|
||||||
|
let text = xkb_state.key_get_utf8(keycode);
|
||||||
|
let text = if text.is_empty() {
|
||||||
|
let keysym = xkb_state.key_get_one_sym(keycode);
|
||||||
|
keysym_to_text(keysym)
|
||||||
|
} else {
|
||||||
|
Some(SharedString::from(text.as_str()))
|
||||||
|
};
|
||||||
|
|
||||||
|
let Some(text) = text else {
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
let event = match state {
|
||||||
|
wl_keyboard::KeyState::Pressed => WindowEvent::KeyPressed { text },
|
||||||
|
wl_keyboard::KeyState::Released => WindowEvent::KeyReleased { text },
|
||||||
|
_ => return true,
|
||||||
|
};
|
||||||
|
|
||||||
|
target.dispatch_event(event);
|
||||||
|
true
|
||||||
|
}
|
||||||
7
crates/adapters/src/wayland/input/mod.rs
Normal file
7
crates/adapters/src/wayland/input/mod.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
pub mod keyboard;
|
||||||
|
pub mod pointer;
|
||||||
|
pub mod state;
|
||||||
|
|
||||||
|
pub use keyboard::{KeyboardEventTarget, KeyboardSurfaceResolver};
|
||||||
|
pub use pointer::{PointerEventTarget, PointerSurfaceResolver};
|
||||||
|
pub use state::{KeyboardInputState, PointerInputState};
|
||||||
196
crates/adapters/src/wayland/input/pointer.rs
Normal file
196
crates/adapters/src/wayland/input/pointer.rs
Normal file
|
|
@ -0,0 +1,196 @@
|
||||||
|
use crate::wayland::surfaces::pointer_utils::wayland_button_to_slint;
|
||||||
|
use slint::{LogicalPosition, platform::WindowEvent};
|
||||||
|
use wayland_client::{
|
||||||
|
Proxy, WEnum,
|
||||||
|
backend::ObjectId,
|
||||||
|
protocol::{wl_pointer, wl_surface::WlSurface},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::state::PointerInputState;
|
||||||
|
|
||||||
|
pub trait PointerEventTarget {
|
||||||
|
fn to_logical_position(&self, surface_x: f64, surface_y: f64) -> LogicalPosition;
|
||||||
|
fn dispatch_event(&self, event: WindowEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait PointerSurfaceResolver {
|
||||||
|
type Target: PointerEventTarget;
|
||||||
|
|
||||||
|
fn find_surface(&self, surface_id: &ObjectId) -> Option<&Self::Target>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_pointer_enter<R: PointerSurfaceResolver>(
|
||||||
|
input_state: &mut PointerInputState,
|
||||||
|
resolver: &R,
|
||||||
|
_serial: u32,
|
||||||
|
surface: &WlSurface,
|
||||||
|
surface_x: f64,
|
||||||
|
surface_y: f64,
|
||||||
|
) -> bool {
|
||||||
|
let surface_id = surface.id();
|
||||||
|
let Some(target) = resolver.find_surface(&surface_id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let position = target.to_logical_position(surface_x, surface_y);
|
||||||
|
input_state.set_active_surface(Some(surface_id));
|
||||||
|
input_state.set_current_position(position);
|
||||||
|
|
||||||
|
target.dispatch_event(WindowEvent::PointerMoved { position });
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_pointer_motion<R: PointerSurfaceResolver>(
|
||||||
|
input_state: &mut PointerInputState,
|
||||||
|
resolver: &R,
|
||||||
|
surface_x: f64,
|
||||||
|
surface_y: f64,
|
||||||
|
) -> bool {
|
||||||
|
let Some(surface_id) = input_state.active_surface_id().cloned() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Some(target) = resolver.find_surface(&surface_id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let position = target.to_logical_position(surface_x, surface_y);
|
||||||
|
input_state.set_current_position(position);
|
||||||
|
|
||||||
|
target.dispatch_event(WindowEvent::PointerMoved { position });
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_pointer_leave<R: PointerSurfaceResolver>(
|
||||||
|
input_state: &mut PointerInputState,
|
||||||
|
resolver: &R,
|
||||||
|
) -> bool {
|
||||||
|
let Some(surface_id) = input_state.active_surface_id().cloned() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(target) = resolver.find_surface(&surface_id) {
|
||||||
|
target.dispatch_event(WindowEvent::PointerExited);
|
||||||
|
}
|
||||||
|
|
||||||
|
input_state.set_active_surface(None);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_pointer_button<R: PointerSurfaceResolver>(
|
||||||
|
input_state: &PointerInputState,
|
||||||
|
resolver: &R,
|
||||||
|
_scale_factor: f32,
|
||||||
|
_serial: u32,
|
||||||
|
button: u32,
|
||||||
|
button_state: WEnum<wl_pointer::ButtonState>,
|
||||||
|
) -> bool {
|
||||||
|
let Some(surface_id) = input_state.active_surface_id() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let Some(target) = resolver.find_surface(surface_id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let position = input_state.current_position();
|
||||||
|
let slint_button = wayland_button_to_slint(button);
|
||||||
|
|
||||||
|
let event = match button_state {
|
||||||
|
WEnum::Value(wl_pointer::ButtonState::Pressed) => WindowEvent::PointerPressed {
|
||||||
|
button: slint_button,
|
||||||
|
position,
|
||||||
|
},
|
||||||
|
WEnum::Value(wl_pointer::ButtonState::Released) => WindowEvent::PointerReleased {
|
||||||
|
button: slint_button,
|
||||||
|
position,
|
||||||
|
},
|
||||||
|
_ => return true,
|
||||||
|
};
|
||||||
|
|
||||||
|
target.dispatch_event(event);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_axis_source(
|
||||||
|
input_state: &PointerInputState,
|
||||||
|
_axis_source: wl_pointer::AxisSource,
|
||||||
|
) -> bool {
|
||||||
|
input_state.has_active_surface()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_axis(
|
||||||
|
input_state: &mut PointerInputState,
|
||||||
|
axis: wl_pointer::Axis,
|
||||||
|
value: f64,
|
||||||
|
) -> bool {
|
||||||
|
if !input_state.has_active_surface() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
let delta = value as f32;
|
||||||
|
|
||||||
|
match axis {
|
||||||
|
wl_pointer::Axis::HorizontalScroll => {
|
||||||
|
input_state.accumulate_axis_value(delta, 0.0);
|
||||||
|
}
|
||||||
|
wl_pointer::Axis::VerticalScroll => {
|
||||||
|
input_state.accumulate_axis_value(0.0, delta);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_axis_discrete(
|
||||||
|
input_state: &mut PointerInputState,
|
||||||
|
axis: wl_pointer::Axis,
|
||||||
|
discrete: i32,
|
||||||
|
) -> bool {
|
||||||
|
if !input_state.has_active_surface() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cast_precision_loss)]
|
||||||
|
let delta = (discrete as f32) * 60.0;
|
||||||
|
|
||||||
|
match axis {
|
||||||
|
wl_pointer::Axis::HorizontalScroll => {
|
||||||
|
input_state.accumulate_axis_value(delta, 0.0);
|
||||||
|
}
|
||||||
|
wl_pointer::Axis::VerticalScroll => {
|
||||||
|
input_state.accumulate_axis_value(0.0, delta);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_axis_stop(_input_state: &PointerInputState, _axis: wl_pointer::Axis) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_pointer_frame<R: PointerSurfaceResolver>(
|
||||||
|
input_state: &mut PointerInputState,
|
||||||
|
resolver: &R,
|
||||||
|
) -> bool {
|
||||||
|
let Some(surface_id) = input_state.active_surface_id().cloned() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
let (delta_x, delta_y) = input_state.take_accumulated_axis();
|
||||||
|
|
||||||
|
let Some(target) = resolver.find_surface(&surface_id) else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if delta_x.abs() > f32::EPSILON || delta_y.abs() > f32::EPSILON {
|
||||||
|
let position = input_state.current_position();
|
||||||
|
target.dispatch_event(WindowEvent::PointerScrolled {
|
||||||
|
position,
|
||||||
|
delta_x,
|
||||||
|
delta_y,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
112
crates/adapters/src/wayland/input/state.rs
Normal file
112
crates/adapters/src/wayland/input/state.rs
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
use slint::LogicalPosition;
|
||||||
|
use wayland_client::backend::ObjectId;
|
||||||
|
|
||||||
|
pub struct PointerInputState {
|
||||||
|
active_surface_id: Option<ObjectId>,
|
||||||
|
current_position: LogicalPosition,
|
||||||
|
accumulated_axis_x: f32,
|
||||||
|
accumulated_axis_y: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PointerInputState {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
active_surface_id: None,
|
||||||
|
current_position: LogicalPosition::new(0.0, 0.0),
|
||||||
|
accumulated_axis_x: 0.0,
|
||||||
|
accumulated_axis_y: 0.0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn active_surface_id(&self) -> Option<&ObjectId> {
|
||||||
|
self.active_surface_id.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_active_surface(&mut self, surface_id: Option<ObjectId>) {
|
||||||
|
self.active_surface_id = surface_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn current_position(&self) -> LogicalPosition {
|
||||||
|
self.current_position
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_current_position(&mut self, position: LogicalPosition) {
|
||||||
|
self.current_position = position;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn accumulate_axis_value(&mut self, delta_x: f32, delta_y: f32) {
|
||||||
|
self.accumulated_axis_x += delta_x;
|
||||||
|
self.accumulated_axis_y += delta_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn take_accumulated_axis(&mut self) -> (f32, f32) {
|
||||||
|
let delta_x = self.accumulated_axis_x;
|
||||||
|
let delta_y = self.accumulated_axis_y;
|
||||||
|
self.accumulated_axis_x = 0.0;
|
||||||
|
self.accumulated_axis_y = 0.0;
|
||||||
|
(delta_x, delta_y)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.active_surface_id = None;
|
||||||
|
self.current_position = LogicalPosition::new(0.0, 0.0);
|
||||||
|
self.accumulated_axis_x = 0.0;
|
||||||
|
self.accumulated_axis_y = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_surface_if_matches(&mut self, surface_id: &ObjectId) {
|
||||||
|
if self.active_surface_id.as_ref() == Some(surface_id) {
|
||||||
|
self.active_surface_id = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn has_active_surface(&self) -> bool {
|
||||||
|
self.active_surface_id.is_some()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PointerInputState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct KeyboardInputState {
|
||||||
|
focused_surface_id: Option<ObjectId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyboardInputState {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
focused_surface_id: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn focused_surface_id(&self) -> Option<&ObjectId> {
|
||||||
|
self.focused_surface_id.as_ref()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_focused_surface(&mut self, surface_id: Option<ObjectId>) {
|
||||||
|
self.focused_surface_id = surface_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn reset(&mut self) {
|
||||||
|
self.focused_surface_id = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_surface_if_matches(&mut self, surface_id: &ObjectId) {
|
||||||
|
if self.focused_surface_id.as_ref() == Some(surface_id) {
|
||||||
|
self.focused_surface_id = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn has_focused_surface(&self) -> bool {
|
||||||
|
self.focused_surface_id.is_some()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for KeyboardInputState {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
pub(crate) mod config;
|
pub(crate) mod config;
|
||||||
pub(crate) mod event_handling;
|
pub(crate) mod event_handling;
|
||||||
pub(crate) mod globals;
|
pub(crate) mod globals;
|
||||||
|
pub(crate) mod input;
|
||||||
pub(crate) mod managed_proxies;
|
pub(crate) mod managed_proxies;
|
||||||
pub mod ops;
|
pub mod ops;
|
||||||
pub(crate) mod outputs;
|
pub(crate) mod outputs;
|
||||||
|
|
|
||||||
|
|
@ -1,87 +1,113 @@
|
||||||
use crate::wayland::surfaces::keyboard_state::{KeyboardState, keysym_to_text};
|
use crate::wayland::input::keyboard::{
|
||||||
use crate::wayland::surfaces::pointer_utils::wayland_button_to_slint;
|
handle_keyboard_enter as shared_keyboard_enter, handle_keyboard_key as shared_keyboard_key,
|
||||||
use log::info;
|
handle_keyboard_leave as shared_keyboard_leave,
|
||||||
use slint::{
|
|
||||||
LogicalPosition, SharedString,
|
|
||||||
platform::{WindowAdapter, WindowEvent},
|
|
||||||
};
|
};
|
||||||
|
use crate::wayland::input::pointer::{
|
||||||
|
handle_axis as shared_axis, handle_axis_discrete as shared_axis_discrete,
|
||||||
|
handle_axis_source as shared_axis_source, handle_axis_stop as shared_axis_stop,
|
||||||
|
handle_pointer_button as shared_pointer_button, handle_pointer_enter as shared_pointer_enter,
|
||||||
|
handle_pointer_frame as shared_pointer_frame, handle_pointer_leave as shared_pointer_leave,
|
||||||
|
handle_pointer_motion as shared_pointer_motion,
|
||||||
|
};
|
||||||
|
use crate::wayland::input::{
|
||||||
|
KeyboardEventTarget, KeyboardInputState, KeyboardSurfaceResolver, PointerEventTarget,
|
||||||
|
PointerInputState, PointerSurfaceResolver,
|
||||||
|
};
|
||||||
|
use crate::wayland::surfaces::keyboard_state::KeyboardState;
|
||||||
|
use slint::{LogicalPosition, platform::WindowEvent};
|
||||||
use wayland_client::{
|
use wayland_client::{
|
||||||
Proxy, WEnum,
|
WEnum,
|
||||||
backend::ObjectId,
|
backend::ObjectId,
|
||||||
protocol::{wl_keyboard, wl_pointer, wl_surface::WlSurface},
|
protocol::{wl_keyboard, wl_pointer, wl_surface::WlSurface},
|
||||||
};
|
};
|
||||||
use xkbcommon::xkb;
|
|
||||||
|
|
||||||
use super::state::ActiveLockSurface;
|
use super::state::ActiveLockSurface;
|
||||||
|
|
||||||
pub(super) struct InputState {
|
pub(super) struct InputState {
|
||||||
pub active_pointer_surface_id: Option<ObjectId>,
|
pub pointer: PointerInputState,
|
||||||
pub keyboard_focus_surface_id: Option<ObjectId>,
|
pub keyboard: KeyboardInputState,
|
||||||
pub current_pointer_position: LogicalPosition,
|
|
||||||
pub accumulated_axis_x: f32,
|
|
||||||
pub accumulated_axis_y: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputState {
|
impl InputState {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
active_pointer_surface_id: None,
|
pointer: PointerInputState::new(),
|
||||||
keyboard_focus_surface_id: None,
|
keyboard: KeyboardInputState::new(),
|
||||||
current_pointer_position: LogicalPosition::new(0.0, 0.0),
|
|
||||||
accumulated_axis_x: 0.0,
|
|
||||||
accumulated_axis_y: 0.0,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.active_pointer_surface_id = None;
|
self.pointer.reset();
|
||||||
self.keyboard_focus_surface_id = None;
|
self.keyboard.reset();
|
||||||
self.current_pointer_position = LogicalPosition::new(0.0, 0.0);
|
|
||||||
self.accumulated_axis_x = 0.0;
|
|
||||||
self.accumulated_axis_y = 0.0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clear_surface_refs(&mut self, surface_id: &ObjectId) {
|
pub fn clear_surface_refs(&mut self, surface_id: &ObjectId) {
|
||||||
if self.active_pointer_surface_id.as_ref() == Some(surface_id) {
|
self.pointer.clear_surface_if_matches(surface_id);
|
||||||
self.active_pointer_surface_id = None;
|
self.keyboard.clear_surface_if_matches(surface_id);
|
||||||
}
|
|
||||||
if self.keyboard_focus_surface_id.as_ref() == Some(surface_id) {
|
|
||||||
self.keyboard_focus_surface_id = None;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn has_active_pointer(&self) -> bool {
|
pub const fn has_active_pointer(&self) -> bool {
|
||||||
self.active_pointer_surface_id.is_some()
|
self.pointer.has_active_surface()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn has_keyboard_focus(&self) -> bool {
|
pub const fn has_keyboard_focus(&self) -> bool {
|
||||||
self.keyboard_focus_surface_id.is_some()
|
self.keyboard.has_focused_surface()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PointerEventTarget for ActiveLockSurface {
|
||||||
|
fn to_logical_position(&self, surface_x: f64, surface_y: f64) -> LogicalPosition {
|
||||||
|
ActiveLockSurface::to_logical_position(self, surface_x, surface_y)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn dispatch_event(&self, event: WindowEvent) {
|
||||||
|
ActiveLockSurface::dispatch_event(self, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyboardEventTarget for ActiveLockSurface {
|
||||||
|
fn dispatch_event(&self, event: WindowEvent) {
|
||||||
|
ActiveLockSurface::dispatch_event(self, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LockSurfaceResolver<'a> {
|
||||||
|
lock_surfaces: &'a [(ObjectId, ActiveLockSurface)],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PointerSurfaceResolver for LockSurfaceResolver<'_> {
|
||||||
|
type Target = ActiveLockSurface;
|
||||||
|
|
||||||
|
fn find_surface(&self, surface_id: &ObjectId) -> Option<&Self::Target> {
|
||||||
|
find_surface_by_surface_id(self.lock_surfaces, surface_id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyboardSurfaceResolver for LockSurfaceResolver<'_> {
|
||||||
|
type Target = ActiveLockSurface;
|
||||||
|
|
||||||
|
fn find_surface(&self, surface_id: &ObjectId) -> Option<&Self::Target> {
|
||||||
|
find_surface_by_surface_id(self.lock_surfaces, surface_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_pointer_enter(
|
pub(super) fn handle_pointer_enter(
|
||||||
input_state: &mut InputState,
|
input_state: &mut InputState,
|
||||||
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
||||||
_serial: u32,
|
serial: u32,
|
||||||
surface: &WlSurface,
|
surface: &WlSurface,
|
||||||
surface_x: f64,
|
surface_x: f64,
|
||||||
surface_y: f64,
|
surface_y: f64,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let surface_id = surface.id();
|
let resolver = LockSurfaceResolver { lock_surfaces };
|
||||||
let Some(active_surface) = find_surface_by_surface_id(lock_surfaces, &surface_id) else {
|
shared_pointer_enter(
|
||||||
return false;
|
&mut input_state.pointer,
|
||||||
};
|
&resolver,
|
||||||
|
serial,
|
||||||
let position = active_surface.to_logical_position(surface_x, surface_y);
|
surface,
|
||||||
let window = active_surface.window_rc();
|
surface_x,
|
||||||
|
surface_y,
|
||||||
input_state.active_pointer_surface_id = Some(surface_id.clone());
|
)
|
||||||
input_state.current_pointer_position = position;
|
|
||||||
info!("Lock pointer enter on {:?}", surface_id);
|
|
||||||
window
|
|
||||||
.window()
|
|
||||||
.dispatch_event(WindowEvent::PointerMoved { position });
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_pointer_motion(
|
pub(super) fn handle_pointer_motion(
|
||||||
|
|
@ -90,80 +116,42 @@ pub(super) fn handle_pointer_motion(
|
||||||
surface_x: f64,
|
surface_x: f64,
|
||||||
surface_y: f64,
|
surface_y: f64,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(surface_id) = input_state.active_pointer_surface_id.clone() else {
|
let resolver = LockSurfaceResolver { lock_surfaces };
|
||||||
return false;
|
shared_pointer_motion(&mut input_state.pointer, &resolver, surface_x, surface_y)
|
||||||
};
|
|
||||||
let Some(active_surface) = find_surface_by_surface_id(lock_surfaces, &surface_id) else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
let position = active_surface.to_logical_position(surface_x, surface_y);
|
|
||||||
let window = active_surface.window_rc();
|
|
||||||
|
|
||||||
input_state.current_pointer_position = position;
|
|
||||||
window
|
|
||||||
.window()
|
|
||||||
.dispatch_event(WindowEvent::PointerMoved { position });
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_pointer_leave(
|
pub(super) fn handle_pointer_leave(
|
||||||
input_state: &mut InputState,
|
input_state: &mut InputState,
|
||||||
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(surface_id) = input_state.active_pointer_surface_id.take() else {
|
let resolver = LockSurfaceResolver { lock_surfaces };
|
||||||
return false;
|
shared_pointer_leave(&mut input_state.pointer, &resolver)
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(active_surface) = find_surface_by_surface_id(lock_surfaces, &surface_id) {
|
|
||||||
active_surface.dispatch_event(WindowEvent::PointerExited);
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_pointer_button(
|
pub(super) fn handle_pointer_button(
|
||||||
input_state: &mut InputState,
|
input_state: &mut InputState,
|
||||||
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
_serial: u32,
|
serial: u32,
|
||||||
button: u32,
|
button: u32,
|
||||||
button_state: WEnum<wl_pointer::ButtonState>,
|
button_state: WEnum<wl_pointer::ButtonState>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(surface_id) = input_state.active_pointer_surface_id.clone() else {
|
let resolver = LockSurfaceResolver { lock_surfaces };
|
||||||
return false;
|
shared_pointer_button(
|
||||||
};
|
&input_state.pointer,
|
||||||
let Some(active_surface) = find_surface_by_surface_id(lock_surfaces, &surface_id) else {
|
&resolver,
|
||||||
return false;
|
scale_factor,
|
||||||
};
|
serial,
|
||||||
|
button,
|
||||||
let window = active_surface.window_rc();
|
button_state,
|
||||||
let position = input_state.current_pointer_position;
|
)
|
||||||
let slint_button = wayland_button_to_slint(button);
|
|
||||||
let event = match button_state {
|
|
||||||
WEnum::Value(wl_pointer::ButtonState::Pressed) => WindowEvent::PointerPressed {
|
|
||||||
button: slint_button,
|
|
||||||
position,
|
|
||||||
},
|
|
||||||
WEnum::Value(wl_pointer::ButtonState::Released) => WindowEvent::PointerReleased {
|
|
||||||
button: slint_button,
|
|
||||||
position,
|
|
||||||
},
|
|
||||||
_ => return true,
|
|
||||||
};
|
|
||||||
|
|
||||||
info!(
|
|
||||||
"Lock pointer button {:?} at {:?} (scale {})",
|
|
||||||
button_state, position, scale_factor
|
|
||||||
);
|
|
||||||
window.window().dispatch_event(event);
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_axis_source(
|
pub(super) fn handle_axis_source(
|
||||||
input_state: &InputState,
|
input_state: &InputState,
|
||||||
_axis_source: wl_pointer::AxisSource,
|
axis_source: wl_pointer::AxisSource,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
input_state.active_pointer_surface_id.is_some()
|
shared_axis_source(&input_state.pointer, axis_source)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_axis(
|
pub(super) fn handle_axis(
|
||||||
|
|
@ -171,24 +159,7 @@ pub(super) fn handle_axis(
|
||||||
axis: wl_pointer::Axis,
|
axis: wl_pointer::Axis,
|
||||||
value: f64,
|
value: f64,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if input_state.active_pointer_surface_id.is_none() {
|
shared_axis(&mut input_state.pointer, axis, value)
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
match axis {
|
|
||||||
wl_pointer::Axis::HorizontalScroll => {
|
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
|
||||||
let delta = value as f32;
|
|
||||||
input_state.accumulated_axis_x += delta;
|
|
||||||
}
|
|
||||||
wl_pointer::Axis::VerticalScroll => {
|
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
|
||||||
let delta = value as f32;
|
|
||||||
input_state.accumulated_axis_y += delta;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_axis_discrete(
|
pub(super) fn handle_axis_discrete(
|
||||||
|
|
@ -196,58 +167,19 @@ pub(super) fn handle_axis_discrete(
|
||||||
axis: wl_pointer::Axis,
|
axis: wl_pointer::Axis,
|
||||||
discrete: i32,
|
discrete: i32,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if input_state.active_pointer_surface_id.is_none() {
|
shared_axis_discrete(&mut input_state.pointer, axis, discrete)
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::cast_precision_loss)]
|
|
||||||
let delta = (discrete as f32) * 60.0;
|
|
||||||
match axis {
|
|
||||||
wl_pointer::Axis::HorizontalScroll => {
|
|
||||||
input_state.accumulated_axis_x += delta;
|
|
||||||
}
|
|
||||||
wl_pointer::Axis::VerticalScroll => {
|
|
||||||
input_state.accumulated_axis_y += delta;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_axis_stop(input_state: &InputState, _axis: wl_pointer::Axis) -> bool {
|
pub(super) fn handle_axis_stop(input_state: &InputState, axis: wl_pointer::Axis) -> bool {
|
||||||
input_state.active_pointer_surface_id.is_some()
|
shared_axis_stop(&input_state.pointer, axis)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_pointer_frame(
|
pub(super) fn handle_pointer_frame(
|
||||||
input_state: &mut InputState,
|
input_state: &mut InputState,
|
||||||
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(surface_id) = input_state.active_pointer_surface_id.clone() else {
|
let resolver = LockSurfaceResolver { lock_surfaces };
|
||||||
return false;
|
shared_pointer_frame(&mut input_state.pointer, &resolver)
|
||||||
};
|
|
||||||
let delta_x = input_state.accumulated_axis_x;
|
|
||||||
let delta_y = input_state.accumulated_axis_y;
|
|
||||||
input_state.accumulated_axis_x = 0.0;
|
|
||||||
input_state.accumulated_axis_y = 0.0;
|
|
||||||
|
|
||||||
let Some(active_surface) = find_surface_by_surface_id(lock_surfaces, &surface_id) else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
let window = active_surface.window_rc();
|
|
||||||
|
|
||||||
if delta_x.abs() > f32::EPSILON || delta_y.abs() > f32::EPSILON {
|
|
||||||
let position = input_state.current_pointer_position;
|
|
||||||
window
|
|
||||||
.window()
|
|
||||||
.dispatch_event(WindowEvent::PointerScrolled {
|
|
||||||
position,
|
|
||||||
delta_x,
|
|
||||||
delta_y,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_keyboard_enter(
|
pub(super) fn handle_keyboard_enter(
|
||||||
|
|
@ -255,21 +187,12 @@ pub(super) fn handle_keyboard_enter(
|
||||||
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
lock_surfaces: &[(ObjectId, ActiveLockSurface)],
|
||||||
surface: &WlSurface,
|
surface: &WlSurface,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let surface_id = surface.id();
|
let resolver = LockSurfaceResolver { lock_surfaces };
|
||||||
if find_surface_by_surface_id(lock_surfaces, &surface_id).is_some() {
|
shared_keyboard_enter(&mut input_state.keyboard, &resolver, surface)
|
||||||
input_state.keyboard_focus_surface_id = Some(surface_id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_keyboard_leave(input_state: &mut InputState, surface: &WlSurface) -> bool {
|
pub(super) fn handle_keyboard_leave(input_state: &mut InputState, surface: &WlSurface) -> bool {
|
||||||
let surface_id = surface.id();
|
shared_keyboard_leave(&mut input_state.keyboard, surface)
|
||||||
if input_state.keyboard_focus_surface_id.as_ref() == Some(&surface_id) {
|
|
||||||
input_state.keyboard_focus_surface_id = None;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn handle_keyboard_key(
|
pub(super) fn handle_keyboard_key(
|
||||||
|
|
@ -279,45 +202,8 @@ pub(super) fn handle_keyboard_key(
|
||||||
state: wl_keyboard::KeyState,
|
state: wl_keyboard::KeyState,
|
||||||
keyboard_state: &mut KeyboardState,
|
keyboard_state: &mut KeyboardState,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let Some(surface_id) = input_state.keyboard_focus_surface_id.clone() else {
|
let resolver = LockSurfaceResolver { lock_surfaces };
|
||||||
return false;
|
shared_keyboard_key(&input_state.keyboard, &resolver, key, state, keyboard_state)
|
||||||
};
|
|
||||||
let Some(active_surface) = find_surface_by_surface_id(lock_surfaces, &surface_id) else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
let Some(xkb_state) = keyboard_state.xkb_state.as_mut() else {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
let keycode = xkb::Keycode::new(key + 8);
|
|
||||||
let direction = match state {
|
|
||||||
wl_keyboard::KeyState::Pressed => xkb::KeyDirection::Down,
|
|
||||||
wl_keyboard::KeyState::Released => xkb::KeyDirection::Up,
|
|
||||||
_ => return true,
|
|
||||||
};
|
|
||||||
|
|
||||||
xkb_state.update_key(keycode, direction);
|
|
||||||
|
|
||||||
let text = xkb_state.key_get_utf8(keycode);
|
|
||||||
let text = if text.is_empty() {
|
|
||||||
let keysym = xkb_state.key_get_one_sym(keycode);
|
|
||||||
keysym_to_text(keysym)
|
|
||||||
} else {
|
|
||||||
Some(SharedString::from(text.as_str()))
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(text) = text else {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
let event = match state {
|
|
||||||
wl_keyboard::KeyState::Pressed => WindowEvent::KeyPressed { text },
|
|
||||||
wl_keyboard::KeyState::Released => WindowEvent::KeyReleased { text },
|
|
||||||
_ => return true,
|
|
||||||
};
|
|
||||||
info!("Lock key event {:?}", state);
|
|
||||||
active_surface.dispatch_event(event);
|
|
||||||
true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_surface_by_surface_id<'a>(
|
fn find_surface_by_surface_id<'a>(
|
||||||
|
|
|
||||||
|
|
@ -273,10 +273,6 @@ impl ActiveLockSurface {
|
||||||
self.window.window().dispatch_event(event);
|
self.window.window().dispatch_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn window_rc(&self) -> Rc<FemtoVGWindow> {
|
|
||||||
Rc::clone(&self.window)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn surface(&self) -> &LockSurface {
|
pub const fn surface(&self) -> &LockSurface {
|
||||||
&self.surface
|
&self.surface
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ use crate::errors::{LayerShikaError, Result};
|
||||||
use crate::rendering::egl::context_factory::RenderContextFactory;
|
use crate::rendering::egl::context_factory::RenderContextFactory;
|
||||||
use crate::rendering::slint_integration::platform::CustomSlintPlatform;
|
use crate::rendering::slint_integration::platform::CustomSlintPlatform;
|
||||||
use crate::wayland::globals::context::GlobalContext;
|
use crate::wayland::globals::context::GlobalContext;
|
||||||
|
use crate::wayland::input::KeyboardInputState;
|
||||||
use crate::wayland::managed_proxies::{ManagedWlKeyboard, ManagedWlPointer};
|
use crate::wayland::managed_proxies::{ManagedWlKeyboard, ManagedWlPointer};
|
||||||
use crate::wayland::outputs::{OutputManager, OutputMapping};
|
use crate::wayland::outputs::{OutputManager, OutputMapping};
|
||||||
use crate::wayland::session_lock::lock_context::SessionLockContext;
|
use crate::wayland::session_lock::lock_context::SessionLockContext;
|
||||||
|
|
@ -63,7 +64,7 @@ pub struct AppState {
|
||||||
registry_name_to_output_id: HashMap<u32, ObjectId>,
|
registry_name_to_output_id: HashMap<u32, ObjectId>,
|
||||||
active_surface_key: Option<ShellSurfaceKey>,
|
active_surface_key: Option<ShellSurfaceKey>,
|
||||||
keyboard_focus_key: Option<ShellSurfaceKey>,
|
keyboard_focus_key: Option<ShellSurfaceKey>,
|
||||||
keyboard_focus_surface_id: Option<ObjectId>,
|
keyboard_input_state: KeyboardInputState,
|
||||||
keyboard_state: KeyboardState,
|
keyboard_state: KeyboardState,
|
||||||
lock_manager: Option<SessionLockManager>,
|
lock_manager: Option<SessionLockManager>,
|
||||||
lock_callbacks: Vec<LockCallback>,
|
lock_callbacks: Vec<LockCallback>,
|
||||||
|
|
@ -92,7 +93,7 @@ impl AppState {
|
||||||
registry_name_to_output_id: HashMap::new(),
|
registry_name_to_output_id: HashMap::new(),
|
||||||
active_surface_key: None,
|
active_surface_key: None,
|
||||||
keyboard_focus_key: None,
|
keyboard_focus_key: None,
|
||||||
keyboard_focus_surface_id: None,
|
keyboard_input_state: KeyboardInputState::new(),
|
||||||
keyboard_state: KeyboardState::new(),
|
keyboard_state: KeyboardState::new(),
|
||||||
lock_manager: None,
|
lock_manager: None,
|
||||||
lock_callbacks: Vec::new(),
|
lock_callbacks: Vec::new(),
|
||||||
|
|
@ -626,19 +627,23 @@ impl AppState {
|
||||||
pub fn handle_keyboard_enter(&mut self, _serial: u32, surface: &WlSurface, _keys: &[u8]) {
|
pub fn handle_keyboard_enter(&mut self, _serial: u32, surface: &WlSurface, _keys: &[u8]) {
|
||||||
if let Some(manager) = self.lock_manager.as_mut() {
|
if let Some(manager) = self.lock_manager.as_mut() {
|
||||||
if manager.handle_keyboard_enter(surface) {
|
if manager.handle_keyboard_enter(surface) {
|
||||||
self.set_keyboard_focus(None, None);
|
self.set_keyboard_focus(None);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let surface_id = surface.id();
|
let surface_id = surface.id();
|
||||||
if let Some(key) = self.get_key_by_surface(&surface_id).cloned() {
|
if let Some(key) = self.get_key_by_surface(&surface_id).cloned() {
|
||||||
self.set_keyboard_focus(Some(key), Some(surface_id));
|
self.keyboard_input_state
|
||||||
|
.set_focused_surface(Some(surface_id.clone()));
|
||||||
|
self.set_keyboard_focus(Some(key));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(key) = self.get_key_by_popup(&surface_id).cloned() {
|
if let Some(key) = self.get_key_by_popup(&surface_id).cloned() {
|
||||||
self.set_keyboard_focus(Some(key), Some(surface_id));
|
self.keyboard_input_state
|
||||||
|
.set_focused_surface(Some(surface_id));
|
||||||
|
self.set_keyboard_focus(Some(key));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -649,8 +654,10 @@ impl AppState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.keyboard_focus_surface_id == Some(surface.id()) {
|
let surface_id = surface.id();
|
||||||
self.set_keyboard_focus(None, None);
|
if self.keyboard_input_state.focused_surface_id() == Some(&surface_id) {
|
||||||
|
self.keyboard_input_state.reset();
|
||||||
|
self.set_keyboard_focus(None);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -664,7 +671,7 @@ impl AppState {
|
||||||
let Some(focus_key) = self.keyboard_focus_key.clone() else {
|
let Some(focus_key) = self.keyboard_focus_key.clone() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(surface_id) = self.keyboard_focus_surface_id.clone() else {
|
let Some(surface_id) = self.keyboard_input_state.focused_surface_id().cloned() else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -691,12 +698,11 @@ impl AppState {
|
||||||
self.keyboard_state.repeat_delay = delay;
|
self.keyboard_state.repeat_delay = delay;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_keyboard_focus(&mut self, key: Option<ShellSurfaceKey>, surface_id: Option<ObjectId>) {
|
fn set_keyboard_focus(&mut self, key: Option<ShellSurfaceKey>) {
|
||||||
if let Some(ref k) = key {
|
if let Some(ref k) = key {
|
||||||
self.output_registry.set_active(Some(k.output_handle));
|
self.output_registry.set_active(Some(k.output_handle));
|
||||||
}
|
}
|
||||||
self.keyboard_focus_key = key;
|
self.keyboard_focus_key = key;
|
||||||
self.keyboard_focus_surface_id = surface_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_output_by_popup(&self, popup_surface_id: &ObjectId) -> Option<&PerOutputSurface> {
|
pub fn find_output_by_popup(&self, popup_surface_id: &ObjectId) -> Option<&PerOutputSurface> {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::rendering::femtovg::main_window::FemtoVGWindow;
|
use crate::rendering::femtovg::main_window::FemtoVGWindow;
|
||||||
|
use crate::wayland::input::PointerInputState;
|
||||||
use crate::wayland::surfaces::display_metrics::SharedDisplayMetrics;
|
use crate::wayland::surfaces::display_metrics::SharedDisplayMetrics;
|
||||||
use crate::wayland::surfaces::popup_manager::{ActiveWindow, PopupManager};
|
use crate::wayland::surfaces::popup_manager::{ActiveWindow, PopupManager};
|
||||||
use slint::platform::{WindowAdapter, WindowEvent};
|
use slint::platform::{WindowAdapter, WindowEvent};
|
||||||
|
|
@ -43,12 +44,10 @@ pub struct EventContext {
|
||||||
main_surface_id: ObjectId,
|
main_surface_id: ObjectId,
|
||||||
popup_manager: Option<Rc<PopupManager>>,
|
popup_manager: Option<Rc<PopupManager>>,
|
||||||
display_metrics: SharedDisplayMetrics,
|
display_metrics: SharedDisplayMetrics,
|
||||||
current_pointer_position: LogicalPosition,
|
pointer_state: PointerInputState,
|
||||||
last_pointer_serial: u32,
|
last_pointer_serial: u32,
|
||||||
shared_pointer_serial: Option<Rc<SharedPointerSerial>>,
|
shared_pointer_serial: Option<Rc<SharedPointerSerial>>,
|
||||||
active_surface: ActiveWindow,
|
active_surface: ActiveWindow,
|
||||||
accumulated_axis_x: f32,
|
|
||||||
accumulated_axis_y: f32,
|
|
||||||
axis_source: Option<wl_pointer::AxisSource>,
|
axis_source: Option<wl_pointer::AxisSource>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,12 +63,10 @@ impl EventContext {
|
||||||
main_surface_id,
|
main_surface_id,
|
||||||
popup_manager: None,
|
popup_manager: None,
|
||||||
display_metrics,
|
display_metrics,
|
||||||
current_pointer_position: LogicalPosition::new(0.0, 0.0),
|
pointer_state: PointerInputState::new(),
|
||||||
last_pointer_serial: 0,
|
last_pointer_serial: 0,
|
||||||
shared_pointer_serial: None,
|
shared_pointer_serial: None,
|
||||||
active_surface: ActiveWindow::None,
|
active_surface: ActiveWindow::None,
|
||||||
accumulated_axis_x: 0.0,
|
|
||||||
accumulated_axis_y: 0.0,
|
|
||||||
axis_source: None,
|
axis_source: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +98,7 @@ impl EventContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn current_pointer_position(&self) -> LogicalPosition {
|
pub const fn current_pointer_position(&self) -> LogicalPosition {
|
||||||
self.current_pointer_position
|
self.pointer_state.current_position()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
|
@ -117,7 +114,7 @@ impl EventContext {
|
||||||
(physical_y / f64::from(scale_factor)) as f32,
|
(physical_y / f64::from(scale_factor)) as f32,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
self.current_pointer_position = logical_position;
|
self.pointer_state.set_current_position(logical_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn last_pointer_serial(&self) -> u32 {
|
pub const fn last_pointer_serial(&self) -> u32 {
|
||||||
|
|
@ -222,12 +219,13 @@ impl EventContext {
|
||||||
|
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
pub fn accumulate_axis(&mut self, axis: wl_pointer::Axis, value: f64) {
|
pub fn accumulate_axis(&mut self, axis: wl_pointer::Axis, value: f64) {
|
||||||
|
let delta = value as f32;
|
||||||
match axis {
|
match axis {
|
||||||
wl_pointer::Axis::HorizontalScroll => {
|
wl_pointer::Axis::HorizontalScroll => {
|
||||||
self.accumulated_axis_x += value as f32;
|
self.pointer_state.accumulate_axis_value(delta, 0.0);
|
||||||
}
|
}
|
||||||
wl_pointer::Axis::VerticalScroll => {
|
wl_pointer::Axis::VerticalScroll => {
|
||||||
self.accumulated_axis_y += value as f32;
|
self.pointer_state.accumulate_axis_value(0.0, delta);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -239,23 +237,18 @@ impl EventContext {
|
||||||
|
|
||||||
match axis {
|
match axis {
|
||||||
wl_pointer::Axis::HorizontalScroll => {
|
wl_pointer::Axis::HorizontalScroll => {
|
||||||
self.accumulated_axis_x += delta;
|
self.pointer_state.accumulate_axis_value(delta, 0.0);
|
||||||
}
|
}
|
||||||
wl_pointer::Axis::VerticalScroll => {
|
wl_pointer::Axis::VerticalScroll => {
|
||||||
self.accumulated_axis_y += delta;
|
self.pointer_state.accumulate_axis_value(0.0, delta);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take_accumulated_axis(&mut self) -> (f32, f32) {
|
pub fn take_accumulated_axis(&mut self) -> (f32, f32) {
|
||||||
let delta_x = self.accumulated_axis_x;
|
let (delta_x, delta_y) = self.pointer_state.take_accumulated_axis();
|
||||||
let delta_y = self.accumulated_axis_y;
|
|
||||||
|
|
||||||
self.accumulated_axis_x = 0.0;
|
|
||||||
self.accumulated_axis_y = 0.0;
|
|
||||||
self.axis_source = None;
|
self.axis_source = None;
|
||||||
|
|
||||||
(delta_x, delta_y)
|
(delta_x, delta_y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue