add setting for input provider

This commit is contained in:
galister 2026-07-02 17:36:20 +09:00
parent 07b7d89be6
commit 34bd920f3b
8 changed files with 62 additions and 6 deletions

View File

@ -115,6 +115,8 @@
"HANDSFREE_POINTER_HELP": "Input to use when motion\ncontrollers are unavailable.\nLeft pinch is grab, right is click.",
"HIDE_GRAB_HELP": "Hide grab help",
"HIDE_USERNAME": "Hide username",
"INPUT_EMULATION_METHOD": "Input emulation method",
"INPUT_EMULATION_METHOD_HELP": "Try change this in case mouse or\nkeyboard input does not register.",
"INPUT_PROFILES": "Change Input Bindings",
"INPUT_PROFILES_HELP": "OpenXR controller input bindings",
"INVERT_SCROLL_DIRECTION_X": "Invert horizontal scroll direction",
@ -141,10 +143,15 @@
"HMD_ONLY": "HMD only",
"HMD_PINCH": "HMD + pinch",
"NONE": "None",
"NONE_INPUT_HELP": "Do not emulate mouse and keyboard.\nWill not be able to interact with screens.",
"PIPEWIRE_HELP": "Fast GPU capture,\nstandard on all desktops.",
"PW_FALLBACK_HELP": "Slow method with high CPU usage.\nTry in case PipeWire GPU doesn't work",
"SCREENCOPY_GPU_HELP": "Fast, no screen share popups.\nWorks on: Hyprland, Niri, River, Sway",
"SCREENCOPY_HELP": "Slow, no screen share popups.\nWorks on: Hyprland, Niri, River, Sway"
"SCREENCOPY_HELP": "Slow, no screen share popups.\nWorks on: Hyprland, Niri, River, Sway",
"UINPUT": "Device emulation",
"UINPUT_HELP": "Uses the uinput module to emulate a device.\nYour user must be in the input group.\nKnown to work well on most desktops.",
"WL_VIRTUAL": "Wayland virtual input",
"WL_VIRTUAL_HELP": "Send events to the Wayland compositor using\nzwlr_virtual_pointer and zwp_virtual_keyboard.\nOnly works reliably on some desktops.\nDoes NOT work on KDE, GNOME or COSMIC."
},
"POINTER_LERP_FACTOR": "Pointer smoothing",
"REQUIRES_RESTART": "Requires restart",

View File

