gtk-ng: add show_on_screen_keyboard binding

pull/8224/head
Leah Amelia Chen 2025-08-14 02:38:45 +08:00
parent 0d0d3118f4
commit 23048dbd33
No known key found for this signature in database
8 changed files with 51 additions and 4 deletions

View File

@ -757,6 +757,7 @@ typedef enum {
GHOSTTY_ACTION_OPEN_URL,
GHOSTTY_ACTION_SHOW_CHILD_EXITED,
GHOSTTY_ACTION_PROGRESS_REPORT,
GHOSTTY_ACTION_SHOW_ON_SCREEN_KEYBOARD,
} ghostty_action_tag_e;
typedef union {

View File

@ -4804,6 +4804,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
{},
),
.show_on_screen_keyboard => return try self.rt_app.performAction(
.{ .surface = self },
.show_on_screen_keyboard,
{},
),
.select_all => {
const sel = self.io.terminal.screen.selectAll();
if (sel) |s| {

View File

@ -291,6 +291,9 @@ pub const Action = union(Key) {
/// Show a native GUI notification about the progress of some TUI operation.
progress_report: terminal.osc.Command.ProgressReport,
/// Show the on-screen keyboard.
show_on_screen_keyboard,
/// Sync with: ghostty_action_tag_e
pub const Key = enum(c_int) {
quit,
@ -345,6 +348,7 @@ pub const Action = union(Key) {
open_url,
show_child_exited,
progress_report,
show_on_screen_keyboard,
};
/// Sync with: ghostty_action_u

View File

@ -618,6 +618,7 @@ pub const Application = extern struct {
.toggle_window_decorations => return Action.toggleWindowDecorations(target),
.toggle_command_palette => return Action.toggleCommandPalette(target),
.toggle_split_zoom => return Action.toggleSplitZoom(target),
.show_on_screen_keyboard => return Action.showOnScreenKeyboard(target),
// Unimplemented but todo on gtk-ng branch
.inspector,
@ -2146,6 +2147,21 @@ const Action = struct {
}
}
pub fn showOnScreenKeyboard(target: apprt.Target) bool {
switch (target) {
.app => {
log.warn("show_on_screen_keyboard to app is unexpected", .{});
return false;
},
// NOTE: Even though `activateOsk` takes a gdk.Event, it's currently
// unused by all implementations of `activateOsk` as of GTK 4.18.
// The commit that introduced the method (ce6aa73c) clarifies that
// the event *may* be used by other IM backends, but for Linux desktop
// environments this doesn't matter.
.surface => |v| return v.rt_surface.surface.showOnScreenKeyboard(null),
}
}
fn getQuickTerminalWindow() ?*Window {
// Find a quick terminal window.
const list = gtk.Window.listToplevels();

View File

@ -573,6 +573,11 @@ pub const Surface = extern struct {
return self.as(gtk.Widget).activateAction("win.toggle-command-palette", null) != 0;
}
pub fn showOnScreenKeyboard(self: *Self, event: ?*gdk.Event) bool {
const priv = self.private();
return priv.im_context.as(gtk.IMContext).activateOsk(event) != 0;
}
/// Set the current progress report state.
pub fn setProgressReport(
self: *Self,
@ -1952,11 +1957,10 @@ pub const Surface = extern struct {
// Trigger the on-screen keyboard if we have no selection.
//
// This cannot be easily implemented with e.g. bindings or apprt
// actions since the API accepts a gdk.Event, making it inherently
// apprt-specific.
// It's better to do this here rather than in the core callback
// since we have direct access to the underlying gdk.Event here.
if (button == .left and !surface.hasSelection()) {
if (priv.im_context.as(gtk.IMContext).activateOsk(event) == 0) {
if (!self.showOnScreenKeyboard(event)) {
log.warn("failed to activate the on-screen keyboard", .{});
}
}

View File

@ -539,6 +539,7 @@ pub fn performAction(
.check_for_updates,
.undo,
.redo,
.show_on_screen_keyboard,
=> {
log.warn("unimplemented action={}", .{action});
return false;

View File

@ -524,6 +524,14 @@ pub const Action = union(enum) {
/// Has no effect on macOS.
show_gtk_inspector,
/// Show the on-screen keyboard if one is present.
///
/// Only implemented on Linux (GTK). On GNOME, the "Screen Keyboard"
/// accessibility feature must be turned on, which can be found under
/// Settings > Accessibility > Typing. Other platforms are as of now
/// untested.
show_on_screen_keyboard,
/// Open the configuration file in the default OS editor.
///
/// If your default OS editor isn't configured then this will fail.
@ -1051,6 +1059,7 @@ pub const Action = union(enum) {
.toggle_window_float_on_top,
.toggle_secure_input,
.toggle_command_palette,
.show_on_screen_keyboard,
.reset_window_size,
.crash,
=> .surface,

View File

@ -369,6 +369,12 @@ fn actionCommands(action: Action.Key) []const Command {
.description = "Show the GTK inspector.",
}},
.show_on_screen_keyboard => comptime &.{.{
.action = .show_on_screen_keyboard,
.title = "Show On-Screen Keyboard",
.description = "Show the on-screen keyboard if present.",
}},
.open_config => comptime &.{.{
.action = .open_config,
.title = "Open Config",