Skip to content

Commit

Permalink
feat: deflocalkeys-winiov2 (#893)
Browse files Browse the repository at this point in the history
- Add deflocalkeys-winiov2
- Update windows_key_tester to support winiov2
  • Loading branch information
jtroo authored Mar 30, 2024
1 parent cebf123 commit 10c424a
Show file tree
Hide file tree
Showing 15 changed files with 181 additions and 87 deletions.
11 changes: 10 additions & 1 deletion .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,26 @@ jobs:
shared-key: "persist-cross-job"
workspaces: ./
- run: rustup component add clippy

- name: Run tests no features
run: cargo test --all --no-default-features
- name: Run clippy no features
run: cargo clippy --all --no-default-features -- -D warnings

- name: Run tests default features
run: cargo test --all
- name: Run clippy default features
run: cargo clippy --all -- -D warnings

- name: Run tests winIOv2
run: cargo test --all --features=cmd,win_llhook_read_scancodes,win_sendinput_send_scancodes
- name: Run clippy all winIOv2
run: cargo clippy --all --features=cmd,win_llhook_read_scancodes,win_sendinput_send_scancodes -- -D warnings

- name: Run tests all features
run: cargo test --all --features=cmd,interception_driver,win_sendinput_send_scancodes
- name: Run clippy all features
run: cargo clippy --all --features=cmd,interception_driver,win_sendinput_send_scancodes -- -D warnings
- name: Run check simulated output

- name: Run clippy simulated output
run: cargo clippy --all --features=simulated_output,cmd -- -D warnings
14 changes: 14 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"example_tcp_client",
"tcp_protocol",
"simulated_input",
"windows_key_tester",
]

[package]
Expand Down
8 changes: 7 additions & 1 deletion cfg_samples/kanata.kbd
Original file line number Diff line number Diff line change
Expand Up @@ -240,10 +240,12 @@ If you need help, please feel welcome to ask in the GitHub discussions.
;; deflocalkeys-* enables you to define and use key names that match your locale
;; by defining OS code number mappings for that character.
;;
;; There are three variants of deflocalkeys-*:
;; There are five variants of deflocalkeys-*:
;; - deflocalkeys-win
;; - deflocalkeys-winiov2
;; - deflocalkeys-wintercept
;; - deflocalkeys-linux
;; - deflocalkeys-macos
;;
;; Only one of each deflocalkeys-* variant is allowed. The variants that are
;; not applicable will be ignored, e.g. deflocalkeys-linux and deflocalkeys-wintercept
Expand Down Expand Up @@ -274,6 +276,10 @@ If you need help, please feel welcome to ask in the GitHub discussions.
ì 187
)

(deflocalkeys-winiov2
ì 187
)

(deflocalkeys-linux
ì 13
)
Expand Down
28 changes: 17 additions & 11 deletions docs/config.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -253,27 +253,22 @@ you may want to use `deflayermap` if remapping using these key names.

WARNING: On Windows, you should use either `kanata_winIOv2.exe`
or Interception when using key names according to the browser `event.code`.
The default `kanata.exe` does do remappings according to the browser `event.code`
keys.
The default `kanata.exe` does not do mappings according to the browser `event.code`
key names.

=== deflocalkeys

You can use `deflocalkeys` to define additional key names that can be
used in `defsrc`, `deflayer` and anywhere else in the configuration.

There are four variants of deflocalkeys:
There are five variants of deflocalkeys:

- `deflocalkeys-win`
- `deflocalkeys-winiov2`
- `deflocalkeys-wintercept`
- `deflocalkeys-linux`
- `deflocalkeys-macos`

WARNING: On Windows,
`kanata_winIOv2.exe` does not work using the values from `win-keycode-tester`.
In other words, `kanata.exe` and `kanata_winIOv2.exe` both use
`deflocalkeys-win` but do not agree.
The latest keycode tester program works correctly for the default `kanata.exe`.

