gtk-ng: show on-screen keyboard on LMB release (#8224)
commit
92d6395a8d
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
@ -1946,18 +1951,29 @@ pub const Surface = extern struct {
|
|||
const event = gesture.as(gtk.EventController).getCurrentEvent() orelse return;
|
||||
|
||||
const priv = self.private();
|
||||
if (priv.core_surface) |surface| {
|
||||
const gtk_mods = event.getModifierState();
|
||||
const button = translateMouseButton(gesture.as(gtk.GestureSingle).getCurrentButton());
|
||||
const mods = gtk_key.translateMods(gtk_mods);
|
||||
_ = surface.mouseButtonCallback(
|
||||
.release,
|
||||
button,
|
||||
mods,
|
||||
) catch |err| {
|
||||
log.warn("error in key callback err={}", .{err});
|
||||
return;
|
||||
};
|
||||
const surface = priv.core_surface orelse return;
|
||||
const gtk_mods = event.getModifierState();
|
||||
const button = translateMouseButton(gesture.as(gtk.GestureSingle).getCurrentButton());
|
||||
|
||||
const mods = gtk_key.translateMods(gtk_mods);
|
||||
const consumed = surface.mouseButtonCallback(
|
||||
.release,
|
||||
button,
|
||||
mods,
|
||||
) catch |err| {
|
||||
log.warn("error in key callback err={}", .{err});
|
||||
return;
|
||||
};
|
||||
|
||||
// Trigger the on-screen keyboard if we have no selection,
|
||||
// and that the mouse event hasn't been intercepted by the callback.
|
||||
//
|
||||
// It's better to do this here rather than within the core callback
|
||||
// since we have direct access to the underlying gdk.Event here.
|
||||
if (!consumed and button == .left and !surface.hasSelection()) {
|
||||
if (!self.showOnScreenKeyboard(event)) {
|
||||
log.warn("failed to activate the on-screen keyboard", .{});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -539,6 +539,7 @@ pub fn performAction(
|
|||
.check_for_updates,
|
||||
.undo,
|
||||
.redo,
|
||||
.show_on_screen_keyboard,
|
||||
=> {
|
||||
log.warn("unimplemented action={}", .{action});
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
Loading…
Reference in New Issue