1
0
Fork 0
forked from wry/wry

control-center: add input pane

This commit is contained in:
Julian Orth 2026-03-07 14:49:13 +01:00
parent db06d719dd
commit edbdcdca32
11 changed files with 783 additions and 63 deletions

View file

@ -14,7 +14,7 @@ use {
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER, LIBINPUT_CONFIG_CLICK_METHOD_NONE,
},
object::{Object, Version},
state::{DeviceHandlerData, InputDeviceData},
state::{DeviceHandlerData, InputDeviceData, State},
utils::errorfmt::ErrorFmt,
wire::{JayInputId, jay_input::*},
},
@ -28,6 +28,7 @@ use {
pub struct JayInput {
pub id: JayInputId,
pub client: Rc<Client>,
pub state: Rc<State>,
pub tracker: Tracker<Self>,
pub version: Version,
}
@ -41,6 +42,7 @@ impl JayInput {
Self {
id,
client: client.clone(),
state: client.state.clone(),
tracker: Default::default(),
version,
}
@ -309,7 +311,7 @@ impl JayInputRequestHandler for JayInput {
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE => InputDeviceAccelProfile::Adaptive,
_ => return Err(JayInputError::UnknownAccelerationProfile(req.profile)),
};
dev.set_accel_profile(profile);
dev.set_accel_profile(&self.state, profile);
Ok(())
})
}
@ -317,7 +319,7 @@ impl JayInputRequestHandler for JayInput {
fn set_accel_speed(&self, req: SetAccelSpeed, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_accel_speed(req.speed);
dev.set_accel_speed(&self.state, req.speed);
Ok(())
})
}
@ -325,7 +327,7 @@ impl JayInputRequestHandler for JayInput {
fn set_tap_enabled(&self, req: SetTapEnabled, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_tap_enabled(req.enabled != 0);
dev.set_tap_enabled(&self.state, req.enabled != 0);
Ok(())
})
}
@ -337,7 +339,7 @@ impl JayInputRequestHandler for JayInput {
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_drag_enabled(req.enabled != 0);
dev.set_drag_enabled(&self.state, req.enabled != 0);
Ok(())
})
}
@ -349,7 +351,7 @@ impl JayInputRequestHandler for JayInput {
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_drag_lock_enabled(req.enabled != 0);
dev.set_drag_lock_enabled(&self.state, req.enabled != 0);
Ok(())
})
}
@ -357,7 +359,7 @@ impl JayInputRequestHandler for JayInput {
fn set_left_handed(&self, req: SetLeftHanded, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_left_handed(req.enabled != 0);
dev.set_left_handed(&self.state, req.enabled != 0);
Ok(())
})
}
@ -369,7 +371,7 @@ impl JayInputRequestHandler for JayInput {
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_natural_scrolling_enabled(req.enabled != 0);
dev.set_natural_scrolling_enabled(&self.state, req.enabled != 0);
Ok(())
})
}
@ -381,7 +383,7 @@ impl JayInputRequestHandler for JayInput {
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_px_per_scroll_wheel(req.px);
dev.set_px_per_scroll_wheel(&self.state, req.px);
Ok(())
})
}
@ -393,7 +395,7 @@ impl JayInputRequestHandler for JayInput {
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_transform_matrix([[req.m11, req.m12], [req.m21, req.m22]]);
dev.set_transform_matrix(&self.state, [[req.m11, req.m12], [req.m21, req.m22]]);
Ok(())
})
}
@ -410,7 +412,7 @@ impl JayInputRequestHandler for JayInput {
self.or_error(|| {
let seat = self.seat(req.seat)?;
let dev = self.device(req.id)?;
dev.set_seat(Some(seat));
dev.set_seat(&self.state, Some(seat));
Ok(())
})
}
@ -418,7 +420,7 @@ impl JayInputRequestHandler for JayInput {
fn detach(&self, req: Detach, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_seat(None);
dev.set_seat(&self.state, None);
Ok(())
})
}
@ -459,7 +461,7 @@ impl JayInputRequestHandler for JayInput {
fn set_device_keymap(&self, req: SetDeviceKeymap, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.set_keymap_impl(&req.keymap, req.keymap_len, |map| {
let dev = self.device(req.id)?;
dev.set_keymap(Some(map.clone()));
dev.set_keymap(&self.state, Some(map.clone()));
Ok(())
})
}
@ -490,11 +492,11 @@ impl JayInputRequestHandler for JayInput {
.find(|c| c.global.connector.name.to_ascii_lowercase() == namelc)
.cloned();
match c {
Some(c) => dev.set_output(Some(&c.global)),
Some(c) => dev.set_output(&self.state, Some(&c.global)),
_ => return Err(JayInputError::OutputNotConnected),
}
}
_ => dev.set_output(None),
_ => dev.set_output(&self.state, None),
}
Ok(())
})
@ -507,7 +509,10 @@ impl JayInputRequestHandler for JayInput {
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_calibration_matrix([[req.m00, req.m01, req.m02], [req.m10, req.m11, req.m12]]);
dev.set_calibration_matrix(
&self.state,
[[req.m00, req.m01, req.m02], [req.m10, req.m11, req.m12]],
);
Ok(())
})
}
@ -521,7 +526,7 @@ impl JayInputRequestHandler for JayInput {
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER => InputDeviceClickMethod::Clickfinger,
_ => return Err(JayInputError::UnknownClickMethod(req.method)),
};
dev.set_click_method(method);
dev.set_click_method(&self.state, method);
Ok(())
})
}
@ -533,7 +538,7 @@ impl JayInputRequestHandler for JayInput {
) -> Result<(), Self::Error> {
self.or_error(|| {
let dev = self.device(req.id)?;
dev.set_middle_button_emulation_enabled(req.enabled != 0);
dev.set_middle_button_emulation_enabled(&self.state, req.enabled != 0);
Ok(())
})
}
@ -594,7 +599,7 @@ impl JayInputRequestHandler for JayInput {
req.options,
|map| {
let dev = self.device(req.id)?;
dev.set_keymap(Some(map.clone()));
dev.set_keymap(&self.state, Some(map.clone()));
Ok(())
},
)