Only one of each deflocalkeys-* variant is allowed. The variants that are not
applicable will be ignored, e.g. `deflocalkeys-linux` and `deflocalkeys-wintercept`
are both ignored when using the default Windows kanata binary.
Expand All @@ -292,6 +287,10 @@ Please contribute to the document if you are able!
ì 187
)
(deflocalkeys-winiov2
ì 187
)
(deflocalkeys-wintercept
ì 187
)
Expand All @@ -315,13 +314,20 @@ base 10. This differs between Windows-hooks, Windows-interception, and Linux.
In Linux, `evtest` will give the correct number for the physical key you press.

In Windows using the default hook mechanism, the non-interception version of the
keyboard tester in the kanata repository will give the correct number.
keyboard tester in the kanata repository will give the correct number
in the `code: <number>` section.
(https://github.com/jtroo/kanata/releases/tag/win-keycode-tester-v0.2.0[prebuilt binary])

In Windows uning `winIOv2`, the winIOv2 executable variant
will give the correct number in the `code: <number>` section.

In Windows using Interception, the interception version of the keyboard tester
will give the correct number. Between the hook and interception versions, some
will give the correct number i the `num: <number>` section.
Between the hook and interception versions, some
keys may agree but others may not; do be aware that they are **not** compatible!

However, Interception and winIOv2 should generally agree with each other.

Ideas for improving the user-friendliness of this system are welcome! As
mentioned before, please ask for help in an issue or discussion if needed, and
help with https://github.com/jtroo/kanata/blob/main/docs/locales.adoc[this document]
Expand Down
17 changes: 16 additions & 1 deletion parser/src/cfg/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,8 +289,21 @@ fn parse_cfg(p: &Path) -> MResult<Cfg> {
})
}

