gtk-ng: show on-screen keyboard on LMB release (#8224)
commit
92d6395a8d
|
|
@ -757,6 +757,7 @@ typedef enum {
|
||||||
GHOSTTY_ACTION_OPEN_URL,
|
GHOSTTY_ACTION_OPEN_URL,
|
||||||
GHOSTTY_ACTION_SHOW_CHILD_EXITED,
|
GHOSTTY_ACTION_SHOW_CHILD_EXITED,
|
||||||
GHOSTTY_ACTION_PROGRESS_REPORT,
|
GHOSTTY_ACTION_PROGRESS_REPORT,
|
||||||
|
GHOSTTY_ACTION_SHOW_ON_SCREEN_KEYBOARD,
|
||||||
} ghostty_action_tag_e;
|
} ghostty_action_tag_e;
|
||||||
|
|
||||||
typedef union {
|
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 => {
|
.select_all => {
|
||||||
const sel = self.io.terminal.screen.selectAll();
|
const sel = self.io.terminal.screen.selectAll();
|
||||||
if (sel) |s| {
|
if (sel) |s| {
|
||||||
|
|
|
||||||
|
|
@ -291,6 +291,9 @@ pub const Action = union(Key) {
|
||||||
/// Show a native GUI notification about the progress of some TUI operation.
|
/// Show a native GUI notification about the progress of some TUI operation.
|
||||||
progress_report: terminal.osc.Command.ProgressReport,
|
progress_report: terminal.osc.Command.ProgressReport,
|
||||||
|
|
||||||
|
/// Show the on-screen keyboard.
|
||||||
|
show_on_screen_keyboard,
|
||||||
|
|
||||||
/// Sync with: ghostty_action_tag_e
|
/// Sync with: ghostty_action_tag_e
|
||||||
pub const Key = enum(c_int) {
|
pub const Key = enum(c_int) {
|
||||||
quit,
|
quit,
|
||||||
|
|
@ -345,6 +348,7 @@ pub const Action = union(Key) {
|
||||||
open_url,
|
open_url,
|
||||||
show_child_exited,
|
show_child_exited,
|
||||||
progress_report,
|
progress_report,
|
||||||
|
show_on_screen_keyboard,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Sync with: ghostty_action_u
|
/// Sync with: ghostty_action_u
|
||||||
|
|
|
||||||
|
|
@ -618,6 +618,7 @@ pub const Application = extern struct {
|
||||||
.toggle_window_decorations => return Action.toggleWindowDecorations(target),
|
.toggle_window_decorations => return Action.toggleWindowDecorations(target),
|
||||||
.toggle_command_palette => return Action.toggleCommandPalette(target),
|
.toggle_command_palette => return Action.toggleCommandPalette(target),
|
||||||
.toggle_split_zoom => return Action.toggleSplitZoom(target),
|
.toggle_split_zoom => return Action.toggleSplitZoom(target),
|
||||||
|
.show_on_screen_keyboard => return Action.showOnScreenKeyboard(target),
|
||||||
|
|
||||||
// Unimplemented but todo on gtk-ng branch
|
// Unimplemented but todo on gtk-ng branch
|
||||||
.inspector,
|
.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 {
|
fn getQuickTerminalWindow() ?*Window {
|
||||||
// Find a quick terminal window.
|
// Find a quick terminal window.
|
||||||
const list = gtk.Window.listToplevels();
|
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;
|
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.
|
/// Set the current progress report state.
|
||||||
pub fn setProgressReport(
|
pub fn setProgressReport(
|
||||||
self: *Self,
|
self: *Self,
|
||||||
|
|
@ -1946,11 +1951,12 @@ pub const Surface = extern struct {
|
||||||
const event = gesture.as(gtk.EventController).getCurrentEvent() orelse return;
|
const event = gesture.as(gtk.EventController).getCurrentEvent() orelse return;
|
||||||
|
|
||||||
const priv = self.private();
|
const priv = self.private();
|
||||||
if (priv.core_surface) |surface| {
|
const surface = priv.core_surface orelse return;
|
||||||
const gtk_mods = event.getModifierState();
|
const gtk_mods = event.getModifierState();
|
||||||
const button = translateMouseButton(gesture.as(gtk.GestureSingle).getCurrentButton());
|
const button = translateMouseButton(gesture.as(gtk.GestureSingle).getCurrentButton());
|
||||||
|
|
||||||
const mods = gtk_key.translateMods(gtk_mods);
|
const mods = gtk_key.translateMods(gtk_mods);
|
||||||
_ = surface.mouseButtonCallback(
|
const consumed = surface.mouseButtonCallback(
|
||||||
.release,
|
.release,
|
||||||
button,
|
button,
|
||||||
mods,
|
mods,
|
||||||
|
|
@ -1958,6 +1964,16 @@ pub const Surface = extern struct {
|
||||||
log.warn("error in key callback err={}", .{err});
|
log.warn("error in key callback err={}", .{err});
|
||||||
return;
|
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,
|
.check_for_updates,
|
||||||
.undo,
|
.undo,
|
||||||
.redo,
|
.redo,
|
||||||
|
.show_on_screen_keyboard,
|
||||||
=> {
|
=> {
|
||||||
log.warn("unimplemented action={}", .{action});
|
log.warn("unimplemented action={}", .{action});
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -524,6 +524,14 @@ pub const Action = union(enum) {
|
||||||
/// Has no effect on macOS.
|
/// Has no effect on macOS.
|
||||||
show_gtk_inspector,
|
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.
|
/// Open the configuration file in the default OS editor.
|
||||||
///
|
///
|
||||||
/// If your default OS editor isn't configured then this will fail.
|
/// 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_window_float_on_top,
|
||||||
.toggle_secure_input,
|
.toggle_secure_input,
|
||||||
.toggle_command_palette,
|
.toggle_command_palette,
|
||||||
|
.show_on_screen_keyboard,
|
||||||
.reset_window_size,
|
.reset_window_size,
|
||||||
.crash,
|
.crash,
|
||||||
=> .surface,
|
=> .surface,
|
||||||
|
|
|
||||||
|
|
@ -369,6 +369,12 @@ fn actionCommands(action: Action.Key) []const Command {
|
||||||
.description = "Show the GTK inspector.",
|
.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 &.{.{
|
.open_config => comptime &.{.{
|
||||||
.action = .open_config,
|
.action = .open_config,
|
||||||
.title = "Open Config",
|
.title = "Open Config",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue