linux: add dbus and systemd activation services

This commit is contained in:
Jeffrey C. Ollie
2025-05-24 17:01:06 -05:00
parent c3d65d3975
commit 8824d11e1c
7 changed files with 59 additions and 4 deletions

View File

@@ -1,8 +1,10 @@
[Desktop Entry]
Version=1.0
Name=Ghostty
Type=Application
Comment=A terminal emulator
Exec=ghostty
TryExec=ghostty
Exec=ghostty %F
Icon=com.mitchellh.ghostty
Categories=System;TerminalEmulator;
Keywords=terminal;tty;pty;
@@ -16,6 +18,7 @@ X-TerminalArgTitle=--title=
X-TerminalArgAppId=--class=
X-TerminalArgDir=--working-directory=
X-TerminalArgHold=--wait-after-command
DBusActivatable=true
[Desktop Action new-window]
Name=New Window

4
dist/linux/dbus.service vendored Normal file
View File

@@ -0,0 +1,4 @@
[D-BUS Service]
Name=com.mitchellh.ghostty
SystemdService=com.mitchellh.ghostty.service
Exec=ghostty

7
dist/linux/systemd.service vendored Normal file
View File

@@ -0,0 +1,7 @@
[Unit]
Description=Ghostty
[Service]
Type=dbus
BusName=com.mitchellh.ghostty
ExecStart=ghostty

View File

@@ -117,6 +117,11 @@ in
mkdir -p "$out/nix-support"
sed -i -e "s@^Exec=.*ghostty@Exec=$out/bin/ghostty@" $out/share/applications/com.mitchellh.ghostty.desktop
sed -i -e "s@^TryExec=.*ghostty@TryExec=$out/bin/ghostty@" $out/share/applications/com.mitchellh.ghostty.desktop
sed -i -e "s@^Exec=.*ghostty@Exec=$out/bin/ghostty@" $out/share/dbus-1/services/com.mitchellh.ghostty.service
sed -i -e "s@^ExecStart=.*ghostty@ExecStart=$out/bin/ghostty@" $out/lib/systemd/user/com.mitchellh.ghostty.service
mkdir -p "$terminfo/share"
mv "$terminfo_src" "$terminfo/share/terminfo"
ln -sf "$terminfo/share/terminfo" "$terminfo_src"

View File

@@ -400,11 +400,15 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
// This just calls the `activate` signal but its part of the normal startup
// routine so we just call it, but only if the config allows it (this allows
// for launching Ghostty in the "background" without immediately opening
// a window)
// a window). An initial window will not be immediately created if we were
// launched by D-Bus activation or systemd. D-Bus activation will send it's
// own `activate` or `new-window` signal later.
//
// https://gitlab.gnome.org/GNOME/glib/-/blob/bd2ccc2f69ecfd78ca3f34ab59e42e2b462bad65/gio/gapplication.c#L2302
if (config.@"initial-window")
gio_app.activate();
if (config.@"initial-window") switch (config.@"launched-from".?) {
.dbus, .systemd => {},
else => gio_app.activate(),
};
// Internally, GTK ensures that only one instance of this provider exists in the provider list
// for the display.
@@ -1678,6 +1682,17 @@ fn gtkActionShowGTKInspector(
};
}
fn gtkActionNewWindow(
_: *gio.SimpleAction,
_: ?*glib.Variant,
self: *App,
) callconv(.c) void {
log.info("received new window action", .{});
_ = self.core_app.mailbox.push(.{
.new_window = .{},
}, .{ .forever = {} });
}
/// 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 {
@@ -1697,7 +1712,9 @@ fn initActions(self: *App) void {
.{ "reload-config", gtkActionReloadConfig, null },
.{ "present-surface", gtkActionPresentSurface, t },
.{ "show-gtk-inspector", gtkActionShowGTKInspector, null },
.{ "new-window", gtkActionNewWindow, null },
};
inline for (actions) |entry| {
const action = gio.SimpleAction.new(entry[0], entry[2]);
defer action.unref();

View File

@@ -2325,6 +2325,15 @@ pub fn defaultTermioEnv(self: *Surface) !std.process.EnvMap {
env.remove("GDK_DISABLE");
env.remove("GSK_RENDERER");
// Remove some environment variables that are set when Ghostty is launched
// from a `.desktop` file, by D-Bus activation, or systemd.
env.remove("GIO_LAUNCHED_DESKTOP_FILE");
env.remove("GIO_LAUNCHED_DESKTOP_FILE_PID");
env.remove("DBUS_STARTER_ADDRESS");
env.remove("DBUS_STARTER_BUS_TYPE");
env.remove("INVOCATION_ID");
env.remove("JOURNAL_STREAM");
// Unset environment varies set by snaps if we're running in a snap.
// This allows Ghostty to further launch additional snaps.
if (env.get("SNAP")) |_| {

View File

@@ -201,6 +201,16 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
b.path("dist/linux/app.desktop"),
"share/applications/com.mitchellh.ghostty.desktop",
).step);
// DBus service for DBus activation
try steps.append(&b.addInstallFile(
b.path("dist/linux/dbus.service"),
"share/dbus-1/services/com.mitchellh.ghostty.service",
).step);
// systemd user service
try steps.append(&b.addInstallFile(
b.path("dist/linux/systemd.service"),
"lib/systemd/user/com.mitchellh.ghostty.service",
).step);
// AppStream metainfo so that application has rich metadata within app stores
try steps.append(&b.addInstallFile(