From 4d18c06804f1567c5b3efad60331c636f3eb4f28 Mon Sep 17 00:00:00 2001 From: Leah Amelia Chen Date: Fri, 30 May 2025 14:04:14 +0200 Subject: [PATCH] gtk(wayland): customize keyboard interactivity for quick terminal Fixes #7476 --- src/apprt/gtk/Window.zig | 2 ++ src/apprt/gtk/winproto/wayland.zig | 28 ++++++++++++++++-------- src/config/Config.zig | 35 ++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index aa1f0a4b1..d9d2da057 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -90,6 +90,7 @@ pub const DerivedConfig = struct { quick_terminal_position: configpkg.Config.QuickTerminalPosition, quick_terminal_size: configpkg.Config.QuickTerminalSize, quick_terminal_autohide: bool, + quick_terminal_keyboard_interactivity: configpkg.Config.QuickTerminalKeyboardInteractivity, maximize: bool, fullscreen: bool, @@ -109,6 +110,7 @@ pub const DerivedConfig = struct { .quick_terminal_position = config.@"quick-terminal-position", .quick_terminal_size = config.@"quick-terminal-size", .quick_terminal_autohide = config.@"quick-terminal-autohide", + .quick_terminal_keyboard_interactivity = config.@"quick-terminal-keyboard-interactivity", .maximize = config.maximize, .fullscreen = config.fullscreen, diff --git a/src/apprt/gtk/winproto/wayland.zig b/src/apprt/gtk/winproto/wayland.zig index 5f5feca6e..5a4f24ff7 100644 --- a/src/apprt/gtk/winproto/wayland.zig +++ b/src/apprt/gtk/winproto/wayland.zig @@ -110,7 +110,6 @@ pub const App = struct { gtk4_layer_shell.initForWindow(window); gtk4_layer_shell.setLayer(window, .top); - gtk4_layer_shell.setKeyboardMode(window, .on_demand); } fn registryListener( @@ -356,9 +355,9 @@ pub const Window = struct { fn syncQuickTerminal(self: *Window) !void { const window = self.apprt_window.window.as(gtk.Window); - const position = self.apprt_window.config.quick_terminal_position; + const config = &self.apprt_window.config; - const anchored_edge: ?gtk4_layer_shell.ShellEdge = switch (position) { + const anchored_edge: ?gtk4_layer_shell.ShellEdge = switch (config.quick_terminal_position) { .left => .left, .right => .right, .top => .top, @@ -366,6 +365,15 @@ pub const Window = struct { .center => null, }; + gtk4_layer_shell.setKeyboardMode( + window, + switch (config.quick_terminal_keyboard_interactivity) { + .none => .none, + .@"on-demand" => .on_demand, + .exclusive => .exclusive, + }, + ); + for (std.meta.tags(gtk4_layer_shell.ShellEdge)) |edge| { if (anchored_edge) |anchored| { if (edge == anchored) { @@ -412,16 +420,18 @@ pub const Window = struct { apprt_window: *ApprtWindow, ) callconv(.c) void { const window = apprt_window.window.as(gtk.Window); - const size = apprt_window.config.quick_terminal_size; - const position = apprt_window.config.quick_terminal_position; + const config = &apprt_window.config; var monitor_size: gdk.Rectangle = undefined; monitor.getGeometry(&monitor_size); - const dims = size.calculate(position, .{ - .width = @intCast(monitor_size.f_width), - .height = @intCast(monitor_size.f_height), - }); + const dims = config.quick_terminal_size.calculate( + config.quick_terminal_position, + .{ + .width = @intCast(monitor_size.f_width), + .height = @intCast(monitor_size.f_height), + }, + ); window.setDefaultSize(@intCast(dims.width), @intCast(dims.height)); } diff --git a/src/config/Config.zig b/src/config/Config.zig index a20719a8f..b59334160 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -1808,6 +1808,34 @@ keybind: Keybinds = .{}, /// On Linux the behavior is always equivalent to `move`. @"quick-terminal-space-behavior": QuickTerminalSpaceBehavior = .move, +/// Determines under which circumstances that the quick terminal should receive +/// keyboard input. See the corresponding [Wayland documentation](https://wayland.app/protocols/wlr-layer-shell-unstable-v1#zwlr_layer_surface_v1:enum:keyboard_interactivity) +/// for a more detailed explanation of the behavior of each option. +/// +/// > [!NOTE] +/// > The exact behavior of each option may differ significantly across +/// > compositors -- experiment with them on your system to find one that +/// > suits your liking! +/// +/// Valid values are: +/// +/// * `none` +/// +/// The quick terminal will not receive any keyboard input. +/// +/// * `on-demand` (default) +/// +/// The quick terminal would only receive keyboard input when it is focused. +/// +/// * `exclusive` +/// +/// The quick terminal will always receive keyboard input, even when another +/// window is currently focused. +/// +/// Only has an effect on Linux Wayland. +/// On macOS the behavior is always equivalent to `on-demand`. +@"quick-terminal-keyboard-interactivity": QuickTerminalKeyboardInteractivity = .@"on-demand", + /// Whether to enable shell integration auto-injection or not. Shell integration /// greatly enhances the terminal experience by enabling a number of features: /// @@ -6138,6 +6166,13 @@ pub const QuickTerminalSpaceBehavior = enum { move, }; +/// See quick-terminal-keyboard-interactivity +pub const QuickTerminalKeyboardInteractivity = enum { + none, + @"on-demand", + exclusive, +}; + /// See grapheme-width-method pub const GraphemeWidthMethod = enum { legacy,