apprt/gtk-ng: move tab

This commit is contained in:
Mitchell Hashimoto
2025-07-29 14:52:31 -07:00
parent 2d1232878d
commit a5188142ba
2 changed files with 67 additions and 1 deletions

View File

@ -503,6 +503,8 @@ pub const Application = extern struct {
.mouse_shape => Action.mouseShape(target, value),
.mouse_visibility => Action.mouseVisibility(target, value),
.move_tab => return Action.moveTab(target, value),
.new_tab => return Action.newTab(target),
.new_window => try Action.newWindow(
@ -537,7 +539,6 @@ pub const Application = extern struct {
.toggle_fullscreen => Action.toggleFullscreen(target),
// Unimplemented but todo on gtk-ng branch
.move_tab,
.new_split,
.resize_split,
.equalize_splits,
@ -1301,6 +1302,30 @@ const Action = struct {
}
}
pub fn moveTab(
target: apprt.Target,
value: apprt.action.MoveTab,
) bool {
switch (target) {
.app => return false,
.surface => |core| {
const surface = core.rt_surface.surface;
const window = ext.getAncestor(
Window,
surface.as(gtk.Widget),
) orelse {
log.warn("surface is not in a window, ignoring new_tab", .{});
return false;
};
return window.moveTab(
surface,
@intCast(value.amount),
);
},
}
}
pub fn newTab(target: apprt.Target) bool {
switch (target) {
.app => {

View File

@ -407,6 +407,47 @@ pub const Window = extern struct {
return true;
}
/// Move the tab containing the given surface by the given amount.
/// Returns if this affected any tab positioning.
pub fn moveTab(
self: *Self,
surface: *Surface,
amount: isize,
) bool {
const priv = self.private();
const tab_view = priv.tab_view;
// If we have one tab we never move.
const total = tab_view.getNPages();
if (total == 1) return false;
// Get the tab that contains the given surface.
const tab = ext.getAncestor(
Tab,
surface.as(gtk.Widget),
) orelse return false;
// Get the page position that contains the tab.
const page = tab_view.getPage(tab.as(gtk.Widget));
const pos = tab_view.getPagePosition(page);
// Move it
const desired_pos: c_int = desired: {
const initial: c_int = @intCast(pos + amount);
const max = total - 1;
break :desired if (initial < 0)
max + initial + 1
else if (initial > max)
initial - max - 1
else
initial;
};
assert(desired_pos >= 0);
assert(desired_pos < total);
return tab_view.reorderPage(page, desired_pos) != 0;
}
/// Updates various appearance properties. This should always be safe
/// to call multiple times. This should be called whenever a change
/// happens that might affect how the window appears (config change,