feat: Make long press to right click configurable
This commit is contained in:
@@ -67,6 +67,7 @@
|
||||
"LEFT_HANDED_MOUSE": "Left-handed mouse",
|
||||
"LEFT_HANDED_MOUSE_HELP": "Use this if mouse buttons are swapped",
|
||||
"LONG_PRESS_DURATION": "Long press duration",
|
||||
"LONG_PRESS_TO_RIGHT_CLICK": "Long press to right click",
|
||||
"LOOK_AND_FEEL": "Look & Feel",
|
||||
"MISC": "Miscellaneous",
|
||||
"NOTIFICATIONS_ENABLED": "Enable notifications",
|
||||
|
||||
@@ -231,6 +231,7 @@ enum SettingType {
|
||||
Language,
|
||||
LeftHandedMouse,
|
||||
LongPressDuration,
|
||||
LongPressToRightClick,
|
||||
NotificationsEnabled,
|
||||
NotificationsSoundEnabled,
|
||||
OpaqueBackground,
|
||||
@@ -267,6 +268,7 @@ impl SettingType {
|
||||
Self::AllowSliding => &mut config.allow_sliding,
|
||||
Self::FocusFollowsMouseMode => &mut config.focus_follows_mouse_mode,
|
||||
Self::LeftHandedMouse => &mut config.left_handed_mouse,
|
||||
Self::LongPressToRightClick => &mut config.long_press_to_right_click,
|
||||
Self::BlockGameInput => &mut config.block_game_input,
|
||||
Self::BlockGameInputIgnoreWatch => &mut config.block_game_input_ignore_watch,
|
||||
Self::BlockPosesOnKbdInteraction => &mut config.block_poses_on_kbd_interaction,
|
||||
@@ -378,6 +380,7 @@ impl SettingType {
|
||||
Self::Language => Ok("APP_SETTINGS.LANGUAGE"),
|
||||
Self::LeftHandedMouse => Ok("APP_SETTINGS.LEFT_HANDED_MOUSE"),
|
||||
Self::LongPressDuration => Ok("APP_SETTINGS.LONG_PRESS_DURATION"),
|
||||
Self::LongPressToRightClick => Ok("APP_SETTINGS.LONG_PRESS_TO_RIGHT_CLICK"),
|
||||
Self::NotificationsEnabled => Ok("APP_SETTINGS.NOTIFICATIONS_ENABLED"),
|
||||
Self::NotificationsSoundEnabled => Ok("APP_SETTINGS.NOTIFICATIONS_SOUND_ENABLED"),
|
||||
Self::OpaqueBackground => Ok("APP_SETTINGS.OPAQUE_BACKGROUND"),
|
||||
@@ -831,6 +834,7 @@ impl<T> TabSettings<T> {
|
||||
checkbox!(mp, c, SettingType::InvertScrollDirectionY);
|
||||
slider_f32!(mp, c, SettingType::ScrollSpeed, 0.1, 5.0, 0.1);
|
||||
slider_f32!(mp, c, SettingType::LongPressDuration, 0.1, 2.0, 0.1);
|
||||
checkbox!(mp, c, SettingType::LongPressToRightClick);
|
||||
slider_f32!(mp, c, SettingType::PointerLerpFactor, 0.1, 1.0, 0.1);
|
||||
slider_f32!(mp, c, SettingType::XrClickSensitivity, 0.1, 1.0, 0.1);
|
||||
slider_f32!(mp, c, SettingType::XrClickSensitivityRelease, 0.1, 1.0, 0.1);
|
||||
|
||||
@@ -101,16 +101,11 @@ impl InputState {
|
||||
hand.interaction.long_press_click_sent = false;
|
||||
}
|
||||
|
||||
let long_press_threshold = Duration::from_secs_f32(session.config.long_press_duration);
|
||||
let is_long_press = hand
|
||||
.click_press_start
|
||||
.is_some_and(|start| start.elapsed() >= long_press_threshold);
|
||||
|
||||
// Prevent the mode from changing during a click (except for long press)
|
||||
if !hand.before.click || is_long_press {
|
||||
if !hand.before.click || (session.config.long_press_to_right_click && hand.click_press_start.is_some_and(|start| start.elapsed() >= Duration::from_secs_f32(session.config.long_press_duration))) {
|
||||
if hand.now.click_modifier_right {
|
||||
hand.interaction.mode = PointerMode::Right;
|
||||
} else if is_long_press {
|
||||
} else if session.config.long_press_to_right_click && hand.click_press_start.is_some_and(|start| start.elapsed() >= Duration::from_secs_f32(session.config.long_press_duration)) {
|
||||
hand.interaction.mode = PointerMode::Right;
|
||||
} else if hand.now.click_modifier_middle {
|
||||
hand.interaction.mode = PointerMode::Middle;
|
||||
@@ -545,18 +540,38 @@ where
|
||||
let pointer = &mut app.input_state.pointers[hit.pointer];
|
||||
|
||||
// Check if we should send a long-press click immediately
|
||||
let long_press_threshold = Duration::from_secs_f32(app.session.config.long_press_duration);
|
||||
let is_long_press = pointer
|
||||
.click_press_start
|
||||
.is_some_and(|start| start.elapsed() >= long_press_threshold);
|
||||
if app.session.config.long_press_to_right_click {
|
||||
let long_press_threshold = Duration::from_secs_f32(app.session.config.long_press_duration);
|
||||
let is_long_press = pointer
|
||||
.click_press_start
|
||||
.is_some_and(|start| start.elapsed() >= long_press_threshold);
|
||||
|
||||
if is_long_press && pointer.now.click && !pointer.interaction.long_press_click_sent {
|
||||
// Immediately send right-click (press + release)
|
||||
pointer.interaction.long_press_click_sent = true;
|
||||
let mut hit_right = hit;
|
||||
hit_right.mode = PointerMode::Right;
|
||||
hovered.config.backend.on_pointer(app, &hit_right, true);
|
||||
hovered.config.backend.on_pointer(app, &hit_right, false);
|
||||
if is_long_press && pointer.now.click && !pointer.interaction.long_press_click_sent {
|
||||
// Immediately send right-click (press + release)
|
||||
pointer.interaction.long_press_click_sent = true;
|
||||
let mut hit_right = hit;
|
||||
hit_right.mode = PointerMode::Right;
|
||||
hovered.config.backend.on_pointer(app, &hit_right, true);
|
||||
hovered.config.backend.on_pointer(app, &hit_right, false);
|
||||
} else if pointer.now.click && !pointer.before.click {
|
||||
pointer.interaction.clicked_id = Some(hit.overlay);
|
||||
update_focus(
|
||||
&mut app.hid_provider.keyboard_focus,
|
||||
hovered.config.keyboard_focus,
|
||||
);
|
||||
hovered.config.backend.on_pointer(app, &hit, true);
|
||||
} else if !pointer.now.click && pointer.before.click {
|
||||
// Only send release if we haven't already sent a long press click
|
||||
if !pointer.interaction.long_press_click_sent {
|
||||
if let Some(clicked_id) = pointer.interaction.clicked_id.take() {
|
||||
if let Some(clicked) = overlays.mut_by_id(clicked_id) {
|
||||
clicked.config.backend.on_pointer(app, &hit, false);
|
||||
}
|
||||
} else {
|
||||
hovered.config.backend.on_pointer(app, &hit, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if pointer.now.click && !pointer.before.click {
|
||||
pointer.interaction.clicked_id = Some(hit.overlay);
|
||||
update_focus(
|
||||
|
||||
@@ -113,6 +113,7 @@ pub struct AutoSettings {
|
||||
pub invert_scroll_direction_y: bool,
|
||||
pub scroll_speed: f32,
|
||||
pub long_press_duration: f32,
|
||||
pub long_press_to_right_click: bool,
|
||||
pub notifications_enabled: bool,
|
||||
pub notifications_sound_enabled: bool,
|
||||
pub keyboard_sound_enabled: bool,
|
||||
@@ -163,6 +164,7 @@ pub fn save_settings(config: &GeneralConfig) -> anyhow::Result<()> {
|
||||
invert_scroll_direction_y: config.invert_scroll_direction_y,
|
||||
scroll_speed: config.scroll_speed,
|
||||
long_press_duration: config.long_press_duration,
|
||||
long_press_to_right_click: config.long_press_to_right_click,
|
||||
notifications_enabled: config.notifications_enabled,
|
||||
notifications_sound_enabled: config.notifications_sound_enabled,
|
||||
keyboard_sound_enabled: config.keyboard_sound_enabled,
|
||||
|
||||
@@ -182,6 +182,9 @@
|
||||
## before it's considered a long press
|
||||
#long_press_duration: 1.0
|
||||
|
||||
## When enabled, a long press will be interpreted as a right click.
|
||||
#long_press_to_right_click: true
|
||||
|
||||
## Change speed of scrolling
|
||||
# 0.5 → half the speed
|
||||
# 2.0 → twice the speed
|
||||
|
||||
@@ -184,6 +184,9 @@ pub struct GeneralConfig {
|
||||
#[serde(default = "def_one")]
|
||||
pub long_press_duration: f32,
|
||||
|
||||
#[serde(default = "def_true")]
|
||||
pub long_press_to_right_click: bool,
|
||||
|
||||
#[serde(default = "def_mouse_move_interval_ms")]
|
||||
pub mouse_move_interval_ms: i32,
|
||||
|
||||
|
||||
Reference in New Issue
Block a user