diff --git a/src/apprt/embedded.zig b/src/apprt/embedded.zig index ffcf7fdbe..18674bc38 100644 --- a/src/apprt/embedded.zig +++ b/src/apprt/embedded.zig @@ -224,6 +224,7 @@ pub const App = struct { const result: input.Keymap.Translation = if (event_text) |text| .{ .text = text, .composing = event.composing, + .mods = translate_mods, } else try self.keymap.translate( &buf, switch (target) { @@ -231,14 +232,7 @@ pub const App = struct { .surface => |surface| &surface.keymap_state, }, @intCast(keycode), - if (comptime builtin.target.isDarwin()) mods: { - // On macOS we strip ctrl because UCKeyTranslate - // converts to the masked values (i.e. ctrl+c becomes 3) - // and we don't want that behavior. - var v = translate_mods; - v.ctrl = false; - break :mods v; - } else translate_mods, + translate_mods, ); // TODO(mitchellh): I think we can get rid of the above keymap @@ -275,16 +269,12 @@ pub const App = struct { // then we clear the text. We handle non-printables in the // key encoder manual (such as tab, ctrl+c, etc.) if (result.text.len == 1 and result.text[0] < 0x20) { - break :translate .{ .composing = false, .text = "" }; + break :translate .{}; } } break :translate result; - } else .{ .composing = false, .text = "" }; - - // UCKeyTranslate always consumes all mods, so if we have any output - // then we've consumed our translate mods. - const consumed_mods: input.Mods = if (result.text.len > 0) translate_mods else .{}; + } else .{}; // We need to always do a translation with no modifiers at all in // order to get the "unshifted_codepoint" for the key event. @@ -356,7 +346,7 @@ pub const App = struct { .key = key, .physical_key = physical_key, .mods = mods, - .consumed_mods = consumed_mods, + .consumed_mods = result.mods, .composing = result.composing, .utf8 = result.text, .unshifted_codepoint = unshifted_codepoint, diff --git a/src/input/KeymapDarwin.zig b/src/input/KeymapDarwin.zig index 3d81b0f4b..154f648a6 100644 --- a/src/input/KeymapDarwin.zig +++ b/src/input/KeymapDarwin.zig @@ -50,10 +50,13 @@ pub const State = struct { pub const Translation = struct { /// The translation result. If this is a dead key state, then this will /// be pre-edit text that can be displayed but will ultimately be replaced. - text: []const u8, + text: []const u8 = "", /// Whether the text is still composing, i.e. this is a dead key state. - composing: bool, + composing: bool = false, + + /// The mods that were consumed to produce this translation + mods: Mods = .{}, }; pub fn init() !Keymap { @@ -122,8 +125,18 @@ pub fn translate( out: []u8, state: *State, code: u16, - mods: Mods, + input_mods: Mods, ) !Translation { + // On macOS we strip ctrl because UCKeyTranslate + // converts to the masked values (i.e. ctrl+c becomes 3) + // and we don't want that behavior in Ghostty ever. This makes + // this file not a general-purpose keymap implementation. + const mods: Mods = mods: { + var v = input_mods; + v.ctrl = false; + break :mods v; + }; + // Get the keycode for the space key, using comptime. const code_space: u16 = comptime space: for (codes) |entry| { if (std.mem.eql(u8, entry.code, "Space")) @@ -183,7 +196,11 @@ pub fn translate( // Convert the utf16 to utf8 const len = try std.unicode.utf16leToUtf8(out, char[0..char_count]); - return .{ .text = out[0..len], .composing = composing }; + return .{ + .text = out[0..len], + .composing = composing, + .mods = mods, + }; } /// Map to the modifiers format used by the UCKeyTranslate function. diff --git a/src/input/KeymapNoop.zig b/src/input/KeymapNoop.zig index 414c52954..b6a9d57b9 100644 --- a/src/input/KeymapNoop.zig +++ b/src/input/KeymapNoop.zig @@ -6,8 +6,9 @@ const Mods = @import("key.zig").Mods; pub const State = struct {}; pub const Translation = struct { - text: []const u8, - composing: bool, + text: []const u8 = "", + composing: bool = false, + mods: Mods = .{}, }; pub fn init() !KeymapNoop {