diff --git a/src/gui/wio/input.zig b/src/gui/wio/input.zig index 3d968b56..0b43b78f 100644 --- a/src/gui/wio/input.zig +++ b/src/gui/wio/input.zig @@ -23,6 +23,11 @@ pub const Mods = packed struct(u8) { .super = pressed.has(.left_gui) or pressed.has(.right_gui), }; } + + /// True only when shift is the sole active modifier. + pub fn shiftOnly(self: Mods) bool { + return self.shift and !self.alt and !self.ctrl and !self.super and !self.hyper and !self.meta; + } }; // Simple set of currently held buttons (for modifier tracking) @@ -54,58 +59,58 @@ pub const KeyEvent = struct { // Map a wio.Button to the primary codepoint for that key pub fn codepointFromButton(b: wio.Button, mods: Mods) u21 { return switch (b) { - .a => if (mods.shift) 'A' else 'a', - .b => if (mods.shift) 'B' else 'b', - .c => if (mods.shift) 'C' else 'c', - .d => if (mods.shift) 'D' else 'd', - .e => if (mods.shift) 'E' else 'e', - .f => if (mods.shift) 'F' else 'f', - .g => if (mods.shift) 'G' else 'g', - .h => if (mods.shift) 'H' else 'h', - .i => if (mods.shift) 'I' else 'i', - .j => if (mods.shift) 'J' else 'j', - .k => if (mods.shift) 'K' else 'k', - .l => if (mods.shift) 'L' else 'l', - .m => if (mods.shift) 'M' else 'm', - .n => if (mods.shift) 'N' else 'n', - .o => if (mods.shift) 'O' else 'o', - .p => if (mods.shift) 'P' else 'p', - .q => if (mods.shift) 'Q' else 'q', - .r => if (mods.shift) 'R' else 'r', - .s => if (mods.shift) 'S' else 's', - .t => if (mods.shift) 'T' else 't', - .u => if (mods.shift) 'U' else 'u', - .v => if (mods.shift) 'V' else 'v', - .w => if (mods.shift) 'W' else 'w', - .x => if (mods.shift) 'X' else 'x', - .y => if (mods.shift) 'Y' else 'y', - .z => if (mods.shift) 'Z' else 'z', - .@"0" => if (mods.shift) ')' else '0', - .@"1" => if (mods.shift) '!' else '1', - .@"2" => if (mods.shift) '@' else '2', - .@"3" => if (mods.shift) '#' else '3', - .@"4" => if (mods.shift) '$' else '4', - .@"5" => if (mods.shift) '%' else '5', - .@"6" => if (mods.shift) '^' else '6', - .@"7" => if (mods.shift) '&' else '7', - .@"8" => if (mods.shift) '*' else '8', - .@"9" => if (mods.shift) '(' else '9', + .a => if (mods.shiftOnly()) 'A' else 'a', + .b => if (mods.shiftOnly()) 'B' else 'b', + .c => if (mods.shiftOnly()) 'C' else 'c', + .d => if (mods.shiftOnly()) 'D' else 'd', + .e => if (mods.shiftOnly()) 'E' else 'e', + .f => if (mods.shiftOnly()) 'F' else 'f', + .g => if (mods.shiftOnly()) 'G' else 'g', + .h => if (mods.shiftOnly()) 'H' else 'h', + .i => if (mods.shiftOnly()) 'I' else 'i', + .j => if (mods.shiftOnly()) 'J' else 'j', + .k => if (mods.shiftOnly()) 'K' else 'k', + .l => if (mods.shiftOnly()) 'L' else 'l', + .m => if (mods.shiftOnly()) 'M' else 'm', + .n => if (mods.shiftOnly()) 'N' else 'n', + .o => if (mods.shiftOnly()) 'O' else 'o', + .p => if (mods.shiftOnly()) 'P' else 'p', + .q => if (mods.shiftOnly()) 'Q' else 'q', + .r => if (mods.shiftOnly()) 'R' else 'r', + .s => if (mods.shiftOnly()) 'S' else 's', + .t => if (mods.shiftOnly()) 'T' else 't', + .u => if (mods.shiftOnly()) 'U' else 'u', + .v => if (mods.shiftOnly()) 'V' else 'v', + .w => if (mods.shiftOnly()) 'W' else 'w', + .x => if (mods.shiftOnly()) 'X' else 'x', + .y => if (mods.shiftOnly()) 'Y' else 'y', + .z => if (mods.shiftOnly()) 'Z' else 'z', + .@"0" => if (mods.shiftOnly()) ')' else '0', + .@"1" => if (mods.shiftOnly()) '!' else '1', + .@"2" => if (mods.shiftOnly()) '@' else '2', + .@"3" => if (mods.shiftOnly()) '#' else '3', + .@"4" => if (mods.shiftOnly()) '$' else '4', + .@"5" => if (mods.shiftOnly()) '%' else '5', + .@"6" => if (mods.shiftOnly()) '^' else '6', + .@"7" => if (mods.shiftOnly()) '&' else '7', + .@"8" => if (mods.shiftOnly()) '*' else '8', + .@"9" => if (mods.shiftOnly()) '(' else '9', .space => ' ', .enter => '\r', .tab => '\t', .backspace => 0x7f, .escape => 0x1b, - .minus => if (mods.shift) '_' else '-', - .equals => if (mods.shift) '+' else '=', - .left_bracket => if (mods.shift) '{' else '[', - .right_bracket => if (mods.shift) '}' else ']', - .backslash => if (mods.shift) '|' else '\\', - .semicolon => if (mods.shift) ':' else ';', - .apostrophe => if (mods.shift) '"' else '\'', - .grave => if (mods.shift) '~' else '`', - .comma => if (mods.shift) '<' else ',', - .dot => if (mods.shift) '>' else '.', - .slash => if (mods.shift) '?' else '/', + .minus => if (mods.shiftOnly()) '_' else '-', + .equals => if (mods.shiftOnly()) '+' else '=', + .left_bracket => if (mods.shiftOnly()) '{' else '[', + .right_bracket => if (mods.shiftOnly()) '}' else ']', + .backslash => if (mods.shiftOnly()) '|' else '\\', + .semicolon => if (mods.shiftOnly()) ':' else ';', + .apostrophe => if (mods.shiftOnly()) '"' else '\'', + .grave => if (mods.shiftOnly()) '~' else '`', + .comma => if (mods.shiftOnly()) '<' else ',', + .dot => if (mods.shiftOnly()) '>' else '.', + .slash => if (mods.shiftOnly()) '?' else '/', // Navigation keys map to special Unicode private-use codepoints // that Flow's input layer understands (matching kitty protocol). .up => 0xF700,