diff --git a/src/Configuration.zig b/src/Configuration.zig new file mode 100644 index 0000000..a6a7273 --- /dev/null +++ b/src/Configuration.zig @@ -0,0 +1,51 @@ +const Configuration = @This(); + +pub const Mods = struct { + ctrl: bool = false, + alt: bool = false, + shift: bool = false, + win: bool = false, +}; + +pub const Key = enum(u16) { + // zig fmt: off + @"0" = 0x30, @"1" = 0x31, @"2" = 0x32, @"3" = 0x33, @"4" = 0x34, + @"5" = 0x35, @"6" = 0x36, @"7" = 0x37, @"8" = 0x38, @"9" = 0x39, + + a = 0x41, b = 0x42, c = 0x43, d = 0x44, e = 0x45, f = 0x46, g = 0x47, + h = 0x48, i = 0x49, j = 0x4A, k = 0x4B, l = 0x4C, m = 0x4D, n = 0x4E, + o = 0x4F, p = 0x50, q = 0x51, r = 0x52, s = 0x53, t = 0x54, u = 0x55, + v = 0x56, w = 0x57, x = 0x58, y = 0x59, z = 0x5A, + + f1 = 0x70, f2 = 0x71, f3 = 0x72, f4 = 0x73, f5 = 0x74, f6 = 0x75, + f7 = 0x76, f8 = 0x77, f9 = 0x78, f10 = 0x79, f11 = 0x7A, f12 = 0x7B, + + backspace = 0x08, + tab = 0x09, + enter = 0x0D, + escape = 0x1B, + space = 0x20, + + left = 0x25, up = 0x26, right = 0x27, down = 0x28, + // zig fmt: on +}; + +pub const Action = union(enum) { + nothing, +}; + +pub const Keybind = struct { + mods: Mods = .{}, + key: Key, + action: Action, +}; + +keybinds: []const Keybind = &.{}, + +pub const default: Configuration = .{ + .keybinds = &.{ + // .{ .mods = .{ .alt = true, .shift = true }, .key = .q, .action = .quit_focused_window }, + // .{ .mods = .{ .alt = true }, .key = .enter, .action = .{ .spawn = &.{ "wt.exe", "nu" } } }, + .{ .mods = .{ .alt = true, .shift = true }, .key = .n, .action = .nothing }, + }, +}; diff --git a/src/KeyboardHook.zig b/src/KeyboardHook.zig index bd88063..cb4522a 100644 --- a/src/KeyboardHook.zig +++ b/src/KeyboardHook.zig @@ -38,14 +38,38 @@ fn keyboardProc( } const kb: *const win32.ui.windows_and_messaging.KBDLLHOOKSTRUCT = @ptrFromInt(@as(usize, @bitCast(lparam))); - if (kb.flags.ALTDOWN == 1) { - log.debug("key pressed (alt down): vkCode=0x{X}", .{kb.vkCode}); + const vk = kb.vkCode; + const mods: Configuration.Mods = .{ + .alt = kb.flags.ALTDOWN == 1, + .ctrl = isKeyDown(.CONTROL), + .shift = isKeyDown(.SHIFT), + .win = isKeyDown(.LWIN) or isKeyDown(.RWIN), + }; + + for (wm.config.keybinds) |keybind| { + if (std.meta.eql(keybind.mods, mods) and @intFromEnum(keybind.key) == vk) { + log.debug("keybind matched: {}", .{keybind.key}); + + switch (keybind.action) { + .nothing => {}, + } + + return 1; + } } return win32.ui.windows_and_messaging.CallNextHookEx(null, code, wparam, lparam); } +fn isKeyDown(vk: win32.ui.input.keyboard_and_mouse.VIRTUAL_KEY) bool { + const state = win32.ui.input.keyboard_and_mouse.GetAsyncKeyState(@intFromEnum(vk)); + return (@as(u16, @bitCast(state)) & 0x8000) != 0; +} + const log = std.log.scoped(.keyboard_hook); +const wm = &@import("main.zig").wm; +const Configuration = @import("Configuration.zig"); + const win32 = @import("win32"); const std = @import("std"); diff --git a/src/WindowManager.zig b/src/WindowManager.zig index a6e9cbc..685790a 100644 --- a/src/WindowManager.zig +++ b/src/WindowManager.zig @@ -6,6 +6,7 @@ allocator: std.mem.Allocator, window_hook: WindowHook, keyboard_hook: KeyboardHook, screens: std.ArrayList(Screen) = .empty, +config: Configuration = .default, pub fn init(allocator: std.mem.Allocator) !WindowManager { log.debug("getting the window manager ready", .{}); @@ -87,6 +88,7 @@ fn pumpMessages() void { const log = std.log.scoped(.window_manager); +const Configuration = @import("Configuration.zig"); const KeyboardHook = @import("KeyboardHook.zig"); const WindowHook = @import("WindowHook.zig");