keyboard: release modifier when a non-modifier is released

This commit is contained in:
galister
2024-02-01 18:45:26 +01:00
parent a0c31fa3ed
commit 7888898018

View File

@@ -10,7 +10,7 @@ use crate::{
backend::overlay::{OverlayData, OverlayState}, backend::overlay::{OverlayData, OverlayState},
config, config,
gui::{color_parse, CanvasBuilder, Control}, gui::{color_parse, CanvasBuilder, Control},
hid::{KeyModifier, VirtualKey, KEYS_TO_MODS}, hid::{KeyModifier, VirtualKey, ALT, CTRL, KEYS_TO_MODS, META, SHIFT, SUPER},
state::{AppSession, AppState}, state::{AppSession, AppState},
}; };
use glam::{vec2, vec3a, Affine2}; use glam::{vec2, vec3a, Affine2};
@@ -21,6 +21,7 @@ use serde::{Deserialize, Serialize};
const PIXELS_PER_UNIT: f32 = 80.; const PIXELS_PER_UNIT: f32 = 80.;
const BUTTON_PADDING: f32 = 4.; const BUTTON_PADDING: f32 = 4.;
const AUTO_RELEASE_MODS: [KeyModifier; 5] = [SHIFT, CTRL, ALT, SUPER, META];
pub fn create_keyboard<O>(app: &AppState) -> OverlayData<O> pub fn create_keyboard<O>(app: &AppState) -> OverlayData<O>
where where
@@ -72,7 +73,6 @@ where
maybe_state = Some(KeyButtonData::Modifier { maybe_state = Some(KeyButtonData::Modifier {
modifier: *mods, modifier: *mods,
sticky: false, sticky: false,
pressed: false,
}); });
} else { } else {
maybe_state = Some(KeyButtonData::Key { vk, pressed: false }); maybe_state = Some(KeyButtonData::Key { vk, pressed: false });
@@ -138,16 +138,11 @@ fn key_press(
app.hid_provider.send_key(*vk as _, true); app.hid_provider.send_key(*vk as _, true);
*pressed = true; *pressed = true;
} }
Some(KeyButtonData::Modifier { Some(KeyButtonData::Modifier { modifier, sticky }) => {
modifier,
sticky,
pressed,
}) => {
*sticky = data.modifiers & *modifier == 0; *sticky = data.modifiers & *modifier == 0;
data.modifiers |= *modifier; data.modifiers |= *modifier;
data.key_click(&app.session); data.key_click(&app.session);
app.hid_provider.set_modifiers(data.modifiers); app.hid_provider.set_modifiers(data.modifiers);
*pressed = true;
} }
Some(KeyButtonData::Macro { verbs }) => { Some(KeyButtonData::Macro { verbs }) => {
data.key_click(&app.session); data.key_click(&app.session);
@@ -178,16 +173,18 @@ fn key_release(
Some(KeyButtonData::Key { vk, pressed }) => { Some(KeyButtonData::Key { vk, pressed }) => {
app.hid_provider.send_key(*vk as _, false); app.hid_provider.send_key(*vk as _, false);
*pressed = false; *pressed = false;
for m in AUTO_RELEASE_MODS.iter() {
if data.modifiers & *m != 0 {
data.modifiers &= !*m;
app.hid_provider.set_modifiers(data.modifiers);
} }
Some(KeyButtonData::Modifier { }
modifier, }
sticky, Some(KeyButtonData::Modifier { modifier, sticky }) => {
pressed,
}) => {
if !*sticky { if !*sticky {
data.modifiers &= !*modifier; data.modifiers &= !*modifier;
app.hid_provider.set_modifiers(data.modifiers); app.hid_provider.set_modifiers(data.modifiers);
*pressed = false;
} }
} }
_ => {} _ => {}
@@ -196,12 +193,12 @@ fn key_release(
fn test_highlight( fn test_highlight(
control: &Control<KeyboardData, KeyButtonData>, control: &Control<KeyboardData, KeyButtonData>,
_data: &mut KeyboardData, data: &mut KeyboardData,
_app: &mut AppState, _app: &mut AppState,
) -> bool { ) -> bool {
match control.state.as_ref() { match control.state.as_ref() {
Some(KeyButtonData::Key { pressed, .. }) => *pressed, Some(KeyButtonData::Key { pressed, .. }) => *pressed,
Some(KeyButtonData::Modifier { pressed, .. }) => *pressed, Some(KeyButtonData::Modifier { modifier, .. }) => data.modifiers & *modifier != 0,
_ => false, _ => false,
} }
} }
@@ -240,22 +237,10 @@ impl KeyboardData {
} }
enum KeyButtonData { enum KeyButtonData {
Key { Key { vk: VirtualKey, pressed: bool },
vk: VirtualKey, Modifier { modifier: KeyModifier, sticky: bool },
pressed: bool, Macro { verbs: Vec<(VirtualKey, bool)> },
}, Exec { program: String, args: Vec<String> },
Modifier {
modifier: KeyModifier,
sticky: bool,
pressed: bool,
},
Macro {
verbs: Vec<(VirtualKey, bool)>,
},
Exec {
program: String,
args: Vec<String>,
},
} }
static LAYOUT: Lazy<Layout> = Lazy::new(Layout::load_from_disk); static LAYOUT: Lazy<Layout> = Lazy::new(Layout::load_from_disk);