@ -284,6 +284,7 @@ enum SettingType {
HandsfreePointer,
HideGrabHelp,
HideUsername,
InputEmulationMethod,
InvertScrollDirectionX,
InvertScrollDirectionY,
KeyboardMiddleClick,
@ -392,6 +393,10 @@ impl SettingType {
Self::CaptureMethod => {
config.capture_method = wlx_common::config::CaptureMethod::from_str(value).expect("Invalid enum value!")
}
Self::InputEmulationMethod => {
config.input_emulation_method =
wlx_common::config::InputEmulationMethod::from_str(value).expect("Invalid enum value!")
}
Self::KeyboardMiddleClick => {
config.keyboard_middle_click_mode =
wlx_common::config::AltModifier::from_str(value).expect("Invalid enum value!")
@ -409,6 +414,7 @@ impl SettingType {
fn get_enum_title(self, config: &mut GeneralConfig) -> Translation {
match self {
Self::CaptureMethod => Self::get_enum_title_inner(config.capture_method),
Self::InputEmulationMethod => Self::get_enum_title_inner(config.input_emulation_method),
Self::KeyboardMiddleClick => Self::get_enum_title_inner(config.keyboard_middle_click_mode),
Self::HandsfreePointer => Self::get_enum_title_inner(config.handsfree_pointer),
Self::Language => match &config.language {
@ -454,6 +460,7 @@ impl SettingType {
Self::HandsfreePointer => Ok("APP_SETTINGS.HANDSFREE_POINTER"),
Self::HideGrabHelp => Ok("APP_SETTINGS.HIDE_GRAB_HELP"),
Self::HideUsername => Ok("APP_SETTINGS.HIDE_USERNAME"),
Self::InputEmulationMethod => Ok("APP_SETTINGS.INPUT_EMULATION_METHOD"),
Self::InvertScrollDirectionX => Ok("APP_SETTINGS.INVERT_SCROLL_DIRECTION_X"),
Self::InvertScrollDirectionY => Ok("APP_SETTINGS.INVERT_SCROLL_DIRECTION_Y"),
Self::KeyboardMiddleClick => Ok("APP_SETTINGS.KEYBOARD_MIDDLE_CLICK"),
@ -500,6 +507,7 @@ impl SettingType {
Self::DoubleCursorFix => Some("APP_SETTINGS.DOUBLE_CURSOR_FIX_HELP"),
Self::GridOpacity => Some("APP_SETTINGS.GRID_OPACITY_HELP"),
Self::HandsfreePointer => Some("APP_SETTINGS.HANDSFREE_POINTER_HELP"),
Self::InputEmulationMethod => Some("APP_SETTINGS.INPUT_EMULATION_METHOD_HELP"),
Self::KeyboardMiddleClick => Some("APP_SETTINGS.KEYBOARD_MIDDLE_CLICK_HELP"),
Self::LeftHandedMouse => Some("APP_SETTINGS.LEFT_HANDED_MOUSE_HELP"),
Self::ScreenRenderDown => Some("APP_SETTINGS.SCREEN_RENDER_DOWN_HELP"),
@ -527,6 +535,7 @@ impl SettingType {
| Self::DoubleCursorFix
| Self::Language
| Self::CaptureMethod
| Self::InputEmulationMethod
)
}

View File

@ -10,6 +10,7 @@ impl SettingsTab for State {}
impl State {
pub fn mount(par: SettingsMountParams) -> anyhow::Result<State> {
let c = options_category(par.mp, par.id_parent, "APP_SETTINGS.MISC", "dashboard/blocks.svg")?;
options_dropdown::<wlx_common::config::InputEmulationMethod>(par.mp, c, &SettingType::InputEmulationMethod)?;
options_dropdown::<wlx_common::config::CaptureMethod>(par.mp, c, &SettingType::CaptureMethod)?;
options_checkbox(par.mp, c, SettingType::XwaylandByDefault)?;
options_checkbox(par.mp, c, SettingType::UprightScreenFix)?;

View File

@ -469,7 +469,9 @@ fn input_controls_for_hand(
clicks_dropdown(mp, parent, action.clone(), click_type)?;
if let Some(component) = current.as_ref().map(|x| x.component)
&& component.is_analog() && &*action != "scroll" // hax
&& component.is_analog()
&& &*action != "scroll"
// hax
{
threshold_slider(mp, parent, action, side, threshold)?;
}

View File

@ -92,7 +92,7 @@ impl AppState {
.log_err("Could not initialize WayVR Server")
.ok();
let (hid_provider, mut hid_error) = HidWrapper::new();
let (hid_provider, mut hid_error) = HidWrapper::new(session.config.input_emulation_method);
#[cfg(feature = "osc")]
let osc_sender = crate::subsystem::osc::OscSender::new(session.config.osc_out_port).ok();

View File

@ -1,3 +1,4 @@
use crate::overlays::toast::Toast;
use crate::subsystem::hid::provider::HidProvider;
use crate::subsystem::hid::{VirtualKey, WheelDelta, XkbKeymap};
use glam::Vec2;
@ -17,3 +18,7 @@ impl HidProvider for DummyProvider {
fn commit(&mut self) {}
}
pub fn initialize_dummy() -> anyhow::Result<Box<dyn HidProvider>, Toast> {
Ok(Box::new(DummyProvider {}))
}

View File

@ -1,3 +1,5 @@
use wlx_common::config::InputEmulationMethod;
use super::hid::{self, VirtualKey};
use crate::subsystem::hid::provider::HidProvider;
@ -17,9 +19,14 @@ pub struct HidWrapper {
}
impl HidWrapper {
pub fn new() -> (Self, Option<Toast>) {
let (provider, toast) = hid::provider::wl_virtual::initialize_wl_virtual()
.or_else(|_| hid::provider::uinput::initialize_uinput())
pub fn new(method: InputEmulationMethod) -> (Self, Option<Toast>) {
let maybe_provider = match method {
InputEmulationMethod::Uinput => hid::provider::uinput::initialize_uinput(),
InputEmulationMethod::WlVirtual => hid::provider::wl_virtual::initialize_wl_virtual(),
InputEmulationMethod::None => hid::provider::dummy::initialize_dummy(),
};
let (provider, toast) = maybe_provider
.map(|provider| (provider, None))
.unwrap_or_else(|toast| (Box::new(DummyProvider {}), Some(toast)));

View File

@ -40,6 +40,28 @@ pub enum CaptureMethod {
ScreenCopyCpu,
}
#[derive(Default, Clone, Copy, Serialize, Deserialize, AsRefStr, EnumString, EnumProperty, VariantArray)]
pub enum InputEmulationMethod {
#[default]
#[strum(props(
Translation = "APP_SETTINGS.OPTION.UINPUT",
Tooltip = "APP_SETTINGS.OPTION.UINPUT_HELP"
))]
Uinput,
#[strum(props(
Translation = "APP_SETTINGS.OPTION.WL_VIRTUAL",
Tooltip = "APP_SETTINGS.OPTION.WL_VIRTUAL_HELP"
))]
WlVirtual,
#[strum(props(
Translation = "APP_SETTINGS.OPTION.NONE",
Tooltip = "APP_SETTINGS.OPTION.NONE_INPUT_HELP"
))]
None,
}
#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, AsRefStr, EnumString, EnumProperty, VariantArray)]
pub enum AltModifier {
#[default]
@ -292,6 +314,9 @@ pub struct GeneralConfig {
#[serde(default)]
pub capture_method: CaptureMethod,
#[serde(default)]
pub input_emulation_method: InputEmulationMethod,
#[serde(default = "def_true")]
pub allow_sliding: bool,