fix(gui): fix encoding of base and shifted key codes

This commit is contained in:
CJ van den Berg 2026-03-30 21:37:31 +02:00
parent 6784797078
commit 932b640271
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9

View file

@ -296,7 +296,6 @@ fn wioLoop() void {
var held_buttons = input_translate.ButtonSet{}; var held_buttons = input_translate.ButtonSet{};
var mouse_pos: wio.Position = .{ .x = 0, .y = 0 }; var mouse_pos: wio.Position = .{ .x = 0, .y = 0 };
var text_input_active: bool = false;
var running = true; var running = true;
while (running) { while (running) {
@ -335,17 +334,17 @@ fn wioLoop() void {
yoff, yoff,
}) catch {}; }) catch {};
} else { } else {
const cp = input_translate.codepointFromButton(btn, mods); const base_cp = input_translate.codepointFromButton(btn, .{});
const deferred_to_char = text_input_active and !mods.ctrl and !mods.alt and cp >= 0x20 and cp <= 0x7e; const shifted_cp = input_translate.codepointFromButton(btn, .{ .shift = true });
if (cp != 0 and !deferred_to_char) sendKey(1, cp, cp, mods); if (base_cp != 0) sendKey(1, base_cp, shifted_cp, mods);
} }
}, },
.button_repeat => |btn| { .button_repeat => |btn| {
const mods = input_translate.Mods.fromButtons(held_buttons); const mods = input_translate.Mods.fromButtons(held_buttons);
if (input_translate.mouseButtonId(btn) == null) { if (input_translate.mouseButtonId(btn) == null) {
const cp = input_translate.codepointFromButton(btn, mods); const base_cp = input_translate.codepointFromButton(btn, .{});
const deferred_to_char = text_input_active and !mods.ctrl and !mods.alt and cp >= 0x20 and cp <= 0x7e; const shifted_cp = input_translate.codepointFromButton(btn, .{ .shift = true });
if (cp != 0 and !deferred_to_char) sendKey(2, cp, cp, mods); if (base_cp != 0) sendKey(2, base_cp, shifted_cp, mods);
} }
}, },
.button_release => |btn| { .button_release => |btn| {
@ -368,13 +367,19 @@ fn wioLoop() void {
yoff, yoff,
}) catch {}; }) catch {};
} else { } else {
const cp = input_translate.codepointFromButton(btn, mods); const base_cp = input_translate.codepointFromButton(btn, .{});
if (cp != 0) sendKey(3, cp, cp, mods); const shifted_cp = input_translate.codepointFromButton(btn, .{ .shift = true });
if (base_cp != 0) sendKey(3, base_cp, shifted_cp, mods);
} }
}, },
.char => |cp| { .char => |cp| {
const mods = input_translate.Mods.fromButtons(held_buttons); // Only handle non-ASCII IME-composed codepoints here.
sendKey(1, cp, cp, mods); // ASCII keys are fully handled by .button_press with correct
// base/shifted codepoints, avoiding double-firing on X11.
if (cp > 0x7f) {
const mods = input_translate.Mods.fromButtons(held_buttons);
sendKey(1, cp, cp, mods);
}
}, },
.mouse => |pos| { .mouse => |pos| {
mouse_pos = pos; mouse_pos = pos;
@ -394,14 +399,8 @@ fn wioLoop() void {
const row_cell: i32 = @intCast(@divTrunc(@as(i32, @intCast(mouse_pos.y)), wio_font.cell_size.y)); const row_cell: i32 = @intCast(@divTrunc(@as(i32, @intCast(mouse_pos.y)), wio_font.cell_size.y));
tui_pid.send(.{ "RDR", "B", @as(u8, 1), btn_id, col_cell, row_cell, @as(i32, 0), @as(i32, 0) }) catch {}; tui_pid.send(.{ "RDR", "B", @as(u8, 1), btn_id, col_cell, row_cell, @as(i32, 0), @as(i32, 0) }) catch {};
}, },
.focused => { .focused => window.enableTextInput(.{}),
text_input_active = true; .unfocused => window.disableTextInput(),
window.enableTextInput(.{});
},
.unfocused => {
text_input_active = false;
window.disableTextInput();
},
else => {}, else => {},
} }
} }
@ -512,8 +511,11 @@ fn sendResize(
fn sendKey(kind: u8, codepoint: u21, shifted_codepoint: u21, mods: input_translate.Mods) void { fn sendKey(kind: u8, codepoint: u21, shifted_codepoint: u21, mods: input_translate.Mods) void {
var text_buf: [4]u8 = undefined; var text_buf: [4]u8 = undefined;
const text_len = if (codepoint >= 0x20 and codepoint < 0x7f) // Text is the character that would be typed: empty when ctrl/alt active,
std.unicode.utf8Encode(codepoint, &text_buf) catch 0 // shifted_codepoint when shift is held, otherwise codepoint.
const text_cp: u21 = if (mods.shift) shifted_codepoint else codepoint;
const text_len: usize = if (!mods.ctrl and !mods.alt and text_cp >= 0x20 and text_cp != 0x7f)
std.unicode.utf8Encode(text_cp, &text_buf) catch 0
else else
0; 0;
tui_pid.send(.{ tui_pid.send(.{