mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 08:46:08 +03:00
apprt: key/charCallback, input supports all glfw keys
This commit is contained in:
214
src/Window.zig
214
src/Window.zig
@ -394,8 +394,6 @@ pub fn create(alloc: Allocator, app: *App, config: *const Config) !*Window {
|
||||
// }, .{ .width = null, .height = null });
|
||||
|
||||
// Setup our callbacks and user data
|
||||
winsys.window.setCharCallback(charCallback);
|
||||
winsys.window.setKeyCallback(keyCallback);
|
||||
winsys.window.setFocusCallback(focusCallback);
|
||||
winsys.window.setRefreshCallback(refreshCallback);
|
||||
winsys.window.setScrollCallback(scrollCallback);
|
||||
@ -720,51 +718,46 @@ pub fn sizeCallback(self: *Window, size: apprt.WindowSize) !void {
|
||||
try self.io_thread.wakeup.send();
|
||||
}
|
||||
|
||||
fn charCallback(window: glfw.Window, codepoint: u21) void {
|
||||
pub fn charCallback(self: *Window, codepoint: u21) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const win = window.getUserPointer(Window) orelse return;
|
||||
|
||||
// Dev Mode
|
||||
if (DevMode.enabled and DevMode.instance.visible) {
|
||||
// If the event was handled by imgui, ignore it.
|
||||
if (imgui.IO.get()) |io| {
|
||||
if (io.cval().WantCaptureKeyboard) {
|
||||
win.queueRender() catch |err|
|
||||
log.err("error scheduling render timer err={}", .{err});
|
||||
try self.queueRender();
|
||||
}
|
||||
} else |_| {}
|
||||
}
|
||||
|
||||
// Ignore if requested. See field docs for more information.
|
||||
if (win.ignore_char) {
|
||||
win.ignore_char = false;
|
||||
if (self.ignore_char) {
|
||||
self.ignore_char = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Critical area
|
||||
{
|
||||
win.renderer_state.mutex.lock();
|
||||
defer win.renderer_state.mutex.unlock();
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
|
||||
// Clear the selction if we have one.
|
||||
if (win.io.terminal.selection != null) {
|
||||
win.io.terminal.selection = null;
|
||||
win.queueRender() catch |err|
|
||||
log.err("error scheduling render in charCallback err={}", .{err});
|
||||
if (self.io.terminal.selection != null) {
|
||||
self.io.terminal.selection = null;
|
||||
try self.queueRender();
|
||||
}
|
||||
|
||||
// We want to scroll to the bottom
|
||||
// TODO: detect if we're at the bottom to avoid the render call here.
|
||||
win.io.terminal.scrollViewport(.{ .bottom = {} }) catch |err|
|
||||
log.err("error scrolling viewport err={}", .{err});
|
||||
try self.io.terminal.scrollViewport(.{ .bottom = {} });
|
||||
}
|
||||
|
||||
// Ask our IO thread to write the data
|
||||
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||
data[0] = @intCast(u8, codepoint);
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_small = .{
|
||||
.data = data,
|
||||
.len = 1,
|
||||
@ -772,38 +765,31 @@ fn charCallback(window: glfw.Window, codepoint: u21) void {
|
||||
}, .{ .forever = {} });
|
||||
|
||||
// After sending all our messages we have to notify our IO thread
|
||||
win.io_thread.wakeup.send() catch {};
|
||||
try self.io_thread.wakeup.send();
|
||||
}
|
||||
|
||||
fn keyCallback(
|
||||
window: glfw.Window,
|
||||
key: glfw.Key,
|
||||
scancode: i32,
|
||||
action: glfw.Action,
|
||||
mods: glfw.Mods,
|
||||
) void {
|
||||
pub fn keyCallback(
|
||||
self: *Window,
|
||||
action: input.Action,
|
||||
key: input.Key,
|
||||
mods: input.Mods,
|
||||
) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const win = window.getUserPointer(Window) orelse return;
|
||||
|
||||
// Dev Mode
|
||||
if (DevMode.enabled and DevMode.instance.visible) {
|
||||
// If the event was handled by imgui, ignore it.
|
||||
if (imgui.IO.get()) |io| {
|
||||
if (io.cval().WantCaptureKeyboard) {
|
||||
win.queueRender() catch |err|
|
||||
log.err("error scheduling render timer err={}", .{err});
|
||||
try self.queueRender();
|
||||
}
|
||||
} else |_| {}
|
||||
}
|
||||
|
||||
// Reset the ignore char setting. If we didn't handle the char
|
||||
// by here, we aren't going to get it so we just reset this.
|
||||
win.ignore_char = false;
|
||||
|
||||
//log.info("KEY {} {} {} {}", .{ key, scancode, mods, action });
|
||||
_ = scancode;
|
||||
self.ignore_char = false;
|
||||
|
||||
if (action == .press or action == .repeat) {
|
||||
// Convert our glfw input into a platform agnostic trigger. When we
|
||||
@ -811,74 +797,12 @@ fn keyCallback(
|
||||
// into a function. For now, this is the only place we do it so we just
|
||||
// put it right here.
|
||||
const trigger: input.Binding.Trigger = .{
|
||||
.mods = @bitCast(input.Mods, mods),
|
||||
.key = switch (key) {
|
||||
.a => .a,
|
||||
.b => .b,
|
||||
.c => .c,
|
||||
.d => .d,
|
||||
.e => .e,
|
||||
.f => .f,
|
||||
.g => .g,
|
||||
.h => .h,
|
||||
.i => .i,
|
||||
.j => .j,
|
||||
.k => .k,
|
||||
.l => .l,
|
||||
.m => .m,
|
||||
.n => .n,
|
||||
.o => .o,
|
||||
.p => .p,
|
||||
.q => .q,
|
||||
.r => .r,
|
||||
.s => .s,
|
||||
.t => .t,
|
||||
.u => .u,
|
||||
.v => .v,
|
||||
.w => .w,
|
||||
.x => .x,
|
||||
.y => .y,
|
||||
.z => .z,
|
||||
.zero => .zero,
|
||||
.one => .one,
|
||||
.two => .three,
|
||||
.three => .four,
|
||||
.four => .four,
|
||||
.five => .five,
|
||||
.six => .six,
|
||||
.seven => .seven,
|
||||
.eight => .eight,
|
||||
.nine => .nine,
|
||||
.up => .up,
|
||||
.down => .down,
|
||||
.right => .right,
|
||||
.left => .left,
|
||||
.home => .home,
|
||||
.end => .end,
|
||||
.page_up => .page_up,
|
||||
.page_down => .page_down,
|
||||
.escape => .escape,
|
||||
.F1 => .f1,
|
||||
.F2 => .f2,
|
||||
.F3 => .f3,
|
||||
.F4 => .f4,
|
||||
.F5 => .f5,
|
||||
.F6 => .f6,
|
||||
.F7 => .f7,
|
||||
.F8 => .f8,
|
||||
.F9 => .f9,
|
||||
.F10 => .f10,
|
||||
.F11 => .f11,
|
||||
.F12 => .f12,
|
||||
.grave_accent => .grave_accent,
|
||||
.minus => .minus,
|
||||
.equal => .equal,
|
||||
else => .invalid,
|
||||
},
|
||||
.mods = mods,
|
||||
.key = key,
|
||||
};
|
||||
|
||||
//log.warn("BINDING TRIGGER={}", .{trigger});
|
||||
if (win.config.keybind.set.get(trigger)) |binding_action| {
|
||||
if (self.config.keybind.set.get(trigger)) |binding_action| {
|
||||
//log.warn("BINDING ACTION={}", .{binding_action});
|
||||
|
||||
switch (binding_action) {
|
||||
@ -886,13 +810,13 @@ fn keyCallback(
|
||||
.ignore => {},
|
||||
|
||||
.csi => |data| {
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_stable = "\x1B[",
|
||||
}, .{ .forever = {} });
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_stable = data,
|
||||
}, .{ .forever = {} });
|
||||
win.io_thread.wakeup.send() catch {};
|
||||
try self.io_thread.wakeup.send();
|
||||
},
|
||||
|
||||
.cursor_key => |ck| {
|
||||
@ -900,37 +824,37 @@ fn keyCallback(
|
||||
// in cursor keys mode. We're in "normal" mode if cursor
|
||||
// keys mdoe is NOT set.
|
||||
const normal = normal: {
|
||||
win.renderer_state.mutex.lock();
|
||||
defer win.renderer_state.mutex.unlock();
|
||||
break :normal !win.io.terminal.modes.cursor_keys;
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
break :normal !self.io.terminal.modes.cursor_keys;
|
||||
};
|
||||
|
||||
if (normal) {
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_stable = ck.normal,
|
||||
}, .{ .forever = {} });
|
||||
} else {
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_stable = ck.application,
|
||||
}, .{ .forever = {} });
|
||||
}
|
||||
|
||||
win.io_thread.wakeup.send() catch {};
|
||||
try self.io_thread.wakeup.send();
|
||||
},
|
||||
|
||||
.copy_to_clipboard => {
|
||||
// We can read from the renderer state without holding
|
||||
// the lock because only we will write to this field.
|
||||
if (win.io.terminal.selection) |sel| {
|
||||
var buf = win.io.terminal.screen.selectionString(
|
||||
win.alloc,
|
||||
if (self.io.terminal.selection) |sel| {
|
||||
var buf = self.io.terminal.screen.selectionString(
|
||||
self.alloc,
|
||||
sel,
|
||||
win.config.@"clipboard-trim-trailing-spaces",
|
||||
self.config.@"clipboard-trim-trailing-spaces",
|
||||
) catch |err| {
|
||||
log.err("error reading selection string err={}", .{err});
|
||||
return;
|
||||
};
|
||||
defer win.alloc.free(buf);
|
||||
defer self.alloc.free(buf);
|
||||
|
||||
glfw.setClipboardString(buf) catch |err| {
|
||||
log.err("error setting clipboard string err={}", .{err});
|
||||
@ -947,99 +871,99 @@ fn keyCallback(
|
||||
|
||||
if (data.len > 0) {
|
||||
const bracketed = bracketed: {
|
||||
win.renderer_state.mutex.lock();
|
||||
defer win.renderer_state.mutex.unlock();
|
||||
break :bracketed win.io.terminal.modes.bracketed_paste;
|
||||
self.renderer_state.mutex.lock();
|
||||
defer self.renderer_state.mutex.unlock();
|
||||
break :bracketed self.io.terminal.modes.bracketed_paste;
|
||||
};
|
||||
|
||||
if (bracketed) {
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_stable = "\x1B[200~",
|
||||
}, .{ .forever = {} });
|
||||
}
|
||||
|
||||
_ = win.io_thread.mailbox.push(termio.Message.writeReq(
|
||||
win.alloc,
|
||||
_ = self.io_thread.mailbox.push(try termio.Message.writeReq(
|
||||
self.alloc,
|
||||
data,
|
||||
) catch unreachable, .{ .forever = {} });
|
||||
), .{ .forever = {} });
|
||||
|
||||
if (bracketed) {
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_stable = "\x1B[201~",
|
||||
}, .{ .forever = {} });
|
||||
}
|
||||
|
||||
win.io_thread.wakeup.send() catch {};
|
||||
try self.io_thread.wakeup.send();
|
||||
}
|
||||
},
|
||||
|
||||
.increase_font_size => |delta| {
|
||||
log.debug("increase font size={}", .{delta});
|
||||
|
||||
var size = win.font_size;
|
||||
var size = self.font_size;
|
||||
size.points +|= delta;
|
||||
win.setFontSize(size);
|
||||
self.setFontSize(size);
|
||||
},
|
||||
|
||||
.decrease_font_size => |delta| {
|
||||
log.debug("decrease font size={}", .{delta});
|
||||
|
||||
var size = win.font_size;
|
||||
var size = self.font_size;
|
||||
size.points = @max(1, size.points -| delta);
|
||||
win.setFontSize(size);
|
||||
self.setFontSize(size);
|
||||
},
|
||||
|
||||
.reset_font_size => {
|
||||
log.debug("reset font size", .{});
|
||||
|
||||
var size = win.font_size;
|
||||
size.points = win.config.@"font-size";
|
||||
win.setFontSize(size);
|
||||
var size = self.font_size;
|
||||
size.points = self.config.@"font-size";
|
||||
self.setFontSize(size);
|
||||
},
|
||||
|
||||
.toggle_dev_mode => if (DevMode.enabled) {
|
||||
DevMode.instance.visible = !DevMode.instance.visible;
|
||||
win.queueRender() catch unreachable;
|
||||
try self.queueRender();
|
||||
} else log.warn("dev mode was not compiled into this binary", .{}),
|
||||
|
||||
.new_window => {
|
||||
_ = win.app.mailbox.push(.{
|
||||
_ = self.app.mailbox.push(.{
|
||||
.new_window = .{
|
||||
.font_size = if (win.config.@"window-inherit-font-size")
|
||||
win.font_size
|
||||
.font_size = if (self.config.@"window-inherit-font-size")
|
||||
self.font_size
|
||||
else
|
||||
null,
|
||||
},
|
||||
}, .{ .instant = {} });
|
||||
win.app.wakeup();
|
||||
self.app.wakeup();
|
||||
},
|
||||
|
||||
.new_tab => {
|
||||
_ = win.app.mailbox.push(.{
|
||||
_ = self.app.mailbox.push(.{
|
||||
.new_tab = .{
|
||||
.parent = win,
|
||||
.parent = self,
|
||||
|
||||
.font_size = if (win.config.@"window-inherit-font-size")
|
||||
win.font_size
|
||||
.font_size = if (self.config.@"window-inherit-font-size")
|
||||
self.font_size
|
||||
else
|
||||
null,
|
||||
},
|
||||
}, .{ .instant = {} });
|
||||
win.app.wakeup();
|
||||
self.app.wakeup();
|
||||
},
|
||||
|
||||
.close_window => win.window.setShouldClose(true),
|
||||
.close_window => self.windowing_system.setShouldClose(),
|
||||
|
||||
.quit => {
|
||||
_ = win.app.mailbox.push(.{
|
||||
_ = self.app.mailbox.push(.{
|
||||
.quit = {},
|
||||
}, .{ .instant = {} });
|
||||
win.app.wakeup();
|
||||
self.app.wakeup();
|
||||
},
|
||||
}
|
||||
|
||||
// Bindings always result in us ignoring the char if printable
|
||||
win.ignore_char = true;
|
||||
self.ignore_char = true;
|
||||
|
||||
// No matter what, if there is a binding then we are done.
|
||||
return;
|
||||
@ -1099,7 +1023,7 @@ fn keyCallback(
|
||||
// Ask our IO thread to write the data
|
||||
var data: termio.Message.WriteReq.Small.Array = undefined;
|
||||
data[0] = @intCast(u8, char);
|
||||
_ = win.io_thread.mailbox.push(.{
|
||||
_ = self.io_thread.mailbox.push(.{
|
||||
.write_small = .{
|
||||
.data = data,
|
||||
.len = 1,
|
||||
@ -1107,7 +1031,7 @@ fn keyCallback(
|
||||
}, .{ .forever = {} });
|
||||
|
||||
// After sending all our messages we have to notify our IO thread
|
||||
win.io_thread.wakeup.send() catch {};
|
||||
try self.io_thread.wakeup.send();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,9 +7,11 @@ const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const trace = @import("tracy").trace;
|
||||
const glfw = @import("glfw");
|
||||
const objc = @import("objc");
|
||||
const App = @import("../App.zig");
|
||||
const input = @import("../input.zig");
|
||||
const internal_os = @import("../os/main.zig");
|
||||
const renderer = @import("../renderer.zig");
|
||||
const Renderer = renderer.Renderer;
|
||||
@ -85,6 +87,8 @@ pub const Window = struct {
|
||||
// Set our callbacks
|
||||
win.setUserPointer(core_win);
|
||||
win.setSizeCallback(sizeCallback);
|
||||
win.setCharCallback(charCallback);
|
||||
win.setKeyCallback(keyCallback);
|
||||
|
||||
// Build our result
|
||||
return Window{
|
||||
@ -158,6 +162,12 @@ pub const Window = struct {
|
||||
return apprt.WindowSize{ .width = size.width, .height = size.height };
|
||||
}
|
||||
|
||||
/// Set the flag that notes this window should be closed for the next
|
||||
/// iteration of the event loop.
|
||||
pub fn setShouldClose(self: *Window) void {
|
||||
self.window.setShouldClose(true);
|
||||
}
|
||||
|
||||
fn sizeCallback(window: glfw.Window, width: i32, height: i32) void {
|
||||
_ = width;
|
||||
_ = height;
|
||||
@ -177,4 +187,167 @@ pub const Window = struct {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
fn charCallback(window: glfw.Window, codepoint: u21) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const core_win = window.getUserPointer(CoreWindow) orelse return;
|
||||
core_win.charCallback(codepoint) catch |err| {
|
||||
log.err("error in char callback err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
fn keyCallback(
|
||||
window: glfw.Window,
|
||||
glfw_key: glfw.Key,
|
||||
scancode: i32,
|
||||
glfw_action: glfw.Action,
|
||||
glfw_mods: glfw.Mods,
|
||||
) void {
|
||||
_ = scancode;
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
// Convert our glfw types into our input types
|
||||
const mods = @bitCast(input.Mods, glfw_mods);
|
||||
const action: input.Action = switch (glfw_action) {
|
||||
.release => .release,
|
||||
.press => .press,
|
||||
.repeat => .repeat,
|
||||
};
|
||||
const key: input.Key = switch (glfw_key) {
|
||||
.a => .a,
|
||||
.b => .b,
|
||||
.c => .c,
|
||||
.d => .d,
|
||||
.e => .e,
|
||||
.f => .f,
|
||||
.g => .g,
|
||||
.h => .h,
|
||||
.i => .i,
|
||||
.j => .j,
|
||||
.k => .k,
|
||||
.l => .l,
|
||||
.m => .m,
|
||||
.n => .n,
|
||||
.o => .o,
|
||||
.p => .p,
|
||||
.q => .q,
|
||||
.r => .r,
|
||||
.s => .s,
|
||||
.t => .t,
|
||||
.u => .u,
|
||||
.v => .v,
|
||||
.w => .w,
|
||||
.x => .x,
|
||||
.y => .y,
|
||||
.z => .z,
|
||||
.zero => .zero,
|
||||
.one => .one,
|
||||
.two => .three,
|
||||
.three => .four,
|
||||
.four => .four,
|
||||
.five => .five,
|
||||
.six => .six,
|
||||
.seven => .seven,
|
||||
.eight => .eight,
|
||||
.nine => .nine,
|
||||
.up => .up,
|
||||
.down => .down,
|
||||
.right => .right,
|
||||
.left => .left,
|
||||
.home => .home,
|
||||
.end => .end,
|
||||
.page_up => .page_up,
|
||||
.page_down => .page_down,
|
||||
.escape => .escape,
|
||||
.F1 => .f1,
|
||||
.F2 => .f2,
|
||||
.F3 => .f3,
|
||||
.F4 => .f4,
|
||||
.F5 => .f5,
|
||||
.F6 => .f6,
|
||||
.F7 => .f7,
|
||||
.F8 => .f8,
|
||||
.F9 => .f9,
|
||||
.F10 => .f10,
|
||||
.F11 => .f11,
|
||||
.F12 => .f12,
|
||||
.F13 => .f13,
|
||||
.F14 => .f14,
|
||||
.F15 => .f15,
|
||||
.F16 => .f16,
|
||||
.F17 => .f17,
|
||||
.F18 => .f18,
|
||||
.F19 => .f19,
|
||||
.F20 => .f20,
|
||||
.F21 => .f21,
|
||||
.F22 => .f22,
|
||||
.F23 => .f23,
|
||||
.F24 => .f24,
|
||||
.F25 => .f25,
|
||||
.kp_0 => .kp_0,
|
||||
.kp_1 => .kp_1,
|
||||
.kp_2 => .kp_2,
|
||||
.kp_3 => .kp_3,
|
||||
.kp_4 => .kp_4,
|
||||
.kp_5 => .kp_5,
|
||||
.kp_6 => .kp_6,
|
||||
.kp_7 => .kp_7,
|
||||
.kp_8 => .kp_8,
|
||||
.kp_9 => .kp_9,
|
||||
.kp_decimal => .kp_decimal,
|
||||
.kp_divide => .kp_divide,
|
||||
.kp_multiply => .kp_multiply,
|
||||
.kp_subtract => .kp_subtract,
|
||||
.kp_add => .kp_add,
|
||||
.kp_enter => .kp_enter,
|
||||
.kp_equal => .kp_equal,
|
||||
.grave_accent => .grave_accent,
|
||||
.minus => .minus,
|
||||
.equal => .equal,
|
||||
.space => .space,
|
||||
.semicolon => .semicolon,
|
||||
.apostrophe => .apostrophe,
|
||||
.comma => .comma,
|
||||
.period => .period,
|
||||
.slash => .slash,
|
||||
.left_bracket => .left_bracket,
|
||||
.right_bracket => .right_bracket,
|
||||
.backslash => .backslash,
|
||||
.enter => .enter,
|
||||
.tab => .tab,
|
||||
.backspace => .backspace,
|
||||
.insert => .insert,
|
||||
.delete => .delete,
|
||||
.caps_lock => .caps_lock,
|
||||
.scroll_lock => .scroll_lock,
|
||||
.num_lock => .num_lock,
|
||||
.print_screen => .print_screen,
|
||||
.pause => .pause,
|
||||
.left_shift => .left_shift,
|
||||
.left_control => .left_control,
|
||||
.left_alt => .left_alt,
|
||||
.left_super => .left_super,
|
||||
.right_shift => .right_shift,
|
||||
.right_control => .right_control,
|
||||
.right_alt => .right_alt,
|
||||
.right_super => .right_super,
|
||||
|
||||
.menu,
|
||||
.world_1,
|
||||
.world_2,
|
||||
.unknown,
|
||||
=> .invalid,
|
||||
};
|
||||
|
||||
const core_win = window.getUserPointer(CoreWindow) orelse return;
|
||||
core_win.keyCallback(action, key, mods) catch |err| {
|
||||
log.err("error in key callback err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -13,6 +13,13 @@ pub const Mods = packed struct {
|
||||
_padding: u2 = 0,
|
||||
};
|
||||
|
||||
/// The action associated with an input event.
|
||||
pub const Action = enum {
|
||||
release,
|
||||
press,
|
||||
repeat,
|
||||
};
|
||||
|
||||
/// The set of keys that can map to keybindings. These have no fixed enum
|
||||
/// values because we map platform-specific keys to this set. Note that
|
||||
/// this only needs to accomodate what maps to a key. If a key is not bound
|
||||
@ -61,10 +68,19 @@ pub const Key = enum {
|
||||
eight,
|
||||
nine,
|
||||
|
||||
// other
|
||||
// puncuation
|
||||
semicolon,
|
||||
space,
|
||||
apostrophe,
|
||||
comma,
|
||||
grave_accent, // `
|
||||
period,
|
||||
slash,
|
||||
minus,
|
||||
equal,
|
||||
left_bracket, // [
|
||||
right_bracket, // ]
|
||||
backslash, // /
|
||||
|
||||
// control
|
||||
up,
|
||||
@ -73,10 +89,21 @@ pub const Key = enum {
|
||||
left,
|
||||
home,
|
||||
end,
|
||||
insert,
|
||||
delete,
|
||||
caps_lock,
|
||||
scroll_lock,
|
||||
num_lock,
|
||||
page_up,
|
||||
page_down,
|
||||
escape,
|
||||
enter,
|
||||
tab,
|
||||
backspace,
|
||||
print_screen,
|
||||
pause,
|
||||
|
||||
// function keys
|
||||
f1,
|
||||
f2,
|
||||
f3,
|
||||
@ -89,6 +116,48 @@ pub const Key = enum {
|
||||
f10,
|
||||
f11,
|
||||
f12,
|
||||
f13,
|
||||
f14,
|
||||
f15,
|
||||
f16,
|
||||
f17,
|
||||
f18,
|
||||
f19,
|
||||
f20,
|
||||
f21,
|
||||
f22,
|
||||
f23,
|
||||
f24,
|
||||
f25,
|
||||
|
||||
// keypad
|
||||
kp_0,
|
||||
kp_1,
|
||||
kp_2,
|
||||
kp_3,
|
||||
kp_4,
|
||||
kp_5,
|
||||
kp_6,
|
||||
kp_7,
|
||||
kp_8,
|
||||
kp_9,
|
||||
kp_decimal,
|
||||
kp_divide,
|
||||
kp_multiply,
|
||||
kp_subtract,
|
||||
kp_add,
|
||||
kp_enter,
|
||||
kp_equal,
|
||||
|
||||
// modifiers
|
||||
left_shift,
|
||||
left_control,
|
||||
left_alt,
|
||||
left_super,
|
||||
right_shift,
|
||||
right_control,
|
||||
right_alt,
|
||||
right_super,
|
||||
|
||||
// To support more keys (there are obviously more!) add them here
|
||||
// and ensure the mapping is up to date in the Window key handler.
|
||||
|
Reference in New Issue
Block a user