gui: add move_current_tab action

This commit is contained in:
axdank
2024-10-24 00:01:54 -03:00
parent 61aff898bd
commit 465d60def8
7 changed files with 75 additions and 0 deletions

View File

@ -3913,6 +3913,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool
}, },
), ),
.move_current_tab => |position| try self.rt_app.performAction(
.{ .surface = self },
.move_current_tab,
position,
),
.new_split => |direction| try self.rt_app.performAction( .new_split => |direction| try self.rt_app.performAction(
.{ .surface = self }, .{ .surface = self },
.new_split, .new_split,

View File

@ -100,6 +100,9 @@ pub const Action = union(Key) {
/// Toggle the visibility of all Ghostty terminal windows. /// Toggle the visibility of all Ghostty terminal windows.
toggle_visibility, toggle_visibility,
/// Move current tab given a position
move_current_tab: isize,
/// Jump to a specific tab. Must handle the scenario that the tab /// Jump to a specific tab. Must handle the scenario that the tab
/// value is invalid. /// value is invalid.
goto_tab: GotoTab, goto_tab: GotoTab,
@ -190,6 +193,7 @@ pub const Action = union(Key) {
toggle_window_decorations, toggle_window_decorations,
toggle_quick_terminal, toggle_quick_terminal,
toggle_visibility, toggle_visibility,
move_current_tab,
goto_tab, goto_tab,
goto_split, goto_split,
resize_split, resize_split,
@ -318,6 +322,12 @@ pub const GotoTab = enum(c_int) {
_, _,
}; };
/// Move current tab .
pub const MoveCurrentTabDirection = enum(c_int) {
right,
left,
};
/// The fullscreen mode to toggle to if we're moving to fullscreen. /// The fullscreen mode to toggle to if we're moving to fullscreen.
pub const Fullscreen = enum(c_int) { pub const Fullscreen = enum(c_int) {
native, native,

View File

@ -213,6 +213,7 @@ pub const App = struct {
.toggle_quick_terminal, .toggle_quick_terminal,
.toggle_visibility, .toggle_visibility,
.goto_tab, .goto_tab,
.move_current_tab,
.inspector, .inspector,
.render_inspector, .render_inspector,
.quit_timer, .quit_timer,

View File

@ -456,6 +456,7 @@ pub fn performAction(
.new_tab => try self.newTab(target), .new_tab => try self.newTab(target),
.goto_tab => self.gotoTab(target, value), .goto_tab => self.gotoTab(target, value),
.move_current_tab => self.moveCurrentTab(target, value),
.new_split => try self.newSplit(target, value), .new_split => try self.newSplit(target, value),
.resize_split => self.resizeSplit(target, value), .resize_split => self.resizeSplit(target, value),
.equalize_splits => self.equalizeSplits(target), .equalize_splits => self.equalizeSplits(target),
@ -527,6 +528,23 @@ fn gotoTab(_: *App, target: apprt.Target, tab: apprt.action.GotoTab) void {
} }
} }
fn moveCurrentTab(_: *App, target: apprt.Target, position: isize) void {
switch (target) {
.app => {},
.surface => |v| {
const window = v.rt_surface.container.window() orelse {
log.info(
"moveCurrentTab invalid for container={s}",
.{@tagName(v.rt_surface.container)},
);
return;
};
window.moveCurrentTab(v.rt_surface, @intCast(position));
},
}
}
fn newSplit( fn newSplit(
self: *App, self: *App,
target: apprt.Target, target: apprt.Target,

View File

@ -456,6 +456,15 @@ pub fn gotoNextTab(self: *Window, surface: *Surface) void {
self.focusCurrentTab(); self.focusCurrentTab();
} }
/// Move the current tab for a surface.
pub fn moveCurrentTab(self: *Window, surface: *Surface, position: c_int) void {
const tab = surface.container.tab() orelse {
log.info("surface is not attached to a tab bar, cannot navigate", .{});
return;
};
self.notebook.moveTab(tab, position);
}
/// Go to the next tab for a surface. /// Go to the next tab for a surface.
pub fn gotoLastTab(self: *Window) void { pub fn gotoLastTab(self: *Window) void {
const max = self.notebook.nPages() -| 1; const max = self.notebook.nPages() -| 1;

View File

@ -183,6 +183,33 @@ pub const Notebook = union(enum) {
self.gotoNthTab(next_idx); self.gotoNthTab(next_idx);
} }
pub fn moveTab(self: Notebook, tab: *Tab, position: c_int) void {
switch (self) {
.gtk_notebook => |notebook| {
c.gtk_notebook_reorder_child(notebook, @ptrCast(tab.box), position);
},
.adw_tab_view => |tab_view| {
if (comptime !adwaita.versionAtLeast(0, 0, 0)) unreachable;
const page = c.adw_tab_view_get_page(tab_view, @ptrCast(tab.box));
const page_idx = self.getTabPosition(tab) orelse return;
const max = self.nPages() -| 1;
var new_position: c_int = page_idx + position;
if (new_position < 0) {
new_position = max;
} else if (new_position > max) {
new_position = 0;
}
if (new_position == page_idx) return;
_ = c.adw_tab_view_reorder_page(tab_view, page, new_position);
},
}
}
pub fn setTabLabel(self: Notebook, tab: *Tab, title: [:0]const u8) void { pub fn setTabLabel(self: Notebook, tab: *Tab, title: [:0]const u8) void {
switch (self) { switch (self) {
.adw_tab_view => |tab_view| { .adw_tab_view => |tab_view| {

View File

@ -300,6 +300,9 @@ pub const Action = union(enum) {
/// Go to the tab with the specific number, 1-indexed. /// Go to the tab with the specific number, 1-indexed.
goto_tab: usize, goto_tab: usize,
/// Move current tab to a position
move_current_tab: isize,
/// Toggle the tab overview. /// Toggle the tab overview.
/// This only works with libadwaita enabled currently. /// This only works with libadwaita enabled currently.
toggle_tab_overview: void, toggle_tab_overview: void,
@ -646,6 +649,7 @@ pub const Action = union(enum) {
.next_tab, .next_tab,
.last_tab, .last_tab,
.goto_tab, .goto_tab,
.move_current_tab,
.toggle_tab_overview, .toggle_tab_overview,
.new_split, .new_split,
.goto_split, .goto_split,