Skip to content

Commit

Permalink
fix: reduce blast radius of windows sft-arrowkey workaround (#414)
Browse files Browse the repository at this point in the history
This commit makes changes to the blast radius of the workaround for
issue #138:

> Shift and arrows interact weirdly on a layer

Discovered in this issue was a problem where activating shift on keys
other than the physical shift keys, and then also pressing arrow keys,
caused stuck-shift behaviour. The fault is, as is typical, Windows'
weird behaviour. The workaround added was to release all shift key
states if a single shift key state was found to no longer exist, when
comparing the previous keyberon state to the current one.

In some cases, this release of shift causes an earlier release of shift
than is desired, because some other key activated shift. This commit
reduces the blast radius of the shift state releases to only states with
the physical lsft key. In hindsight, Windows' weird behaviour only
would have affected the physical lsft key's coordinate anyway, so this
is a good change to make. In addition, this issue only affects the
LLHOOK mechanism and not Interception, so the code is conditionally
compiled out for the Interception driver as well.
  • Loading branch information
jtroo committed May 22, 2023
1 parent f5a4a02 commit 18358ce
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
38 changes: 23 additions & 15 deletions src/kanata/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,19 +48,20 @@ pub fn set_win_altgr_behaviour(cfg: &cfg::Cfg) -> Result<()> {
Ok(())
}

fn state_filter(v: &State<'_, &&[&CustomAction]>) -> Option<State<'static, ()>> {
match v {
State::NormalKey { keycode, coord } => Some(State::NormalKey::<()> {
keycode: *keycode,
coord: *coord,
}),
State::FakeKey { keycode } => Some(State::FakeKey::<()> { keycode: *keycode }),
_ => None,
}
}

impl Kanata {
#[cfg(not(feature = "interception_driver"))]
pub fn check_release_non_physical_shift(&mut self) -> Result<()> {
fn state_filter(v: &State<'_, &&[&CustomAction]>) -> Option<State<'static, ()>> {
match v {
State::NormalKey { keycode, coord } => Some(State::NormalKey::<()> {
keycode: *keycode,
coord: *coord,
}),
State::FakeKey { keycode } => Some(State::FakeKey::<()> { keycode: *keycode }),
_ => None,
}
}

static PREV_STATES: Lazy<Mutex<Vec<State<'static, ()>>>> = Lazy::new(|| Mutex::new(vec![]));
let mut prev_states = PREV_STATES.lock();

Expand Down Expand Up @@ -96,12 +97,14 @@ impl Kanata {
{
continue;
}
log::debug!("releasing all {keycode:?}");
log::debug!(
"lsft-arrowkey workaround: releasing {keycode:?} at its typical coordinate"
);
self.layout.bm().states.retain(|s| match s {
State::NormalKey {
keycode: cur_kc, ..
}
| State::FakeKey { keycode: cur_kc } => cur_kc != keycode,
keycode: cur_kc,
coord: cur_coord,
} => cur_kc != keycode && *cur_coord != (0, u16::from(OsCode::from(keycode))),
_ => true,
});
log::debug!("releasing {keycode:?} from pressed keys");
Expand All @@ -116,4 +119,9 @@ impl Kanata {
prev_states.extend(self.layout.bm().states.iter().filter_map(state_filter));
Ok(())
}

#[cfg(feature = "interception_driver")]
pub fn check_release_non_physical_shift(&mut self) -> Result<()> {
Ok(())
}
}
1 change: 1 addition & 0 deletions src/oskbd/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ impl KbdOut {

/// Send using C-S-u + <unicode hex number> + spc
pub fn send_unicode(&mut self, c: char) -> Result<(), io::Error> {
log::debug!("sending unicode {c}");
let hex = format!("{:x}", c as u32);
self.press_key(OsCode::KEY_LEFTCTRL)?;
self.press_key(OsCode::KEY_LEFTSHIFT)?;
Expand Down
1 change: 1 addition & 0 deletions src/oskbd/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub use self::interception::*;
pub use interception_convert::*;

fn send_uc(c: char, up: bool) {
log::debug!("sending unicode {c}");
let mut inputs: [INPUT; 2] = unsafe { mem::zeroed() };

let n_inputs = inputs
Expand Down

0 comments on commit 18358ce

Please sign in to comment.