apprt/gtk-ng: setup action maps in app and window

This commit is contained in:
Mitchell Hashimoto
2025-07-25 11:20:39 -07:00
parent e865535f6e
commit 02e6ef7e9b
2 changed files with 113 additions and 0 deletions

View File

@ -10,6 +10,7 @@ const gobject = @import("gobject");
const gtk = @import("gtk"); const gtk = @import("gtk");
const build_config = @import("../../../build_config.zig"); const build_config = @import("../../../build_config.zig");
const i18n = @import("../../../os/main.zig").i18n;
const apprt = @import("../../../apprt.zig"); const apprt = @import("../../../apprt.zig");
const cgroup = @import("../cgroup.zig"); const cgroup = @import("../cgroup.zig");
const CoreApp = @import("../../../App.zig"); const CoreApp = @import("../../../App.zig");
@ -677,6 +678,9 @@ pub const Application = extern struct {
// Setup our style manager (light/dark mode) // Setup our style manager (light/dark mode)
self.startupStyleManager(); self.startupStyleManager();
// Setup our action map
self.startupActionMap();
// Setup our cgroup for the application. // Setup our cgroup for the application.
self.startupCgroup() catch |err| { self.startupCgroup() catch |err| {
log.warn("cgroup initialization failed err={}", .{err}); log.warn("cgroup initialization failed err={}", .{err});
@ -762,6 +766,30 @@ pub const Application = extern struct {
); );
} }
/// Setup our action map.
fn startupActionMap(self: *Self) void {
const actions = .{
.{ "quit", actionQuit, null },
};
const action_map = self.as(gio.ActionMap);
inline for (actions) |entry| {
const action = gio.SimpleAction.new(
entry[0],
entry[2],
);
defer action.unref();
_ = gio.SimpleAction.signals.activate.connect(
action,
*Self,
entry[1],
self,
.{},
);
action_map.addAction(action.as(gio.Action));
}
}
const CgroupError = error{ const CgroupError = error{
DbusConnectionFailed, DbusConnectionFailed,
CgroupInitFailed, CgroupInitFailed,
@ -961,6 +989,17 @@ pub const Application = extern struct {
dialog.present(null); dialog.present(null);
} }
fn actionQuit(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Self,
) callconv(.c) void {
const priv = self.private();
priv.core_app.performAction(self.rt(), .quit) catch |err| {
log.warn("error quitting err={}", .{err});
};
}
//---------------------------------------------------------------- //----------------------------------------------------------------
// Boilerplate/Noise // Boilerplate/Noise

View File

@ -2,10 +2,14 @@ const std = @import("std");
const build_config = @import("../../../build_config.zig"); const build_config = @import("../../../build_config.zig");
const assert = std.debug.assert; const assert = std.debug.assert;
const adw = @import("adw"); const adw = @import("adw");
const gio = @import("gio");
const glib = @import("glib");
const gobject = @import("gobject"); const gobject = @import("gobject");
const gtk = @import("gtk"); const gtk = @import("gtk");
const i18n = @import("../../../os/main.zig").i18n;
const CoreSurface = @import("../../../Surface.zig"); const CoreSurface = @import("../../../Surface.zig");
const adw_version = @import("../adw_version.zig");
const gresource = @import("../build/gresource.zig"); const gresource = @import("../build/gresource.zig");
const Common = @import("../class.zig").Common; const Common = @import("../class.zig").Common;
const Application = @import("application.zig").Application; const Application = @import("application.zig").Application;
@ -80,6 +84,32 @@ pub const Window = extern struct {
// Set our window icon. We can't set this in the blueprint file // Set our window icon. We can't set this in the blueprint file
// because its dependent on the build config. // because its dependent on the build config.
self.as(gtk.Window).setIconName(build_config.bundle_id); self.as(gtk.Window).setIconName(build_config.bundle_id);
self.initActionMap();
}
/// Setup our action map.
fn initActionMap(self: *Self) void {
const actions = .{
.{ "about", actionAbout, null },
};
const action_map = self.as(gio.ActionMap);
inline for (actions) |entry| {
const action = gio.SimpleAction.new(
entry[0],
entry[2],
);
defer action.unref();
_ = gio.SimpleAction.signals.activate.connect(
action,
*Self,
entry[1],
self,
.{},
);
action_map.addAction(action.as(gio.Action));
}
} }
//--------------------------------------------------------------- //---------------------------------------------------------------
@ -112,6 +142,50 @@ pub const Window = extern struct {
self.as(gtk.Window).close(); self.as(gtk.Window).close();
} }
fn actionAbout(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *Self,
) callconv(.c) void {
const name = "Ghostty";
const icon = "com.mitchellh.ghostty";
const website = "https://ghostty.org";
if (adw_version.supportsDialogs()) {
adw.showAboutDialog(
self.as(gtk.Widget),
"application-name",
name,
"developer-name",
i18n._("Ghostty Developers"),
"application-icon",
icon,
"version",
build_config.version_string.ptr,
"issue-url",
"https://github.com/ghostty-org/ghostty/issues",
"website",
website,
@as(?*anyopaque, null),
);
} else {
gtk.showAboutDialog(
self.as(gtk.Window),
"program-name",
name,
"logo-icon-name",
icon,
"title",
i18n._("About Ghostty"),
"version",
build_config.version_string.ptr,
"website",
website,
@as(?*anyopaque, null),
);
}
}
const C = Common(Self, Private); const C = Common(Self, Private);
pub const as = C.as; pub const as = C.as;
pub const ref = C.ref; pub const ref = C.ref;