apprt/gtk: initial app menu

This commit is contained in:
Mitchell Hashimoto
2023-09-18 12:54:19 -07:00
parent 4606d56dc0
commit 394ab3017f
2 changed files with 56 additions and 0 deletions

View File

@ -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(&gtkActionQuit), 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;
}

View File

@ -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") {