mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
macos: don't do full surface-style key translation for imgui
This commit is contained in:
@ -413,7 +413,7 @@ void ghostty_inspector_set_size(ghostty_inspector_t, uint32_t, uint32_t);
|
||||
void ghostty_inspector_mouse_button(ghostty_inspector_t, ghostty_input_mouse_state_e, ghostty_input_mouse_button_e, ghostty_input_mods_e);
|
||||
void ghostty_inspector_mouse_pos(ghostty_inspector_t, double, double);
|
||||
void ghostty_inspector_mouse_scroll(ghostty_inspector_t, double, double, ghostty_input_scroll_mods_t);
|
||||
void ghostty_inspector_key(ghostty_inspector_t, ghostty_input_action_e, uint32_t, ghostty_input_mods_e);
|
||||
void ghostty_inspector_key(ghostty_inspector_t, ghostty_input_action_e, ghostty_input_key_e, ghostty_input_mods_e);
|
||||
void ghostty_inspector_text(ghostty_inspector_t, const char *);
|
||||
|
||||
// APIs I'd like to get rid of eventually but are still needed for now.
|
||||
|
@ -235,5 +235,122 @@ extension Ghostty {
|
||||
0x3B: GHOSTTY_KEY_SEMICOLON,
|
||||
0x2F: GHOSTTY_KEY_SLASH,
|
||||
]
|
||||
|
||||
// Mapping of event keyCode to ghostty input key values. This is cribbed from
|
||||
// glfw mostly since we started as a glfw-based app way back in the day!
|
||||
static let keycodeToKey: [UInt16 : ghostty_input_key_e] = [
|
||||
0x1D: GHOSTTY_KEY_ZERO,
|
||||
0x12: GHOSTTY_KEY_ONE,
|
||||
0x13: GHOSTTY_KEY_TWO,
|
||||
0x14: GHOSTTY_KEY_THREE,
|
||||
0x15: GHOSTTY_KEY_FOUR,
|
||||
0x17: GHOSTTY_KEY_FIVE,
|
||||
0x16: GHOSTTY_KEY_SIX,
|
||||
0x1A: GHOSTTY_KEY_SEVEN,
|
||||
0x1C: GHOSTTY_KEY_EIGHT,
|
||||
0x19: GHOSTTY_KEY_NINE,
|
||||
0x00: GHOSTTY_KEY_A,
|
||||
0x0B: GHOSTTY_KEY_B,
|
||||
0x08: GHOSTTY_KEY_C,
|
||||
0x02: GHOSTTY_KEY_D,
|
||||
0x0E: GHOSTTY_KEY_E,
|
||||
0x03: GHOSTTY_KEY_F,
|
||||
0x05: GHOSTTY_KEY_G,
|
||||
0x04: GHOSTTY_KEY_H,
|
||||
0x22: GHOSTTY_KEY_I,
|
||||
0x26: GHOSTTY_KEY_J,
|
||||
0x28: GHOSTTY_KEY_K,
|
||||
0x25: GHOSTTY_KEY_L,
|
||||
0x2E: GHOSTTY_KEY_M,
|
||||
0x2D: GHOSTTY_KEY_N,
|
||||
0x1F: GHOSTTY_KEY_O,
|
||||
0x23: GHOSTTY_KEY_P,
|
||||
0x0C: GHOSTTY_KEY_Q,
|
||||
0x0F: GHOSTTY_KEY_R,
|
||||
0x01: GHOSTTY_KEY_S,
|
||||
0x11: GHOSTTY_KEY_T,
|
||||
0x20: GHOSTTY_KEY_U,
|
||||
0x09: GHOSTTY_KEY_V,
|
||||
0x0D: GHOSTTY_KEY_W,
|
||||
0x07: GHOSTTY_KEY_X,
|
||||
0x10: GHOSTTY_KEY_Y,
|
||||
0x06: GHOSTTY_KEY_Z,
|
||||
|
||||
0x27: GHOSTTY_KEY_APOSTROPHE,
|
||||
0x2A: GHOSTTY_KEY_BACKSLASH,
|
||||
0x2B: GHOSTTY_KEY_COMMA,
|
||||
0x18: GHOSTTY_KEY_EQUAL,
|
||||
0x32: GHOSTTY_KEY_GRAVE_ACCENT,
|
||||
0x21: GHOSTTY_KEY_LEFT_BRACKET,
|
||||
0x1B: GHOSTTY_KEY_MINUS,
|
||||
0x2F: GHOSTTY_KEY_PERIOD,
|
||||
0x1E: GHOSTTY_KEY_RIGHT_BRACKET,
|
||||
0x29: GHOSTTY_KEY_SEMICOLON,
|
||||
0x2C: GHOSTTY_KEY_SLASH,
|
||||
|
||||
0x33: GHOSTTY_KEY_BACKSPACE,
|
||||
0x39: GHOSTTY_KEY_CAPS_LOCK,
|
||||
0x75: GHOSTTY_KEY_DELETE,
|
||||
0x7D: GHOSTTY_KEY_DOWN,
|
||||
0x77: GHOSTTY_KEY_END,
|
||||
0x24: GHOSTTY_KEY_ENTER,
|
||||
0x35: GHOSTTY_KEY_ESCAPE,
|
||||
0x7A: GHOSTTY_KEY_F1,
|
||||
0x78: GHOSTTY_KEY_F2,
|
||||
0x63: GHOSTTY_KEY_F3,
|
||||
0x76: GHOSTTY_KEY_F4,
|
||||
0x60: GHOSTTY_KEY_F5,
|
||||
0x61: GHOSTTY_KEY_F6,
|
||||
0x62: GHOSTTY_KEY_F7,
|
||||
0x64: GHOSTTY_KEY_F8,
|
||||
0x65: GHOSTTY_KEY_F9,
|
||||
0x6D: GHOSTTY_KEY_F10,
|
||||
0x67: GHOSTTY_KEY_F11,
|
||||
0x6F: GHOSTTY_KEY_F12,
|
||||
0x69: GHOSTTY_KEY_PRINT_SCREEN,
|
||||
0x6B: GHOSTTY_KEY_F14,
|
||||
0x71: GHOSTTY_KEY_F15,
|
||||
0x6A: GHOSTTY_KEY_F16,
|
||||
0x40: GHOSTTY_KEY_F17,
|
||||
0x4F: GHOSTTY_KEY_F18,
|
||||
0x50: GHOSTTY_KEY_F19,
|
||||
0x5A: GHOSTTY_KEY_F20,
|
||||
0x73: GHOSTTY_KEY_HOME,
|
||||
0x72: GHOSTTY_KEY_INSERT,
|
||||
0x7B: GHOSTTY_KEY_LEFT,
|
||||
0x3A: GHOSTTY_KEY_LEFT_ALT,
|
||||
0x3B: GHOSTTY_KEY_LEFT_CONTROL,
|
||||
0x38: GHOSTTY_KEY_LEFT_SHIFT,
|
||||
0x37: GHOSTTY_KEY_LEFT_SUPER,
|
||||
0x47: GHOSTTY_KEY_NUM_LOCK,
|
||||
0x79: GHOSTTY_KEY_PAGE_DOWN,
|
||||
0x74: GHOSTTY_KEY_PAGE_UP,
|
||||
0x7C: GHOSTTY_KEY_RIGHT,
|
||||
0x3D: GHOSTTY_KEY_RIGHT_ALT,
|
||||
0x3E: GHOSTTY_KEY_RIGHT_CONTROL,
|
||||
0x3C: GHOSTTY_KEY_RIGHT_SHIFT,
|
||||
0x36: GHOSTTY_KEY_RIGHT_SUPER,
|
||||
0x31: GHOSTTY_KEY_SPACE,
|
||||
0x30: GHOSTTY_KEY_TAB,
|
||||
0x7E: GHOSTTY_KEY_UP,
|
||||
|
||||
0x52: GHOSTTY_KEY_KP_0,
|
||||
0x53: GHOSTTY_KEY_KP_1,
|
||||
0x54: GHOSTTY_KEY_KP_2,
|
||||
0x55: GHOSTTY_KEY_KP_3,
|
||||
0x56: GHOSTTY_KEY_KP_4,
|
||||
0x57: GHOSTTY_KEY_KP_5,
|
||||
0x58: GHOSTTY_KEY_KP_6,
|
||||
0x59: GHOSTTY_KEY_KP_7,
|
||||
0x5B: GHOSTTY_KEY_KP_8,
|
||||
0x5C: GHOSTTY_KEY_KP_9,
|
||||
0x45: GHOSTTY_KEY_KP_ADD,
|
||||
0x41: GHOSTTY_KEY_KP_DECIMAL,
|
||||
0x4B: GHOSTTY_KEY_KP_DIVIDE,
|
||||
0x4C: GHOSTTY_KEY_KP_ENTER,
|
||||
0x51: GHOSTTY_KEY_KP_EQUAL,
|
||||
0x43: GHOSTTY_KEY_KP_MULTIPLY,
|
||||
0x4E: GHOSTTY_KEY_KP_SUBTRACT,
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -260,16 +260,7 @@ extension Ghostty {
|
||||
override func keyDown(with event: NSEvent) {
|
||||
let action = event.isARepeat ? GHOSTTY_ACTION_REPEAT : GHOSTTY_ACTION_PRESS
|
||||
keyAction(action, event: event)
|
||||
|
||||
// We specifically DO NOT call interpretKeyEvents because ghostty_surface_key
|
||||
// automatically handles all key translation, and we don't handle any commands
|
||||
// currently.
|
||||
//
|
||||
// It is possible that in the future we'll have to modify ghostty_surface_key
|
||||
// and the embedding API so that we can call this because macOS needs to do
|
||||
// some things with certain keys. I'm not sure. For now this works.
|
||||
//
|
||||
// self.interpretKeyEvents([event])
|
||||
self.interpretKeyEvents([event])
|
||||
}
|
||||
|
||||
override func keyUp(with event: NSEvent) {
|
||||
@ -300,8 +291,9 @@ extension Ghostty {
|
||||
|
||||
private func keyAction(_ action: ghostty_input_action_e, event: NSEvent) {
|
||||
guard let inspector = self.inspector else { return }
|
||||
guard let key = Ghostty.keycodeToKey[event.keyCode] else { return }
|
||||
let mods = Ghostty.ghosttyMods(event.modifierFlags)
|
||||
ghostty_inspector_key(inspector, action, UInt32(event.keyCode), mods)
|
||||
ghostty_inspector_key(inspector, action, key, mods)
|
||||
}
|
||||
|
||||
// MARK: NSTextInputClient
|
||||
|
@ -865,123 +865,6 @@ extension Ghostty {
|
||||
|
||||
print("SEL: \(selector)")
|
||||
}
|
||||
|
||||
// Mapping of event keyCode to ghostty input key values. This is cribbed from
|
||||
// glfw mostly since we started as a glfw-based app way back in the day!
|
||||
static let keycodes: [UInt16 : ghostty_input_key_e] = [
|
||||
0x1D: GHOSTTY_KEY_ZERO,
|
||||
0x12: GHOSTTY_KEY_ONE,
|
||||
0x13: GHOSTTY_KEY_TWO,
|
||||
0x14: GHOSTTY_KEY_THREE,
|
||||
0x15: GHOSTTY_KEY_FOUR,
|
||||
0x17: GHOSTTY_KEY_FIVE,
|
||||
0x16: GHOSTTY_KEY_SIX,
|
||||
0x1A: GHOSTTY_KEY_SEVEN,
|
||||
0x1C: GHOSTTY_KEY_EIGHT,
|
||||
0x19: GHOSTTY_KEY_NINE,
|
||||
0x00: GHOSTTY_KEY_A,
|
||||
0x0B: GHOSTTY_KEY_B,
|
||||
0x08: GHOSTTY_KEY_C,
|
||||
0x02: GHOSTTY_KEY_D,
|
||||
0x0E: GHOSTTY_KEY_E,
|
||||
0x03: GHOSTTY_KEY_F,
|
||||
0x05: GHOSTTY_KEY_G,
|
||||
0x04: GHOSTTY_KEY_H,
|
||||
0x22: GHOSTTY_KEY_I,
|
||||
0x26: GHOSTTY_KEY_J,
|
||||
0x28: GHOSTTY_KEY_K,
|
||||
0x25: GHOSTTY_KEY_L,
|
||||
0x2E: GHOSTTY_KEY_M,
|
||||
0x2D: GHOSTTY_KEY_N,
|
||||
0x1F: GHOSTTY_KEY_O,
|
||||
0x23: GHOSTTY_KEY_P,
|
||||
0x0C: GHOSTTY_KEY_Q,
|
||||
0x0F: GHOSTTY_KEY_R,
|
||||
0x01: GHOSTTY_KEY_S,
|
||||
0x11: GHOSTTY_KEY_T,
|
||||
0x20: GHOSTTY_KEY_U,
|
||||
0x09: GHOSTTY_KEY_V,
|
||||
0x0D: GHOSTTY_KEY_W,
|
||||
0x07: GHOSTTY_KEY_X,
|
||||
0x10: GHOSTTY_KEY_Y,
|
||||
0x06: GHOSTTY_KEY_Z,
|
||||
|
||||
0x27: GHOSTTY_KEY_APOSTROPHE,
|
||||
0x2A: GHOSTTY_KEY_BACKSLASH,
|
||||
0x2B: GHOSTTY_KEY_COMMA,
|
||||
0x18: GHOSTTY_KEY_EQUAL,
|
||||
0x32: GHOSTTY_KEY_GRAVE_ACCENT,
|
||||
0x21: GHOSTTY_KEY_LEFT_BRACKET,
|
||||
0x1B: GHOSTTY_KEY_MINUS,
|
||||
0x2F: GHOSTTY_KEY_PERIOD,
|
||||
0x1E: GHOSTTY_KEY_RIGHT_BRACKET,
|
||||
0x29: GHOSTTY_KEY_SEMICOLON,
|
||||
0x2C: GHOSTTY_KEY_SLASH,
|
||||
|
||||
0x33: GHOSTTY_KEY_BACKSPACE,
|
||||
0x39: GHOSTTY_KEY_CAPS_LOCK,
|
||||
0x75: GHOSTTY_KEY_DELETE,
|
||||
0x7D: GHOSTTY_KEY_DOWN,
|
||||
0x77: GHOSTTY_KEY_END,
|
||||
0x24: GHOSTTY_KEY_ENTER,
|
||||
0x35: GHOSTTY_KEY_ESCAPE,
|
||||
0x7A: GHOSTTY_KEY_F1,
|
||||
0x78: GHOSTTY_KEY_F2,
|
||||
0x63: GHOSTTY_KEY_F3,
|
||||
0x76: GHOSTTY_KEY_F4,
|
||||
0x60: GHOSTTY_KEY_F5,
|
||||
0x61: GHOSTTY_KEY_F6,
|
||||
0x62: GHOSTTY_KEY_F7,
|
||||
0x64: GHOSTTY_KEY_F8,
|
||||
0x65: GHOSTTY_KEY_F9,
|
||||
0x6D: GHOSTTY_KEY_F10,
|
||||
0x67: GHOSTTY_KEY_F11,
|
||||
0x6F: GHOSTTY_KEY_F12,
|
||||
0x69: GHOSTTY_KEY_PRINT_SCREEN,
|
||||
0x6B: GHOSTTY_KEY_F14,
|
||||
0x71: GHOSTTY_KEY_F15,
|
||||
0x6A: GHOSTTY_KEY_F16,
|
||||
0x40: GHOSTTY_KEY_F17,
|
||||
0x4F: GHOSTTY_KEY_F18,
|
||||
0x50: GHOSTTY_KEY_F19,
|
||||
0x5A: GHOSTTY_KEY_F20,
|
||||
0x73: GHOSTTY_KEY_HOME,
|
||||
0x72: GHOSTTY_KEY_INSERT,
|
||||
0x7B: GHOSTTY_KEY_LEFT,
|
||||
0x3A: GHOSTTY_KEY_LEFT_ALT,
|
||||
0x3B: GHOSTTY_KEY_LEFT_CONTROL,
|
||||
0x38: GHOSTTY_KEY_LEFT_SHIFT,
|
||||
0x37: GHOSTTY_KEY_LEFT_SUPER,
|
||||
0x47: GHOSTTY_KEY_NUM_LOCK,
|
||||
0x79: GHOSTTY_KEY_PAGE_DOWN,
|
||||
0x74: GHOSTTY_KEY_PAGE_UP,
|
||||
0x7C: GHOSTTY_KEY_RIGHT,
|
||||
0x3D: GHOSTTY_KEY_RIGHT_ALT,
|
||||
0x3E: GHOSTTY_KEY_RIGHT_CONTROL,
|
||||
0x3C: GHOSTTY_KEY_RIGHT_SHIFT,
|
||||
0x36: GHOSTTY_KEY_RIGHT_SUPER,
|
||||
0x31: GHOSTTY_KEY_SPACE,
|
||||
0x30: GHOSTTY_KEY_TAB,
|
||||
0x7E: GHOSTTY_KEY_UP,
|
||||
|
||||
0x52: GHOSTTY_KEY_KP_0,
|
||||
0x53: GHOSTTY_KEY_KP_1,
|
||||
0x54: GHOSTTY_KEY_KP_2,
|
||||
0x55: GHOSTTY_KEY_KP_3,
|
||||
0x56: GHOSTTY_KEY_KP_4,
|
||||
0x57: GHOSTTY_KEY_KP_5,
|
||||
0x58: GHOSTTY_KEY_KP_6,
|
||||
0x59: GHOSTTY_KEY_KP_7,
|
||||
0x5B: GHOSTTY_KEY_KP_8,
|
||||
0x5C: GHOSTTY_KEY_KP_9,
|
||||
0x45: GHOSTTY_KEY_KP_ADD,
|
||||
0x41: GHOSTTY_KEY_KP_DECIMAL,
|
||||
0x4B: GHOSTTY_KEY_KP_DIVIDE,
|
||||
0x4C: GHOSTTY_KEY_KP_ENTER,
|
||||
0x51: GHOSTTY_KEY_KP_EQUAL,
|
||||
0x43: GHOSTTY_KEY_KP_MULTIPLY,
|
||||
0x4E: GHOSTTY_KEY_KP_SUBTRACT,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1010,65 +1010,9 @@ pub const Inspector = struct {
|
||||
pub fn keyCallback(
|
||||
self: *Inspector,
|
||||
action: input.Action,
|
||||
keycode: u32,
|
||||
key: input.Key,
|
||||
mods: input.Mods,
|
||||
) !void {
|
||||
// True if this is a key down event
|
||||
const is_down = action == .press or action == .repeat;
|
||||
|
||||
// Translate our key using the keymap for our localized keyboard layout.
|
||||
// We only translate for keydown events. Otherwise, we only care about
|
||||
// the raw keycode.
|
||||
var buf: [128]u8 = undefined;
|
||||
const result: input.Keymap.Translation = if (is_down) translate: {
|
||||
const result = try self.surface.app.keymap.translate(
|
||||
&buf,
|
||||
&self.keymap_state,
|
||||
@intCast(keycode),
|
||||
mods,
|
||||
);
|
||||
|
||||
// If this is a dead key, then we're composing a character and
|
||||
// we don't do anything.
|
||||
if (result.composing) return;
|
||||
|
||||
// If the text is just a single non-printable ASCII character
|
||||
// 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 result;
|
||||
} else .{ .composing = false, .text = "" };
|
||||
|
||||
// We want to get the physical unmapped key to process keybinds.
|
||||
const physical_key = keycode: for (input.keycodes.entries) |entry| {
|
||||
if (entry.native == keycode) break :keycode entry.key;
|
||||
} else .invalid;
|
||||
|
||||
// If the resulting text has length 1 then we can take its key
|
||||
// and attempt to translate it to a key enum and call the key callback.
|
||||
// If the length is greater than 1 then we're going to call the
|
||||
// charCallback.
|
||||
//
|
||||
// We also only do key translation if this is not a dead key.
|
||||
const key = if (!result.composing) key: {
|
||||
// If our physical key is a keypad key, we use that.
|
||||
if (physical_key.keypad()) break :key physical_key;
|
||||
|
||||
// A completed key. If the length of the key is one then we can
|
||||
// attempt to translate it to a key enum and call the key
|
||||
// callback. First try plain ASCII.
|
||||
if (result.text.len > 0) {
|
||||
if (input.Key.fromASCII(result.text[0])) |key| {
|
||||
break :key key;
|
||||
}
|
||||
}
|
||||
|
||||
break :key physical_key;
|
||||
} else .invalid;
|
||||
|
||||
self.queueRender();
|
||||
cimgui.c.igSetCurrentContext(self.ig_ctx);
|
||||
const io: *cimgui.c.ImGuiIO = cimgui.c.igGetIO();
|
||||
@ -1087,19 +1031,6 @@ pub const Inspector = struct {
|
||||
action == .press or action == .repeat,
|
||||
);
|
||||
}
|
||||
|
||||
// Send any text
|
||||
if (result.text.len > 0) text: {
|
||||
const view = std.unicode.Utf8View.init(result.text) catch |err| {
|
||||
log.warn("cannot build utf8 view over input: {}", .{err});
|
||||
break :text;
|
||||
};
|
||||
var it = view.iterator();
|
||||
|
||||
while (it.nextCodepoint()) |cp| {
|
||||
cimgui.c.ImGuiIO_AddInputCharacter(io, cp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn newFrame(self: *Inspector) !void {
|
||||
@ -1462,12 +1393,12 @@ pub const CAPI = struct {
|
||||
export fn ghostty_inspector_key(
|
||||
ptr: *Inspector,
|
||||
action: input.Action,
|
||||
keycode: u32,
|
||||
key: input.Key,
|
||||
c_mods: c_int,
|
||||
) void {
|
||||
ptr.keyCallback(
|
||||
action,
|
||||
keycode,
|
||||
key,
|
||||
@bitCast(@as(
|
||||
input.Mods.Backing,
|
||||
@truncate(@as(c_uint, @bitCast(c_mods))),
|
||||
|
Reference in New Issue
Block a user