mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-23 04:06:13 +03:00
look up keybindings on keypress, clean up how non-printables are handled
This commit is contained in:
136
src/Window.zig
136
src/Window.zig
@ -20,6 +20,7 @@ const trace = @import("tracy").trace;
|
|||||||
const max_timer = @import("max_timer.zig");
|
const max_timer = @import("max_timer.zig");
|
||||||
const terminal = @import("terminal/main.zig");
|
const terminal = @import("terminal/main.zig");
|
||||||
const Config = @import("config.zig").Config;
|
const Config = @import("config.zig").Config;
|
||||||
|
const input = @import("input.zig");
|
||||||
|
|
||||||
const RenderTimer = max_timer.MaxTimer(renderTimerCallback);
|
const RenderTimer = max_timer.MaxTimer(renderTimerCallback);
|
||||||
|
|
||||||
@ -486,15 +487,69 @@ fn keyCallback(
|
|||||||
const tracy = trace(@src());
|
const tracy = trace(@src());
|
||||||
defer tracy.end();
|
defer tracy.end();
|
||||||
|
|
||||||
|
const win = window.getUserPointer(Window) orelse return;
|
||||||
|
|
||||||
|
// 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 });
|
//log.info("KEY {} {} {} {}", .{ key, scancode, mods, action });
|
||||||
_ = scancode;
|
_ = scancode;
|
||||||
|
|
||||||
|
if (action == .press or action == .repeat) {
|
||||||
|
// Convert our glfw input into a platform agnostic trigger. When we
|
||||||
|
// extract the platform out of this file, we'll pull a lot of this out
|
||||||
|
// 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,
|
||||||
|
else => .invalid,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (win.config.keybind.set.get(trigger)) |binding_action| {
|
||||||
|
log.warn("BINDING ACTION={}", .{binding_action});
|
||||||
|
_ = binding_action;
|
||||||
|
|
||||||
|
// Bindings always result in us ignoring the char if printable
|
||||||
|
win.ignore_char = true;
|
||||||
|
|
||||||
|
// No matter what, if there is a binding then we are done.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (action == .press and mods.super) {
|
if (action == .press and mods.super) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
// Copy
|
// Copy
|
||||||
.c => {
|
.c => {
|
||||||
const win = window.getUserPointer(Window) orelse return;
|
|
||||||
|
|
||||||
// Ignore this character for writing
|
// Ignore this character for writing
|
||||||
win.ignore_char = true;
|
win.ignore_char = true;
|
||||||
|
|
||||||
@ -517,7 +572,6 @@ fn keyCallback(
|
|||||||
|
|
||||||
// Paste
|
// Paste
|
||||||
.v => {
|
.v => {
|
||||||
const win = window.getUserPointer(Window) orelse return;
|
|
||||||
|
|
||||||
// Ignore this character for writing
|
// Ignore this character for writing
|
||||||
win.ignore_char = true;
|
win.ignore_char = true;
|
||||||
@ -543,46 +597,52 @@ fn keyCallback(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == .press or action == .repeat) {
|
// Handle non-printable characters
|
||||||
const c: u8 = switch (key) {
|
const char: u8 = switch (@bitCast(u8, mods)) {
|
||||||
// Lots more of these:
|
// No modifiers pressed at all
|
||||||
// https://www.physics.udel.edu/~watson/scen103/ascii.html
|
0 => @as(u8, switch (key) {
|
||||||
.a => if (mods.control and !mods.shift) 0x01 else return,
|
|
||||||
.b => if (mods.control and !mods.shift) 0x02 else return,
|
|
||||||
.c => if (mods.control and !mods.shift) 0x03 else return,
|
|
||||||
.d => if (mods.control and !mods.shift) 0x04 else return,
|
|
||||||
.e => if (mods.control and !mods.shift) 0x05 else return,
|
|
||||||
.f => if (mods.control and !mods.shift) 0x06 else return,
|
|
||||||
.g => if (mods.control and !mods.shift) 0x07 else return,
|
|
||||||
.h => if (mods.control and !mods.shift) 0x08 else return,
|
|
||||||
.i => if (mods.control and !mods.shift) 0x09 else return,
|
|
||||||
.j => if (mods.control and !mods.shift) 0x0A else return,
|
|
||||||
.k => if (mods.control and !mods.shift) 0x0B else return,
|
|
||||||
.l => if (mods.control and !mods.shift) 0x0C else return,
|
|
||||||
.m => if (mods.control and !mods.shift) 0x0D else return,
|
|
||||||
.n => if (mods.control and !mods.shift) 0x0E else return,
|
|
||||||
.o => if (mods.control and !mods.shift) 0x0F else return,
|
|
||||||
.p => if (mods.control and !mods.shift) 0x10 else return,
|
|
||||||
.q => if (mods.control and !mods.shift) 0x11 else return,
|
|
||||||
.r => if (mods.control and !mods.shift) 0x12 else return,
|
|
||||||
.s => if (mods.control and !mods.shift) 0x13 else return,
|
|
||||||
.t => if (mods.control and !mods.shift) 0x14 else return,
|
|
||||||
.u => if (mods.control and !mods.shift) 0x15 else return,
|
|
||||||
.v => if (mods.control and !mods.shift) 0x16 else return,
|
|
||||||
.w => if (mods.control and !mods.shift) 0x17 else return,
|
|
||||||
.x => if (mods.control and !mods.shift) 0x18 else return,
|
|
||||||
.y => if (mods.control and !mods.shift) 0x19 else return,
|
|
||||||
.z => if (mods.control and !mods.shift) 0x1A else return,
|
|
||||||
|
|
||||||
.backspace => 0x08,
|
.backspace => 0x08,
|
||||||
.enter => '\r',
|
.enter => '\r',
|
||||||
.tab => '\t',
|
.tab => '\t',
|
||||||
.escape => 0x1B,
|
.escape => 0x1B,
|
||||||
else => return,
|
else => 0,
|
||||||
};
|
}),
|
||||||
|
|
||||||
const win = window.getUserPointer(Window) orelse return;
|
// Control only
|
||||||
win.queueWrite(&[1]u8{c}) catch |err|
|
@bitCast(u8, glfw.Mods{ .control = true }) => @as(u8, switch (key) {
|
||||||
|
.a => 0x01,
|
||||||
|
.b => 0x02,
|
||||||
|
.c => 0x03,
|
||||||
|
.d => 0x04,
|
||||||
|
.e => 0x05,
|
||||||
|
.f => 0x06,
|
||||||
|
.g => 0x07,
|
||||||
|
.h => 0x08,
|
||||||
|
.i => 0x09,
|
||||||
|
.j => 0x0A,
|
||||||
|
.k => 0x0B,
|
||||||
|
.l => 0x0C,
|
||||||
|
.m => 0x0D,
|
||||||
|
.n => 0x0E,
|
||||||
|
.o => 0x0F,
|
||||||
|
.p => 0x10,
|
||||||
|
.q => 0x11,
|
||||||
|
.r => 0x12,
|
||||||
|
.s => 0x13,
|
||||||
|
.t => 0x14,
|
||||||
|
.u => 0x15,
|
||||||
|
.v => 0x16,
|
||||||
|
.w => 0x17,
|
||||||
|
.x => 0x18,
|
||||||
|
.y => 0x19,
|
||||||
|
.z => 0x1A,
|
||||||
|
else => 0,
|
||||||
|
}),
|
||||||
|
|
||||||
|
else => 0,
|
||||||
|
};
|
||||||
|
if (char > 0) {
|
||||||
|
win.queueWrite(&[1]u8{char}) catch |err|
|
||||||
log.err("error queueing write in keyCallback err={}", .{err});
|
log.err("error queueing write in keyCallback err={}", .{err});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user