mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
apprt/gtk: initial app menu
This commit is contained in:
@ -37,6 +37,9 @@ ctx: *c.GMainContext,
|
||||
/// The "none" cursor. We use one that is shared across the entire app.
|
||||
cursor_none: ?*c.GdkCursor,
|
||||
|
||||
/// The shared application menu.
|
||||
menu: ?*c.GMenu = null,
|
||||
|
||||
/// The configuration errors window, if it is currently open.
|
||||
config_errors_window: ?*ConfigErrorsWindow = null,
|
||||
|
||||
@ -140,6 +143,7 @@ pub fn terminate(self: *App) void {
|
||||
c.g_object_unref(self.app);
|
||||
|
||||
if (self.cursor_none) |cursor| c.g_object_unref(cursor);
|
||||
if (self.menu) |menu| c.g_object_unref(menu);
|
||||
|
||||
self.config.deinit();
|
||||
|
||||
@ -195,6 +199,10 @@ pub fn wakeup(self: App) void {
|
||||
pub fn run(self: *App) !void {
|
||||
if (!self.running) return;
|
||||
|
||||
// If we're not remote, then we also setup our actions and menus.
|
||||
self.initActions();
|
||||
self.initMenu();
|
||||
|
||||
// On startup, we want to check for configuration errors right away
|
||||
// so we can show our error window.
|
||||
self.updateConfigErrors() catch |err| {
|
||||
@ -331,3 +339,41 @@ fn gtkActivate(app: *c.GtkApplication, ud: ?*anyopaque) callconv(.C) void {
|
||||
.new_window = .{},
|
||||
}, .{ .forever = {} });
|
||||
}
|
||||
|
||||
fn gtkActionQuit(
|
||||
_: *c.GSimpleAction,
|
||||
_: *c.GVariant,
|
||||
ud: ?*anyopaque,
|
||||
) callconv(.C) void {
|
||||
const self: *App = @ptrCast(@alignCast(ud orelse return));
|
||||
self.core_app.setQuit() catch |err| {
|
||||
log.warn("error setting quit err={}", .{err});
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
/// This is called to setup the action map that this application supports.
|
||||
/// This should be called only once on startup.
|
||||
fn initActions(self: *App) void {
|
||||
const action_quit = c.g_simple_action_new("quit", null);
|
||||
defer c.g_object_unref(action_quit);
|
||||
c.g_action_map_add_action(@ptrCast(self.app), @ptrCast(action_quit));
|
||||
|
||||
_ = c.g_signal_connect_data(action_quit, "activate", c.G_CALLBACK(>kActionQuit), self, null, c.G_CONNECT_DEFAULT);
|
||||
}
|
||||
|
||||
/// This sets the self.menu property to the application menu that can be
|
||||
/// shared by all application windows.
|
||||
fn initMenu(self: *App) void {
|
||||
const menu = c.g_menu_new();
|
||||
errdefer c.g_object_unref(menu);
|
||||
c.g_menu_append(menu, "Quit", "app.quit");
|
||||
|
||||
// {
|
||||
// const section = c.g_menu_new();
|
||||
// defer c.g_object_unref(section);
|
||||
// c.g_menu_append_submenu(menu, "File", @ptrCast(@alignCast(section)));
|
||||
// }
|
||||
|
||||
self.menu = menu;
|
||||
}
|
||||
|
@ -89,6 +89,16 @@ pub fn init(self: *Window, app: *App) !void {
|
||||
c.gtk_widget_set_opacity(@ptrCast(window), app.config.@"background-opacity");
|
||||
}
|
||||
|
||||
// Use the new GTK4 header bar
|
||||
const header = c.gtk_header_bar_new();
|
||||
c.gtk_window_set_titlebar(gtk_window, header);
|
||||
{
|
||||
const btn = c.gtk_menu_button_new();
|
||||
c.gtk_menu_button_set_icon_name(@ptrCast(btn), "open-menu-symbolic");
|
||||
c.gtk_menu_button_set_menu_model(@ptrCast(btn), @ptrCast(@alignCast(app.menu)));
|
||||
c.gtk_header_bar_pack_end(@ptrCast(header), btn);
|
||||
}
|
||||
|
||||
// Hide window decoration if configured. This has to happen before
|
||||
// `gtk_widget_show`.
|
||||
if (!app.config.@"window-decoration") {
|
||||
|
Reference in New Issue
Block a user