From ba883ce39ae11237acf34065cf20474f4428ca6a Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 30 Aug 2023 22:14:44 -0700 Subject: [PATCH] add ghostty_config_trigger C API to find a trigger for an action --- include/ghostty.h | 7 +++++++ src/config.zig | 19 +++++++++++++++++++ src/input/Binding.zig | 21 ++++++++++++++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/include/ghostty.h b/include/ghostty.h index 98bd292da..856b260d8 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -230,6 +230,12 @@ typedef enum { GHOSTTY_KEY_RIGHT_SUPER, } ghostty_input_key_e; +typedef struct { + ghostty_input_key_e key; + ghostty_input_mods_e mods; + bool physical; +} ghostty_input_trigger_s; + // Fully defined types. This MUST be kept in sync with equivalent Zig // structs. To find the Zig struct, grep for this type name. The documentation // for all of these types is available in the Zig source. @@ -282,6 +288,7 @@ void ghostty_config_load_string(ghostty_config_t, const char *, uintptr_t); void ghostty_config_load_default_files(ghostty_config_t); void ghostty_config_load_recursive_files(ghostty_config_t); void ghostty_config_finalize(ghostty_config_t); +ghostty_input_trigger_s ghostty_config_trigger(ghostty_config_t, const char *, uintptr_t); ghostty_app_t ghostty_app_new(const ghostty_runtime_config_s *, ghostty_config_t); void ghostty_app_free(ghostty_app_t); diff --git a/src/config.zig b/src/config.zig index 891595aaf..fea085933 100644 --- a/src/config.zig +++ b/src/config.zig @@ -1559,6 +1559,25 @@ pub const CAPI = struct { log.err("error finalizing config err={}", .{err}); }; } + + export fn ghostty_config_trigger( + self: *Config, + str: [*]const u8, + len: usize, + ) inputpkg.Binding.Trigger { + return config_trigger_(self, str[0..len]) catch |err| err: { + log.err("error finding trigger err={}", .{err}); + break :err .{}; + }; + } + + fn config_trigger_( + self: *Config, + str: []const u8, + ) !inputpkg.Binding.Trigger { + const action = try inputpkg.Binding.Action.parse(str); + return self.keybind.set.getTrigger(action) orelse .{}; + } }; test { diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 5c89bde62..6cb198626 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -282,7 +282,10 @@ pub const Key = enum(c_int) { }; /// Trigger is the associated key state that can trigger an action. -pub const Trigger = struct { +/// This is an extern struct because this is also used in the C API. +/// +/// This must be kept in sync with include/ghostty.h ghostty_input_trigger_s +pub const Trigger = extern struct { /// The key that has to be pressed for a binding to take action. key: key.Key = .invalid, @@ -342,6 +345,22 @@ pub const Set = struct { return self.bindings.get(t); } + /// Get a trigger for the given action. An action can have multiple + /// triggers so this will return the first one found. + pub fn getTrigger(self: Set, a: Action) ?Trigger { + // Note: iterating over the full set each time is not ideal but + // we don't expect to have that many bindings. If this becomes + // a problem we can add a reverse map. + var it = self.bindings.iterator(); + while (it.next()) |entry| { + if (std.meta.eql(entry.value_ptr.*, a)) { + return entry.key_ptr.*; + } + } + + return null; + } + /// Remove a binding for a given trigger. pub fn remove(self: *Set, t: Trigger) void { _ = self.bindings.remove(t);