Skip to content

Commit 12ce9f2

Browse files
authored
feat(GTK): show menu in context menu if titlebar is disabled (ghostty-org#4864)
This PR addresses ghostty-org#4732. While @tristan957 suggested alternative approaches, this implementation provides a straightforward way to make the menu accessible when the window decoration is disabled. It follows patterns seen in other GTK apps for handling submenus, though not strictly in the context menu format truth be told. If there’s a better way to approach this or further refinements needed, I’m happy to discuss and iterate. This has been a minor issue I’ve encountered personally, and I’d like to help improve the experience for others as well. Small video of how it looks: https://github.com/user-attachments/assets/59548fef-f11c-421f-b05b-be81eab6ce06
2 parents 2d7706e + b25c593 commit 12ce9f2

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

src/apprt/gtk/App.zig

+28-12
Original file line numberDiff line numberDiff line change
@@ -831,12 +831,12 @@ fn setSizeLimit(
831831
switch (target) {
832832
.app => {},
833833
.surface => |v| try v.rt_surface.setSizeLimits(.{
834-
.width = value.min_width,
835-
.height = value.min_height,
836-
}, if (value.max_width > 0) .{
837-
.width = value.max_width,
838-
.height = value.max_height,
839-
} else null),
834+
.width = value.min_width,
835+
.height = value.min_height,
836+
}, if (value.max_width > 0) .{
837+
.width = value.max_width,
838+
.height = value.max_height,
839+
} else null),
840840
}
841841
}
842842

@@ -1766,12 +1766,10 @@ fn initActions(self: *App) void {
17661766
}
17671767
}
17681768

1769-
/// This sets the self.menu property to the application menu that can be
1770-
/// shared by all application windows.
1771-
fn initMenu(self: *App) void {
1772-
const menu = c.g_menu_new();
1773-
errdefer c.g_object_unref(menu);
1774-
1769+
/// Initializes and populates the provided GMenu with sections and actions.
1770+
/// This function is used to set up the application's menu structure, either for
1771+
/// the main menu button or as a context menu when window decorations are disabled.
1772+
fn initMenuContent(menu: *c.GMenu) void {
17751773
{
17761774
const section = c.g_menu_new();
17771775
defer c.g_object_unref(section);
@@ -1793,7 +1791,14 @@ fn initMenu(self: *App) void {
17931791
c.g_menu_append(section, "Reload Configuration", "app.reload-config");
17941792
c.g_menu_append(section, "About Ghostty", "win.about");
17951793
}
1794+
}
17961795

1796+
/// This sets the self.menu property to the application menu that can be
1797+
/// shared by all application windows.
1798+
fn initMenu(self: *App) void {
1799+
const menu = c.g_menu_new();
1800+
errdefer c.g_object_unref(menu);
1801+
initMenuContent(@ptrCast(menu));
17971802
self.menu = menu;
17981803
}
17991804

@@ -1825,6 +1830,17 @@ fn initContextMenu(self: *App) void {
18251830
c.g_menu_append(section, "Terminal Inspector", "win.toggle_inspector");
18261831
}
18271832

1833+
if (!self.config.@"window-decoration") {
1834+
const section = c.g_menu_new();
1835+
defer c.g_object_unref(section);
1836+
const submenu = c.g_menu_new();
1837+
defer c.g_object_unref(submenu);
1838+
1839+
initMenuContent(@ptrCast(submenu));
1840+
c.g_menu_append_submenu(section, "Menu", @ptrCast(@alignCast(submenu)));
1841+
c.g_menu_append_section(menu, null, @ptrCast(@alignCast(section)));
1842+
}
1843+
18281844
self.context_menu = menu;
18291845
}
18301846

src/apprt/gtk/Window.zig

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ pub fn init(self: *Window, app: *App) !void {
270270
}
271271

272272
self.context_menu = c.gtk_popover_menu_new_from_model(@ptrCast(@alignCast(self.app.context_menu)));
273-
c.gtk_widget_set_parent(self.context_menu, window);
273+
c.gtk_widget_set_parent(self.context_menu, box);
274274
c.gtk_popover_set_has_arrow(@ptrCast(@alignCast(self.context_menu)), 0);
275275
c.gtk_widget_set_halign(self.context_menu, c.GTK_ALIGN_START);
276276

0 commit comments

Comments
 (0)