View file

@ -28,6 +28,7 @@ use {
ButtonState, InputDeviceAccelProfile, InputDeviceClickMethod, Leds, TransformMatrix,
},
client::{Client, ClientError, ClientId},
control_center::CCI_INPUT,
cursor_user::{CursorUser, CursorUserGroup, CursorUserOwner},
ei::ei_ifs::ei_seat::EiSeat,
fixed::Fixed,
@ -98,6 +99,7 @@ use {
numcell::NumCell,
rc_eq::{rc_eq, rc_weak_eq},
smallmap::SmallMap,
static_text::StaticText,
},
wire::{
ExtIdleNotificationV1Id, WlDataDeviceId, WlKeyboardId, WlPointerId, WlSeatId,
@ -276,6 +278,15 @@ pub enum FallbackOutputMode {
Focus,
}
impl StaticText for FallbackOutputMode {
fn text(&self) -> &'static str {
match self {
FallbackOutputMode::Cursor => "Cursor",
FallbackOutputMode::Focus => "Focus",
}
}
}
impl TryFrom<ConfigFallbackOutputMode> for FallbackOutputMode {
type Error = ();
@ -768,6 +779,7 @@ impl WlSeatGlobal {
if let Some(grab) = self.input_method_grab.get() {
grab.on_repeat_info();
}
self.state.trigger_cci(CCI_INPUT);
}
pub fn close(self: &Rc<Self>) {
@ -963,18 +975,18 @@ impl WlSeatGlobal {
pub fn focus_history_set_visible(&self, visible: bool) {
self.focus_history_visible_only.set(visible);
self.state.trigger_cci(CCI_INPUT);
}
#[expect(dead_code)]
pub fn focus_history_visible(&self) -> bool {
self.focus_history_visible_only.get()
}
pub fn focus_history_set_same_workspace(&self, same_workspace: bool) {
self.focus_history_same_workspace.set(same_workspace);
self.state.trigger_cci(CCI_INPUT);
}
#[expect(dead_code)]
pub fn focus_history_same_workspace(&self) -> bool {
self.focus_history_same_workspace.get()
}
@ -1479,18 +1491,18 @@ impl WlSeatGlobal {
pub fn set_focus_follows_mouse(&self, focus_follows_mouse: bool) {
self.focus_follows_mouse.set(focus_follows_mouse);
self.state.trigger_cci(CCI_INPUT);
}
#[expect(dead_code)]
pub fn focus_follows_mouse(&self) -> bool {
self.focus_follows_mouse.get()
}
pub fn set_fallback_output_mode(&self, fallback_output_mode: FallbackOutputMode) {
self.fallback_output_mode.set(fallback_output_mode);
self.state.trigger_cci(CCI_INPUT);
}
#[expect(dead_code)]
pub fn fallback_output_mode(&self) -> FallbackOutputMode {
self.fallback_output_mode.get()
}
@ -1610,9 +1622,9 @@ impl WlSeatGlobal {
pub fn set_pointer_revert_key(&self, key: KeySym) {
self.revert_key.set(key);
self.state.trigger_cci(CCI_INPUT);
}
#[expect(dead_code)]
pub fn pointer_revert_key(&self) -> KeySym {
self.revert_key.get()
}
@ -1809,7 +1821,7 @@ pub fn collect_kb_foci(node: Rc<dyn Node>) -> SmallVec<[Rc<WlSeatGlobal>; 3]> {
}
impl DeviceHandlerData {
pub fn set_seat(&self, seat: Option<Rc<WlSeatGlobal>>) {
pub fn set_seat(&self, state: &State, seat: Option<Rc<WlSeatGlobal>>) {
if let Some(new) = &seat {
if let Some(old) = self.seat.get()
&& old.id() == new.id()
@ -1848,6 +1860,7 @@ impl DeviceHandlerData {
}
}
self.attach_event_listeners();
state.trigger_cci(CCI_INPUT);
}
fn destroy_physical_keyboard_state(&self) {
@ -1869,13 +1882,14 @@ impl DeviceHandlerData {
};
}
pub fn set_keymap(&self, keymap: Option<Rc<KbvmMap>>) {
pub fn set_keymap(&self, state: &State, keymap: Option<Rc<KbvmMap>>) {
self.destroy_physical_keyboard_state();
self.keymap.set(keymap);
self.attach_event_listeners();
state.trigger_cci(CCI_INPUT);
}
pub fn set_output(&self, output: Option<&WlOutputGlobal>) {
pub fn set_output(&self, state: &State, output: Option<&WlOutputGlobal>) {
match output {
None => {
log::info!("Removing output mapping of {}", self.device.name());
@ -1886,6 +1900,7 @@ impl DeviceHandlerData {
self.output.set(Some(o.opt.clone()));
}
}
state.trigger_cci(CCI_INPUT);
}
pub fn get_rect(&self, state: &State) -> Rect {
@ -1897,52 +1912,64 @@ impl DeviceHandlerData {
state.root.extents.get()
}
pub fn set_accel_profile(&self, v: InputDeviceAccelProfile) {
pub fn set_accel_profile(&self, state: &State, v: InputDeviceAccelProfile) {
self.device.set_accel_profile(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_accel_speed(&self, v: f64) {
pub fn set_accel_speed(&self, state: &State, v: f64) {
self.device.set_accel_speed(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_tap_enabled(&self, v: bool) {
pub fn set_tap_enabled(&self, state: &State, v: bool) {
self.device.set_tap_enabled(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_drag_enabled(&self, v: bool) {
pub fn set_drag_enabled(&self, state: &State, v: bool) {
self.device.set_drag_enabled(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_drag_lock_enabled(&self, v: bool) {
pub fn set_drag_lock_enabled(&self, state: &State, v: bool) {
self.device.set_drag_lock_enabled(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_left_handed(&self, v: bool) {
pub fn set_left_handed(&self, state: &State, v: bool) {
self.device.set_left_handed(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_natural_scrolling_enabled(&self, v: bool) {
pub fn set_natural_scrolling_enabled(&self, state: &State, v: bool) {
self.device.set_natural_scrolling_enabled(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_px_per_scroll_wheel(&self, v: f64) {
pub fn set_px_per_scroll_wheel(&self, state: &State, v: f64) {
self.px_per_scroll_wheel.set(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_transform_matrix(&self, v: TransformMatrix) {
pub fn set_transform_matrix(&self, state: &State, v: TransformMatrix) {
self.device.set_transform_matrix(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_calibration_matrix(&self, v: [[f32; 3]; 2]) {
pub fn set_calibration_matrix(&self, state: &State, v: [[f32; 3]; 2]) {
self.device.set_calibration_matrix(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_click_method(&self, v: InputDeviceClickMethod) {
pub fn set_click_method(&self, state: &State, v: InputDeviceClickMethod) {
self.device.set_click_method(v);
state.trigger_cci(CCI_INPUT);
}
pub fn set_middle_button_emulation_enabled(&self, v: bool) {
pub fn set_middle_button_emulation_enabled(&self, state: &State, v: bool) {
self.device.set_middle_button_emulation_enabled(v);
state.trigger_cci(CCI_INPUT);
}
}

View file

@ -1,6 +1,7 @@
use {
crate::{
backend::KeyState,
control_center::CCI_INPUT,
ifs::{
wl_seat::{
WlSeatGlobal,
@ -89,6 +90,7 @@ impl WlSeatGlobal {
im.cancel_simple(self);
}
}
self.state.trigger_cci(CCI_INPUT);
}
pub fn simple_im_enabled(&self) -> bool {