#[cfg(all(not(feature = "interception_driver"), target_os = "windows"))]
#[cfg(all(
not(feature = "interception_driver"),
any(
not(feature = "win_llhook_read_scancodes"),
not(feature = "win_sendinput_send_scancodes")
),
target_os = "windows"
))]
const DEF_LOCAL_KEYS: &str = "deflocalkeys-win";
#[cfg(all(
feature = "win_llhook_read_scancodes",
feature = "win_sendinput_send_scancodes",
target_os = "windows"
))]
const DEF_LOCAL_KEYS: &str = "deflocalkeys-winiov2";
#[cfg(all(feature = "interception_driver", target_os = "windows"))]
const DEF_LOCAL_KEYS: &str = "deflocalkeys-wintercept";
#[cfg(target_os = "macos")]
Expand Down Expand Up @@ -430,6 +443,7 @@ pub fn parse_cfg_raw_string(
clear_custom_str_oscode_mapping();
for def_local_keys_variant in [
"deflocalkeys-win",
"deflocalkeys-winiov2",
"deflocalkeys-wintercept",
"deflocalkeys-linux",
"deflocalkeys-macos",
Expand Down Expand Up @@ -709,6 +723,7 @@ fn error_on_unknown_top_level_atoms(exprs: &[Spanned<Vec<SExpr>>]) -> Result<()>
| "deflocalkeys-macos"
| "deflocalkeys-linux"
| "deflocalkeys-win"
| "deflocalkeys-winiov2"
| "deflocalkeys-wintercept"
| "deffakekeys"
| "defvirtualkeys"
Expand Down
19 changes: 19 additions & 0 deletions parser/src/cfg/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1256,6 +1256,25 @@ yen 314
¥ 315
new 316
)
(deflocalkeys-winiov2
+ 300
[ 301
] 302
{ 303
} 304
/ 305
; 306
` 307
= 308
- 309
' 310
, 311
. 312
\ 313
yen 314
¥ 315
new 316
)
(deflocalkeys-wintercept
+ 300
[ 301
Expand Down
4 changes: 3 additions & 1 deletion src/oskbd/windows/llhook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ impl InputEvent {
} else {
0
};
crate::oskbd::u16_to_osc((lparam.scanCode as u16) | extended).map(Into::into).unwrap_or(lparam.vkCode)
crate::oskbd::u16_to_osc((lparam.scanCode as u16) | extended)
.map(Into::into)
.unwrap_or(lparam.vkCode)
}
};
Self {
Expand Down
2 changes: 1 addition & 1 deletion src/oskbd/windows/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub use llhook::*;

mod scancode_to_usvk;
#[allow(unused)]
pub(crate) use scancode_to_usvk::*;
pub use scancode_to_usvk::*;

#[cfg(feature = "interception_driver")]
mod interception;
Expand Down
2 changes: 1 addition & 1 deletion src/oskbd/windows/scancode_to_usvk.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use kanata_parser::keys::OsCode;

#[allow(unused)]
pub(crate) fn u16_to_osc(input: u16) -> Option<OsCode> {
pub fn u16_to_osc(input: u16) -> Option<OsCode> {
Some(if input < 0xE000 {
match input {
0x01 => OsCode::KEY_ESC,
Expand Down
15 changes: 8 additions & 7 deletions windows_key_tester/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "windows_key_tester"
version = "0.2.0"
version = "0.3.0"
authors = ["jtroo <[email protected]>"]
description = "Windows keycode tester"
keywords = []
Expand All @@ -11,8 +11,8 @@ readme = "README.md"
license = "LGPL-3.0"
edition = "2021"

[dependencies]
clap = { version = "3", features = [ "derive" ] }
[target.'cfg(target_os = "windows")'.dependencies]
clap = { version = "4", features = [ "std", "derive", "help", "suggestions" ], default_features = false }
log = "0.4.8"
simplelog = "0.12.0"
anyhow = "1"
Expand All @@ -21,12 +21,13 @@ winapi = { version = "0.3.9", features = [
"timeapi",
"mmsystem",
] }
native-windows-gui = "1.0.12"
interception = { version = "0.1.2", optional = true }
native-windows-gui = { version = "1.0.12", default_features = false }
kanata-interception = { version = "0.2.0", optional = true }
kanata = { path = "..", optional = true }

[features]
cmd = []
interception_driver = [ "interception" ]
interception_driver = [ "kanata-interception" ]
winiov2 = [ "kanata" ]

[profile.release]
opt-level = "z"
Expand Down
72 changes: 11 additions & 61 deletions windows_key_tester/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,22 @@
//! events, print out the event info, then forward it the keyboard event as-is to the rest of the
//! operating system handling.

use anyhow::Result;
use log::info;
use simplelog::*;
#[cfg(target_os = "windows")]
mod windows;
#[cfg(target_os = "windows")]
use windows::*;

use clap::Parser;

#[cfg(not(feature = "interception_driver"))]
mod llhook;
#[cfg(not(feature = "interception_driver"))]
use llhook::*;

#[cfg(feature = "interception_driver")]
mod interception;
#[cfg(feature = "interception_driver")]
use crate::interception::*;

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
/// Enable debug logging
#[clap(short, long)]
debug: bool,

/// Enable trace logging (implies --debug as well)
#[clap(short, long)]
trace: bool,
}

/// Parse CLI arguments and initialize logging.
fn cli_init() {
let args = Args::parse();

let log_lvl = match (args.debug, args.trace) {
(_, true) => LevelFilter::Trace,
(true, false) => LevelFilter::Debug,
(false, false) => LevelFilter::Info,
};

let mut log_cfg = ConfigBuilder::new();
if let Err(e) = log_cfg.set_time_offset_to_local() {
eprintln!("WARNING: could not set log TZ to local: {:?}", e);
};
CombinedLogger::init(vec![TermLogger::new(
log_lvl,
log_cfg.build(),
TerminalMode::Mixed,
ColorChoice::AlwaysAnsi,
)])
.expect("logger can init");
log::info!("windows_key_tester v{} starting", env!("CARGO_PKG_VERSION"));
}

fn main_impl() -> Result<()> {
cli_init();
info!("Sleeping for 2s. Please release all keys and don't press additional ones.");
std::thread::sleep(std::time::Duration::from_secs(2));
start()?;
Ok(())
}

fn main() -> Result<()> {
#[cfg(target_os = "windows")]
fn main() {
let ret = main_impl();
if let Err(ref e) = ret {
log::error!("main got error {}", e);
}
eprintln!("\nPress any key to exit");
let _ = std::io::stdin().read_line(&mut String::new());
ret
}

#[cfg(not(target_os = "windows"))]
fn main() {
print!("Hello world! Wrong OS. Doing nothing.");
}
Loading

0 comments on commit 10c424a

Please sign in to comment.