aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/apprt
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-16 23:28:05 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-16 23:29:28 +0300
commit4a3302d19a2baa3a33e910e0088c24e780905b90 (patch)
treedcaf76fae1c82102d933c9225b17ca7ac5d3a847 /vendor/libghostty-vt/src/apprt
parent550e9f8cc085f428429f5cf2da0bb2dba897e8b8 (diff)
chore: update vendored libghostty-vt
refs #276
Diffstat (limited to 'vendor/libghostty-vt/src/apprt')
-rw-r--r--vendor/libghostty-vt/src/apprt/action.zig5
-rw-r--r--vendor/libghostty-vt/src/apprt/gtk/class/application.zig3
-rw-r--r--vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig54
-rw-r--r--vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig10
-rw-r--r--vendor/libghostty-vt/src/apprt/gtk/class/surface.zig61
-rw-r--r--vendor/libghostty-vt/src/apprt/gtk/class/window.zig42
-rw-r--r--vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp5
7 files changed, 133 insertions, 47 deletions
diff --git a/vendor/libghostty-vt/src/apprt/action.zig b/vendor/libghostty-vt/src/apprt/action.zig
index f6865af8..4728d73c 100644
--- a/vendor/libghostty-vt/src/apprt/action.zig
+++ b/vendor/libghostty-vt/src/apprt/action.zig
@@ -295,6 +295,10 @@ pub const Action = union(Key) {
/// it needs to ring the bell. This is usually a sound or visual effect.
ring_bell,
+ /// Called when the active selection changes. The apprt should read the
+ /// current selection itself; this carries no payload.
+ selection_changed,
+
/// Undo the last action. See the "undo" keybinding for more
/// details on what can and cannot be undone.
undo,
@@ -396,6 +400,7 @@ pub const Action = union(Key) {
config_change,
close_window,
ring_bell,
+ selection_changed,
undo,
redo,
check_for_updates,
diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/application.zig b/vendor/libghostty-vt/src/apprt/gtk/class/application.zig
index 107510b4..a627086e 100644
--- a/vendor/libghostty-vt/src/apprt/gtk/class/application.zig
+++ b/vendor/libghostty-vt/src/apprt/gtk/class/application.zig
@@ -743,6 +743,9 @@ pub const Application = extern struct {
.ring_bell => Action.ringBell(target),
+ // GTK has no accessibility consumer for this yet.
+ .selection_changed => {},
+
.scrollbar => Action.scrollbar(target, value),
.set_title => Action.setTitle(target, value),
diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig b/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig
index cf0f31a6..28987c25 100644
--- a/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig
+++ b/vendor/libghostty-vt/src/apprt/gtk/class/global_shortcuts.zig
@@ -108,34 +108,35 @@ pub const GlobalShortcuts = extern struct {
fn close(self: *Self) void {
const priv = self.private();
- const dbus = priv.dbus_connection orelse return;
- if (priv.response_subscription != 0) {
- dbus.signalUnsubscribe(priv.response_subscription);
- priv.response_subscription = 0;
- }
+ if (priv.dbus_connection) |dbus| {
+ if (priv.response_subscription != 0) {
+ dbus.signalUnsubscribe(priv.response_subscription);
+ priv.response_subscription = 0;
+ }
- if (priv.activate_subscription != 0) {
- dbus.signalUnsubscribe(priv.activate_subscription);
- priv.activate_subscription = 0;
- }
+ if (priv.activate_subscription != 0) {
+ dbus.signalUnsubscribe(priv.activate_subscription);
+ priv.activate_subscription = 0;
+ }
- if (priv.handle) |handle| {
- // Close existing session
- dbus.call(
- "org.freedesktop.portal.Desktop",
- handle,
- "org.freedesktop.portal.Session",
- "Close",
- null,
- null,
- .{},
- -1,
- null,
- null,
- null,
- );
- priv.handle = null;
+ if (priv.handle) |handle| {
+ // Close existing session
+ dbus.call(
+ "org.freedesktop.portal.Desktop",
+ handle,
+ "org.freedesktop.portal.Session",
+ "Close",
+ null,
+ null,
+ .{},
+ -1,
+ null,
+ null,
+ null,
+ );
+ priv.handle = null;
+ }
}
if (priv.arena) |*arena| {
@@ -151,7 +152,8 @@ pub const GlobalShortcuts = extern struct {
const priv = self.private();
- // We need configuration to proceed.
+ // We need a dbus connection and configuration to proceed.
+ if (priv.dbus_connection == null) return;
const config = if (priv.config) |v| v.get() else return;
// Setup our new arena that we'll use for memory allocations.
diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig b/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig
index 5aef53d2..7a6b66de 100644
--- a/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig
+++ b/vendor/libghostty-vt/src/apprt/gtk/class/split_tree.zig
@@ -193,6 +193,7 @@ pub const SplitTree = extern struct {
.init("new-split", actionNewSplit, s_variant_type),
.init("equalize", actionEqualize, null),
.init("zoom", actionZoom, null),
+ .init("close-split", actionCloseSplit, null),
};
_ = ext.actions.addAsGroup(Self, self, "split-tree", &actions);
@@ -683,6 +684,15 @@ pub const SplitTree = extern struct {
self.as(gobject.Object).notifyByPspec(properties.tree.impl.param_spec);
}
+ pub fn actionCloseSplit(
+ _: *gio.SimpleAction,
+ _: ?*glib.Variant,
+ self: *Self,
+ ) callconv(.c) void {
+ const surface = self.getActiveSurface() orelse return;
+ surface.close();
+ }
+
fn surfaceCloseRequest(
surface: *Surface,
self: *Self,
diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig b/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig
index 629866dc..54825ce0 100644
--- a/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig
+++ b/vendor/libghostty-vt/src/apprt/gtk/class/surface.zig
@@ -3030,37 +3030,56 @@ pub const Surface = extern struct {
) callconv(.c) c_int {
const priv: *Private = self.private();
- switch (ec.getUnit()) {
- .surface => {},
- .wheel => return @intFromBool(false),
- else => return @intFromBool(false),
- }
+ // Check if horizontal tab scrolling is enabled and this is a
+ // touchpad surface scroll. If not, forward to the terminal.
+ const tab_scroll_enabled = if (priv.config) |config|
+ config.get().@"gtk-horizontal-tab-scroll"
+ else
+ true;
+
+ const is_surface_scroll = ec.getUnit() == .surface;
+
+ if (tab_scroll_enabled and is_surface_scroll) {
+ priv.pending_horizontal_scroll += x;
+
+ if (@abs(priv.pending_horizontal_scroll) < 120) {
+ if (priv.pending_horizontal_scroll_reset) |v| {
+ _ = glib.Source.remove(v);
+ priv.pending_horizontal_scroll_reset = null;
+ }
+ priv.pending_horizontal_scroll_reset = glib.timeoutAdd(500, ecMouseScrollHorizontalReset, self);
+ return @intFromBool(true);
+ }
- priv.pending_horizontal_scroll += x;
+ _ = self.as(gtk.Widget).activateAction(
+ if (priv.pending_horizontal_scroll < 0.0)
+ "tab.next-page"
+ else
+ "tab.previous-page",
+ null,
+ );
- if (@abs(priv.pending_horizontal_scroll) < 120) {
if (priv.pending_horizontal_scroll_reset) |v| {
_ = glib.Source.remove(v);
priv.pending_horizontal_scroll_reset = null;
}
- priv.pending_horizontal_scroll_reset = glib.timeoutAdd(500, ecMouseScrollHorizontalReset, self);
- return @intFromBool(true);
- }
- _ = self.as(gtk.Widget).activateAction(
- if (priv.pending_horizontal_scroll < 0.0)
- "tab.next-page"
- else
- "tab.previous-page",
- null,
- );
+ priv.pending_horizontal_scroll = 0.0;
- if (priv.pending_horizontal_scroll_reset) |v| {
- _ = glib.Source.remove(v);
- priv.pending_horizontal_scroll_reset = null;
+ return @intFromBool(true);
}
- priv.pending_horizontal_scroll = 0.0;
+ // Forward horizontal scroll to the terminal (e.g. for neovim).
+ const surface = priv.core_surface orelse return @intFromBool(false);
+ const scaled = self.scaledCoordinates(x, 0);
+ surface.scrollCallback(
+ scaled.x * -1,
+ 0,
+ .{},
+ ) catch |err| {
+ log.warn("error in scroll callback err={}", .{err});
+ return @intFromBool(false);
+ };
return @intFromBool(true);
}
diff --git a/vendor/libghostty-vt/src/apprt/gtk/class/window.zig b/vendor/libghostty-vt/src/apprt/gtk/class/window.zig
index 2a1a5435..c34f2cb4 100644
--- a/vendor/libghostty-vt/src/apprt/gtk/class/window.zig
+++ b/vendor/libghostty-vt/src/apprt/gtk/class/window.zig
@@ -1156,6 +1156,38 @@ pub const Window = extern struct {
};
}
+ fn toplevelComputeSize(
+ _: *gdk.Toplevel,
+ size: *gdk.ToplevelSize,
+ self: *Self,
+ ) callconv(.c) void {
+ // The compositor/quick terminal own the size in these states.
+ if (self.isMaximized() or
+ self.isFullscreen() or
+ self.isQuickTerminal()) return;
+
+ // If there's no GdkSurface yet these dimensions will be zero size which
+ // will make the window start out as small as possible. These checks ensure
+ // we don't start with a 0, 0 window size.
+ const gdk_surface = self.as(gtk.Native).getSurface() orelse return;
+ const w = gdk_surface.getWidth();
+ const h = gdk_surface.getHeight();
+ if (w <= 0 or h <= 0) return;
+
+ // GTK clamps the requested size to the compositor-reported bounds, which
+ // go stale when the window moves to a larger monitor. Only re-assert the
+ // current size when it exceeds those bounds; otherwise let GTK's default
+ // sizing win so a freshly-mapped window isn't forced to a tiny size.
+ var bounds_w: c_int = undefined;
+ var bounds_h: c_int = undefined;
+ size.getBounds(&bounds_w, &bounds_h);
+
+ if (bounds_w <= 0 or bounds_h <= 0) return;
+ if (w <= bounds_w and h <= bounds_h) return;
+
+ size.setSize(w, h);
+ }
+
fn propFullscreened(
_: *adw.ApplicationWindow,
_: *gobject.ParamSpec,
@@ -1330,6 +1362,16 @@ pub const Window = extern struct {
self,
.{ .detail = "height" },
);
+ // Connect after GTK's compute-size handler so our size wins.
+ if (gobject.ext.cast(gdk.Toplevel, gdk_surface)) |toplevel| {
+ _ = gdk.Toplevel.signals.compute_size.connect(
+ toplevel,
+ *Self,
+ toplevelComputeSize,
+ self,
+ .{ .after = true },
+ );
+ }
}
// When we are realized we always setup our appearance since this
diff --git a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp
index 2f01c48c..2ae0a347 100644
--- a/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp
+++ b/vendor/libghostty-vt/src/apprt/gtk/ui/1.2/surface.blp
@@ -318,6 +318,11 @@ menu context_menu_model {
action: "split-tree.new-split";
target: "right";
}
+
+ item {
+ label: _("Close Split");
+ action: "split-tree.close-split";
+ }
}
submenu {