mirror of
https://github.com/lhns/steam-frame-nix.git
synced 2026-10-06 03:00:13 +02:00
keyboard.vr.functionKeys.enable (default off): while AltGr (Fn on layouts
without AltGr) is one-shot, locked or held, the strip shows F1-F12 instead
of the suggestions. A tap types the extra key VKX_F<n>, which the extra
keys' patch presses with xdotool together with the active Ctrl/Alt/Shift
(Alt+F4, Ctrl+F5) and releases the toggles; the text model resets, like
for Esc. The suggestions are kept as they are meanwhile, so when AltGr goes
off the strip shows the same items and selection again.
- vr-keyboard/function-keys.js: what the strip shows, the F-key keys.
- patch.js (VERSION 27): the strip's view, F-key picks, AltGr changes via
a componentDidUpdate on the keyboard instance (and the poll).
- Allowlist: F1-F12 with any modifiers; Enter still refused.
- relay.mjs: up to 12 strip items.
- Assertions: needs keyboard.vr.enable, extraKeys.enable and a strip
position "above"/"below" ("inside" would hide the AltGr number row).
- Tests: function-keys.test.mjs (switching and restoring, keys against
the allowlist, text model), allowlist F-key cases.
30 lines
1.5 KiB
JavaScript
30 lines
1.5 KiB
JavaScript
// Allowlist of xdotool-helper.mjs: requests come from Steam's UI JS, so the
|
|
// helper must not be able to type ASCII text or press Enter on its behalf.
|
|
// Accepted:
|
|
// key:<combo> the extra keys (Esc, Del, Home, End, PgUp/PgDn, arrows,
|
|
// F1-F12 from keyboard.vr.functionKeys), optionally with
|
|
// modifiers; ctrl and/or alt (+ optional
|
|
// shift) with one key; or shift+Tab
|
|
// type:<char> one character Steam's key emulation can't produce: non-ASCII
|
|
// (äöü߀§°´…) or | @ { [ ] } \ ~ ^ `
|
|
// down:<mod> / up:<mod> hold/release ctrl or alt (checked in the helper)
|
|
const SPECIAL = new Set(['Escape', 'Delete', 'Home', 'End', 'Prior', 'Next', 'Left', 'Right', 'Up', 'Down',
|
|
...Array.from({ length: 12 }, (_, i) => `F${i + 1}`)]);
|
|
const KEY = /^([a-z0-9]|space|BackSpace|Tab|period|comma|minus|plus|numbersign|less|slash|ssharp|udiaeresis|odiaeresis|adiaeresis)$/;
|
|
|
|
export function allowedCombo(combo) {
|
|
const parts = combo.split('+');
|
|
const key = parts.pop();
|
|
const mods = new Set(parts);
|
|
if (parts.length !== mods.size || ![...mods].every((m) => ['ctrl', 'alt', 'shift'].includes(m))) return false;
|
|
if (SPECIAL.has(key)) return true;
|
|
if (key === 'Tab' && mods.size === 1 && mods.has('shift')) return true; // backwards focus
|
|
return KEY.test(key) && (mods.has('ctrl') || mods.has('alt'));
|
|
}
|
|
|
|
export function allowedChar(c) {
|
|
if ([...c].length !== 1) return false;
|
|
const cp = c.codePointAt(0);
|
|
return (cp > 0xa0 && !/\s|\p{C}/u.test(c)) || '|@{[]}\\~^`'.includes(c);
|
|
}
|