From d47411dfe9fe889dbb659eeeeeb85dc2b4faab08 Mon Sep 17 00:00:00 2001 From: Yi Ming Date: Fri, 8 Nov 2024 17:21:25 +0800 Subject: [PATCH] gtk: show/hide tab bar --- include/ghostty.h | 1 + macos/Sources/Ghostty/Ghostty.App.swift | 4 +++- src/Surface.zig | 6 ++++++ src/apprt/action.zig | 4 ++++ src/apprt/glfw.zig | 1 + src/apprt/gtk/App.zig | 18 ++++++++++++++++++ src/apprt/gtk/Window.zig | 18 ++++++++++++++++++ src/input/Binding.zig | 4 ++++ 8 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/ghostty.h b/include/ghostty.h index f4836f210..96b4f1e5f 100644 --- a/include/ghostty.h +++ b/include/ghostty.h @@ -534,6 +534,7 @@ typedef enum { GHOSTTY_ACTION_NEW_SPLIT, GHOSTTY_ACTION_CLOSE_ALL_WINDOWS, GHOSTTY_ACTION_TOGGLE_FULLSCREEN, + GHOSTTY_ACTION_TOGGLE_TAB_BAR, GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW, GHOSTTY_ACTION_TOGGLE_WINDOW_DECORATIONS, GHOSTTY_ACTION_TOGGLE_QUICK_TERMINAL, diff --git a/macos/Sources/Ghostty/Ghostty.App.swift b/macos/Sources/Ghostty/Ghostty.App.swift index 07acf0f91..e94ed6e33 100644 --- a/macos/Sources/Ghostty/Ghostty.App.swift +++ b/macos/Sources/Ghostty/Ghostty.App.swift @@ -111,7 +111,7 @@ extension Ghostty { deinit { // This will force the didSet callbacks to run which free. self.app = nil - + #if os(macOS) NotificationCenter.default.removeObserver(self) #endif @@ -525,6 +525,8 @@ extension Ghostty { fallthrough case GHOSTTY_ACTION_CLOSE_ALL_WINDOWS: fallthrough + case GHOSTTY_ACTION_TOGGLE_TAB_BAR: + fallthrough case GHOSTTY_ACTION_TOGGLE_TAB_OVERVIEW: fallthrough case GHOSTTY_ACTION_TOGGLE_WINDOW_DECORATIONS: diff --git a/src/Surface.zig b/src/Surface.zig index 10ecfd8f1..1bd0d717f 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -4035,6 +4035,12 @@ pub fn performBindingAction(self: *Surface, action: input.Binding.Action) !bool {}, ), + .toggle_tab_bar => try self.rt_app.performAction( + .{ .surface = self }, + .toggle_tab_bar, + {}, + ), + .toggle_tab_overview => try self.rt_app.performAction( .{ .surface = self }, .toggle_tab_overview, diff --git a/src/apprt/action.zig b/src/apprt/action.zig index feb2e2ba4..dd47b3974 100644 --- a/src/apprt/action.zig +++ b/src/apprt/action.zig @@ -88,6 +88,9 @@ pub const Action = union(Key) { /// Toggle fullscreen mode. toggle_fullscreen: Fullscreen, + /// Toggle tab bar. + toggle_tab_bar, + /// Toggle tab overview. toggle_tab_overview, @@ -197,6 +200,7 @@ pub const Action = union(Key) { new_split, close_all_windows, toggle_fullscreen, + toggle_tab_bar, toggle_tab_overview, toggle_window_decorations, toggle_quick_terminal, diff --git a/src/apprt/glfw.zig b/src/apprt/glfw.zig index 638f52bab..940aad421 100644 --- a/src/apprt/glfw.zig +++ b/src/apprt/glfw.zig @@ -208,6 +208,7 @@ pub const App = struct { .toggle_split_zoom, .present_terminal, .close_all_windows, + .toggle_tab_bar, .toggle_tab_overview, .toggle_window_decorations, .toggle_quick_terminal, diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index e6bf24bd1..a96f96571 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -470,6 +470,7 @@ pub fn performAction( .mouse_visibility => self.setMouseVisibility(target, value), .mouse_shape => try self.setMouseShape(target, value), .mouse_over_link => self.setMouseOverLink(target, value), + .toggle_tab_bar => self.toggleTabBar(target), .toggle_tab_overview => self.toggleTabOverview(target), .toggle_window_decorations => self.toggleWindowDecorations(target), .quit_timer => self.quitTimer(value), @@ -654,6 +655,23 @@ fn toggleFullscreen( } } +fn toggleTabBar(_: *App, target: apprt.Target) void { + switch (target) { + .app => {}, + .surface => |v| { + const window = v.rt_surface.container.window() orelse { + log.info( + "toggleTabBar invalid for container={s}", + .{@tagName(v.rt_surface.container)}, + ); + return; + }; + + window.toggleTabBar(); + }, + } +} + fn toggleTabOverview(_: *App, target: apprt.Target) void { switch (target) { .app => {}, diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index e220ac03b..6d670e1bb 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -37,6 +37,8 @@ window: *c.GtkWindow, /// GtkHeaderBar depending on if adw is enabled and linked. header: ?*c.GtkWidget, +tab_bar: ?*c.AdwTabBar, + /// The tab overview for the window. This is possibly null since there is no /// taboverview without a AdwApplicationWindow (libadwaita >= 1.4.0). tab_overview: ?*c.GtkWidget, @@ -74,6 +76,7 @@ pub fn init(self: *Window, app: *App) !void { .app = app, .window = undefined, .header = null, + .tab_bar = null, .tab_overview = null, .notebook = undefined, .context_menu = undefined, @@ -322,6 +325,8 @@ pub fn init(self: *Window, app: *App) !void { @ptrCast(@alignCast(toolbar_view)), ); } + + self.tab_bar = tab_bar; } else { switch (self.notebook) { .adw_tab_view => |tab_view| if (comptime adwaita.versionAtLeast(0, 0, 0)) { @@ -349,6 +354,7 @@ pub fn init(self: *Window, app: *App) !void { if (!app.config.@"gtk-wide-tabs") { c.adw_tab_bar_set_expand_tabs(tab_bar, 0); } + self.tab_bar = tab_bar; }, .gtk_notebook => {}, @@ -496,6 +502,18 @@ pub fn toggleFullscreen(self: *Window) void { } } +pub fn toggleTabBar(self: *Window) void { + if (self.tab_bar) |tab_bar| { + const is_visible = c.gtk_widget_get_visible( + @ptrCast(@alignCast(tab_bar)), + ) == 1; + c.gtk_widget_set_visible(@ptrCast(@alignCast(tab_bar)), @intFromBool(!is_visible)); + } else { + const is_visible = c.gtk_notebook_get_show_tabs(self.notebook.gtk_notebook) == 1; + c.gtk_notebook_set_show_tabs(self.notebook.gtk_notebook, @intFromBool(!is_visible)); + } +} + /// Toggle the window decorations for this window. pub fn toggleWindowDecorations(self: *Window) void { const old_decorated = c.gtk_window_get_decorated(self.window) == 1; diff --git a/src/input/Binding.zig b/src/input/Binding.zig index 5a4cd3f3e..e74347a19 100644 --- a/src/input/Binding.zig +++ b/src/input/Binding.zig @@ -306,6 +306,9 @@ pub const Action = union(enum) { /// If the new position is out of bounds, it wraps around cyclically within the tab range. move_tab: isize, + /// Toggle the tab bar. This works only on Linux. + toggle_tab_bar: void, + /// Toggle the tab overview. /// This only works with libadwaita enabled currently. toggle_tab_overview: void, @@ -639,6 +642,7 @@ pub const Action = union(enum) { .close_surface, .close_window, .toggle_fullscreen, + .toggle_tab_bar, .toggle_window_decorations, .toggle_secure_input, .crash,