diff --git a/src/apprt/gtk/App.zig b/src/apprt/gtk/App.zig index 9e1b23556..a33f1ce51 100644 --- a/src/apprt/gtk/App.zig +++ b/src/apprt/gtk/App.zig @@ -197,6 +197,7 @@ fn updateConfigErrors(self: *App) !void { fn syncActionAccelerators(self: *App) !void { try self.syncActionAccelerator("app.quit", .{ .quit = {} }); + try self.syncActionAccelerator("win.close", .{ .close_surface = {} }); } fn syncActionAccelerator( @@ -397,6 +398,7 @@ fn initActions(self: *App) void { fn initMenu(self: *App) void { const menu = c.g_menu_new(); errdefer c.g_object_unref(menu); + c.g_menu_append(menu, "Close", "win.close"); c.g_menu_append(menu, "Quit", "app.quit"); // { diff --git a/src/apprt/gtk/Window.zig b/src/apprt/gtk/Window.zig index 86ef1cbd8..cf6e109c5 100644 --- a/src/apprt/gtk/Window.zig +++ b/src/apprt/gtk/Window.zig @@ -145,6 +145,9 @@ pub fn init(self: *Window, app: *App) !void { _ = c.g_signal_connect_data(notebook, "switch-page", c.G_CALLBACK(>kSwitchPage), self, null, c.G_CONNECT_DEFAULT); _ = c.g_signal_connect_data(notebook, "create-window", c.G_CALLBACK(>kNotebookCreateWindow), self, null, c.G_CONNECT_DEFAULT); + // Our actions for the menu + initActions(self); + // The box is our main child c.gtk_window_set_child(gtk_window, box); @@ -152,6 +155,17 @@ pub fn init(self: *Window, app: *App) !void { c.gtk_widget_show(window); } +/// Sets up the GTK actions for the window scope. Actions are how GTK handles +/// menus and such. The menu is defined in App.zig but the action is defined +/// here. The string name binds them. +fn initActions(self: *Window) void { + const action_close = c.g_simple_action_new("close", null); + defer c.g_object_unref(action_close); + _ = c.g_signal_connect_data(action_close, "activate", c.G_CALLBACK(>kActionClose), self, null, c.G_CONNECT_DEFAULT); + + c.g_action_map_add_action(@ptrCast(self.window), @ptrCast(action_close)); +} + pub fn deinit(self: *Window) void { if (self.icon_search_dir) |ptr| self.app.core_app.alloc.free(ptr); } @@ -465,6 +479,19 @@ fn getNotebookPageIndex(page: *c.GtkNotebookPage) c_int { return c.g_value_get_int(&value); } +fn gtkActionClose( + _: *c.GSimpleAction, + _: *c.GVariant, + ud: ?*anyopaque, +) callconv(.C) void { + const self: *Window = @ptrCast(@alignCast(ud orelse return)); + const surface = self.app.core_app.focusedSurface() orelse return; + surface.performBindingAction(.{ .close_surface = {} }) catch |err| { + log.warn("error performing binding action error={}", .{err}); + return; + }; +} + fn userdataSelf(ud: *anyopaque) *Window { return @ptrCast(@alignCast(ud)); }