Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions crates/adapters/src/wayland/shell_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ impl WaylandShellSystem {
let event_loop =
EventLoop::try_new().map_err(|e| EventLoopError::Creation { source: e })?;

let state = Self::init_state(config, &connection, &mut event_queue)?;
let mut state = Self::init_state(config, &connection, &mut event_queue)?;
state.set_loop_handle(event_loop.handle());

Ok(Self {
state,
Expand All @@ -100,7 +101,8 @@ impl WaylandShellSystem {
let event_loop =
EventLoop::try_new().map_err(|e| EventLoopError::Creation { source: e })?;

let state = Self::init_state_multi(configs, &connection, &mut event_queue)?;
let mut state = Self::init_state_multi(configs, &connection, &mut event_queue)?;
state.set_loop_handle(event_loop.handle());

Ok(Self {
state,
Expand All @@ -116,7 +118,8 @@ impl WaylandShellSystem {
let event_loop =
EventLoop::try_new().map_err(|e| EventLoopError::Creation { source: e })?;

let state = Self::init_state_minimal(&connection, &mut event_queue)?;
let mut state = Self::init_state_minimal(&connection, &mut event_queue)?;
state.set_loop_handle(event_loop.handle());

Ok(Self {
state,
Expand Down
66 changes: 66 additions & 0 deletions crates/adapters/src/wayland/surfaces/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::cell::RefCell;
use std::collections::HashMap;
use std::os::fd::BorrowedFd;
use std::rc::Rc;
use std::time::Duration;

use layer_shika_domain::entities::output_registry::OutputRegistry;
use layer_shika_domain::value_objects::handle::SurfaceHandle;
Expand All @@ -10,6 +11,9 @@ use layer_shika_domain::value_objects::lock_state::LockState;
use layer_shika_domain::value_objects::output_handle::OutputHandle;
use layer_shika_domain::value_objects::output_info::OutputInfo;
use slint_interpreter::{CompilationResult, ComponentDefinition, Value};
use smithay_client_toolkit::reexports::calloop::{
LoopHandle, RegistrationToken, timer::TimeoutAction, timer::Timer,
};
use wayland_client::Proxy;
use wayland_client::backend::ObjectId;
use wayland_client::protocol::wl_keyboard;
Expand Down Expand Up @@ -79,6 +83,9 @@ pub struct AppState {
lock_callbacks: Vec<LockCallback>,
lock_property_operations: Vec<LockPropertyOperation>,
queue_handle: Option<wayland_client::QueueHandle<AppState>>,
loop_handle: Option<LoopHandle<'static, AppState>>,
repeat_token: Option<RegistrationToken>,
repeat_key: Option<u32>,
}

impl AppState {
Expand Down Expand Up @@ -110,6 +117,9 @@ impl AppState {
lock_callbacks: Vec::new(),
lock_property_operations: Vec::new(),
queue_handle: None,
loop_handle: None,
repeat_token: None,
repeat_key: None,
}
}

Expand All @@ -130,6 +140,11 @@ impl AppState {
self.queue_handle = Some(queue_handle);
}

/// handle back into the event loop, used by the repeat timer
pub fn set_loop_handle(&mut self, handle: LoopHandle<'static, AppState>) {
self.loop_handle = Some(handle);
}

pub fn lock_manager(&self) -> Option<&SessionLockManager> {
self.lock_manager.as_ref()
}
Expand Down Expand Up @@ -690,6 +705,7 @@ impl AppState {

let surface_id = surface.id();
if self.keyboard_input_state.focused_surface_id() == Some(&surface_id) {
self.stop_repeat();
self.keyboard_input_state.reset();
self.set_keyboard_focus(None);
}
Expand All @@ -702,6 +718,20 @@ impl AppState {
}
}

self.dispatch_key(key, state);

match state {
wl_keyboard::KeyState::Pressed => self.start_repeat(key),
wl_keyboard::KeyState::Released => {
if self.repeat_key == Some(key) {
self.stop_repeat();
}
}
_ => {}
}
}

fn dispatch_key(&mut self, key: u32, state: wl_keyboard::KeyState) {
let Some(focus_key) = self.keyboard_focus_key.clone() else {
return;
};
Expand All @@ -714,6 +744,42 @@ impl AppState {
}
}

fn start_repeat(&mut self, key: u32) {
self.stop_repeat();

let Some(handle) = self.loop_handle.clone() else {
return;
};

let rate = self.keyboard_state.repeat_rate;
let delay = self.keyboard_state.repeat_delay;
if rate <= 0 || delay < 0 {
return;
}
let interval = Duration::from_millis(1000 / rate as u64);

self.repeat_key = Some(key);

let token = handle.insert_source(
Timer::from_duration(Duration::from_millis(delay as u64)),
move |_deadline, _metadata, app_state: &mut AppState| {
if app_state.repeat_key != Some(key) {
return TimeoutAction::Drop;
}
app_state.dispatch_key(key, wl_keyboard::KeyState::Pressed);
TimeoutAction::ToDuration(interval)
},
);
self.repeat_token = token.ok();
}

fn stop_repeat(&mut self) {
if let (Some(handle), Some(token)) = (&self.loop_handle, self.repeat_token.take()) {
handle.remove(token);
}
self.repeat_key = None;
}

pub fn handle_modifiers(
&mut self,
_serial: u32,
Expand Down