mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-16 16:15:23 -04:00
2fd9de5062
* fix(keybinds): record numpad keys as KP_* keysyms The shortcut recorder passed only the Qt key code to xkbKeyFromQtKey and dropped Qt.KeypadModifier. Since Qt reuses the same Qt::Key_* values for the numpad and the main row / nav cluster, numpad presses collapsed onto their twins: numpad-7 became "7" (NumLock on) or "Home" (NumLock off) instead of "KP_7"/"KP_Home", numpad-+ became "Equal", numpad-* became "8", numpad Enter became "Return". numpad-5 with NumLock off (Qt.Key_Clear) was missing from the map entirely, so the capture was silently dropped. niri and the other providers bind against the xkb KP_* keysym names, so these tokens never matched the physical key. Pass the keypad flag through to xkbKeyFromQtKey and map keypad presses to the KP_* keysyms: KP_0..KP_9 for the NumLock-on digit codes, the navigation names (KP_Home, KP_End, KP_Up, ...) for the NumLock-off codes, plus the operators and KP_Enter. Main-row keys are unaffected because they never carry the keypad modifier. * fix(keybinds): ignore lock keys while capturing a shortcut NumLock/CapsLock/ScrollLock are toggles, not useful bind targets. Pressing NumLock to switch the numpad between its digit and navigation keysyms (KP_7 vs KP_Home) was captured as the bind itself (e.g. "Super+Num_Lock"). Skip them in the recorder like the other pure modifier keys already are.
222 lines
5.7 KiB
JavaScript
222 lines
5.7 KiB
JavaScript
.pragma library
|
|
|
|
const KEY_MAP = {
|
|
16777234: "Left",
|
|
16777236: "Right",
|
|
16777235: "Up",
|
|
16777237: "Down",
|
|
44: "Comma",
|
|
46: "Period",
|
|
47: "Slash",
|
|
59: "Semicolon",
|
|
39: "Apostrophe",
|
|
91: "BracketLeft",
|
|
93: "BracketRight",
|
|
92: "Backslash",
|
|
45: "Minus",
|
|
61: "Equal",
|
|
96: "grave",
|
|
32: "space",
|
|
16777225: "Print",
|
|
16777226: "Print",
|
|
16777220: "Return",
|
|
16777221: "Return",
|
|
16777217: "Tab",
|
|
16777219: "BackSpace",
|
|
16777223: "Delete",
|
|
16777222: "Insert",
|
|
16777232: "Home",
|
|
16777233: "End",
|
|
16777238: "Page_Up",
|
|
16777239: "Page_Down",
|
|
16777216: "Escape",
|
|
16777252: "Caps_Lock",
|
|
16777253: "Num_Lock",
|
|
16777254: "Scroll_Lock",
|
|
16777224: "Pause",
|
|
16777330: "XF86AudioRaiseVolume",
|
|
16777328: "XF86AudioLowerVolume",
|
|
16777329: "XF86AudioMute",
|
|
16842808: "XF86AudioMicMute",
|
|
16777344: "XF86AudioPlay",
|
|
16777345: "XF86AudioStop",
|
|
16777346: "XF86AudioPrev",
|
|
16777347: "XF86AudioNext",
|
|
16777348: "XF86AudioPause",
|
|
16777349: "XF86AudioMedia",
|
|
16777350: "XF86AudioRecord",
|
|
16842798: "XF86MonBrightnessUp",
|
|
16777394: "XF86MonBrightnessUp",
|
|
16842797: "XF86MonBrightnessDown",
|
|
16777395: "XF86MonBrightnessDown",
|
|
16842800: "XF86KbdBrightnessUp",
|
|
16842799: "XF86KbdBrightnessDown",
|
|
16842796: "XF86PowerOff",
|
|
16842803: "XF86Sleep",
|
|
16842804: "XF86WakeUp",
|
|
16842802: "XF86Eject",
|
|
16842791: "XF86Calculator",
|
|
16842806: "XF86Explorer",
|
|
16777360: "XF86HomePage",
|
|
16842794: "XF86HomePage",
|
|
16777362: "XF86Search",
|
|
16777426: "XF86Search",
|
|
16777376: "XF86Mail",
|
|
16777427: "XF86Mail",
|
|
16777377: "XF86AudioMedia",
|
|
16777419: "XF86Calculator",
|
|
16777429: "XF86Explorer",
|
|
16777442: "XF86Launch0",
|
|
16777443: "XF86Launch1",
|
|
33: "1",
|
|
64: "2",
|
|
35: "3",
|
|
36: "4",
|
|
37: "5",
|
|
94: "6",
|
|
38: "7",
|
|
42: "8",
|
|
40: "9",
|
|
41: "0",
|
|
60: "Comma",
|
|
62: "Period",
|
|
63: "Slash",
|
|
58: "Semicolon",
|
|
34: "Apostrophe",
|
|
123: "BracketLeft",
|
|
125: "BracketRight",
|
|
124: "Backslash",
|
|
95: "Minus",
|
|
43: "Equal",
|
|
126: "grave",
|
|
196: "Adiaeresis",
|
|
214: "Odiaeresis",
|
|
220: "Udiaeresis",
|
|
228: "adiaeresis",
|
|
246: "odiaeresis",
|
|
252: "udiaeresis",
|
|
223: "ssharp",
|
|
201: "Eacute",
|
|
233: "eacute",
|
|
200: "Egrave",
|
|
232: "egrave",
|
|
202: "Ecircumflex",
|
|
234: "ecircumflex",
|
|
203: "Ediaeresis",
|
|
235: "ediaeresis",
|
|
192: "Agrave",
|
|
224: "agrave",
|
|
194: "Acircumflex",
|
|
226: "acircumflex",
|
|
199: "Ccedilla",
|
|
231: "ccedilla",
|
|
206: "Icircumflex",
|
|
238: "icircumflex",
|
|
207: "Idiaeresis",
|
|
239: "idiaeresis",
|
|
212: "Ocircumflex",
|
|
244: "ocircumflex",
|
|
217: "Ugrave",
|
|
249: "ugrave",
|
|
219: "Ucircumflex",
|
|
251: "ucircumflex",
|
|
209: "Ntilde",
|
|
241: "ntilde",
|
|
191: "questiondown",
|
|
161: "exclamdown"
|
|
};
|
|
|
|
// Numpad (keypad) keys. Qt reuses the same Qt::Key_* values for the numpad and
|
|
// the main rows/nav cluster; only Qt.KeypadModifier distinguishes them. niri and
|
|
// the other compositors bind against the xkb KP_* keysym names, so we must emit
|
|
// those instead of the collapsed twin. With NumLock off the numpad sends the
|
|
// navigation keysyms (KP_Home, KP_End, ...); with NumLock on it sends KP_0..KP_9
|
|
// (handled by the digit range in xkbKeyFromQtKey). Operators/Enter are the same
|
|
// in both states.
|
|
const KP_MAP = {
|
|
16777232: "KP_Home",
|
|
16777235: "KP_Up",
|
|
16777238: "KP_Prior",
|
|
16777234: "KP_Left",
|
|
16777227: "KP_Begin",
|
|
16777236: "KP_Right",
|
|
16777233: "KP_End",
|
|
16777237: "KP_Down",
|
|
16777239: "KP_Next",
|
|
16777222: "KP_Insert",
|
|
16777223: "KP_Delete",
|
|
16777221: "KP_Enter",
|
|
43: "KP_Add",
|
|
45: "KP_Subtract",
|
|
42: "KP_Multiply",
|
|
47: "KP_Divide",
|
|
46: "KP_Decimal"
|
|
};
|
|
|
|
function xkbKeyFromQtKey(qk, isKeypad) {
|
|
if (isKeypad) {
|
|
if (qk >= 48 && qk <= 57)
|
|
return "KP_" + (qk - 48);
|
|
if (KP_MAP[qk])
|
|
return KP_MAP[qk];
|
|
}
|
|
if (qk >= 65 && qk <= 90)
|
|
return String.fromCharCode(qk);
|
|
if (qk >= 97 && qk <= 122)
|
|
return String.fromCharCode(qk - 32);
|
|
if (qk >= 48 && qk <= 57)
|
|
return String.fromCharCode(qk);
|
|
if (qk >= 16777264 && qk <= 16777298)
|
|
return "F" + (qk - 16777264 + 1);
|
|
if (qk >= 16777378 && qk <= 16777387)
|
|
return "XF86Launch" + (qk - 16777378);
|
|
if (qk >= 16777388 && qk <= 16777393)
|
|
return "XF86Launch" + String.fromCharCode(65 + qk - 16777388);
|
|
return KEY_MAP[qk] || "";
|
|
}
|
|
|
|
function modsFromEvent(mods) {
|
|
var result = [];
|
|
if (mods & 0x10000000)
|
|
result.push("Super");
|
|
if (mods & 0x08000000)
|
|
result.push("Alt");
|
|
if (mods & 0x04000000)
|
|
result.push("Ctrl");
|
|
if (mods & 0x02000000)
|
|
result.push("Shift");
|
|
return result;
|
|
}
|
|
|
|
function formatToken(mods, key) {
|
|
return (mods.length ? mods.join("+") + "+" : "") + key;
|
|
}
|
|
|
|
function normalizeKeyCombo(keyCombo) {
|
|
if (!keyCombo)
|
|
return "";
|
|
return keyCombo.toLowerCase().replace(/\bmod\b/g, "super").replace(/\bsuper\b/g, "super");
|
|
}
|
|
|
|
function getConflictingBinds(keyCombo, currentAction, allBinds) {
|
|
if (!keyCombo)
|
|
return [];
|
|
var conflicts = [];
|
|
var normalizedKey = normalizeKeyCombo(keyCombo);
|
|
for (var i = 0; i < allBinds.length; i++) {
|
|
var bind = allBinds[i];
|
|
if (bind.action === currentAction)
|
|
continue;
|
|
for (var k = 0; k < bind.keys.length; k++) {
|
|
if (normalizeKeyCombo(bind.keys[k].key) === normalizedKey) {
|
|
conflicts.push({
|
|
action: bind.action,
|
|
desc: bind.desc || bind.action
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return conflicts;
|
|
}
|