use cmake formatting to template, avoids the custom binary
parent
73d5eb928c
commit
739b691a6d
|
|
@ -1,15 +1,15 @@
|
|||
[Desktop Entry]
|
||||
Version=1.0
|
||||
Name=@@NAME@@
|
||||
Name=@NAME@
|
||||
Type=Application
|
||||
Comment=A terminal emulator
|
||||
TryExec=@@GHOSTTY@@
|
||||
Exec=@@GHOSTTY@@ --launched-from=desktop
|
||||
TryExec=@GHOSTTY@
|
||||
Exec=@GHOSTTY@ --launched-from=desktop
|
||||
Icon=com.mitchellh.ghostty
|
||||
Categories=System;TerminalEmulator;
|
||||
Keywords=terminal;tty;pty;
|
||||
StartupNotify=true
|
||||
StartupWMClass=@@APPID@@
|
||||
StartupWMClass=@APPID@
|
||||
Terminal=false
|
||||
Actions=new-window;
|
||||
X-GNOME-UsesNotifications=true
|
||||
|
|
@ -22,4 +22,4 @@ DBusActivatable=true
|
|||
|
||||
[Desktop Action new-window]
|
||||
Name=New Window
|
||||
Exec=@@GHOSTTY@@ --launched-from=desktop
|
||||
Exec=@GHOSTTY@ --launched-from=desktop
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<component type="desktop-application">
|
||||
<id>@@APPID@@</id>
|
||||
<launchable type="desktop-id">@@APPID@@.desktop</launchable>
|
||||
<name>@@NAME@@</name>
|
||||
<id>@APPID@id>
|
||||
<launchable type="desktop-id">@APPID@desktop</launchable>
|
||||
<name>@NAME@name>
|
||||
<url type="homepage">https://ghostty.org</url>
|
||||
<url type="help">https://ghostty.org/docs</url>
|
||||
<url type="bugtracker">https://github.com/ghostty-org/ghostty/discussions</url>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
[D-BUS Service]
|
||||
Name=@APPID@
|
||||
Exec=@GHOSTTY@ --launched-from=dbus
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
[D-BUS Service]
|
||||
Name=@@APPID@@
|
||||
SystemdService=@@APPID@@.service
|
||||
Exec=@@GHOSTTY@@ --launched-from=dbus
|
||||
Name=@APPID@
|
||||
SystemdService=@APPID@service
|
||||
Exec=@GHOSTTY@ --launched-from=dbus
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
[Unit]
|
||||
Description=@@NAME@@
|
||||
Description=@NAME@
|
||||
|
||||
[Service]
|
||||
Type=dbus
|
||||
BusName=@@APPID@@
|
||||
ExecStart=@@GHOSTTY@@ --launched-from=systemd
|
||||
BusName=@APPID@
|
||||
ExecStart=@GHOSTTY@ --launched-from=systemd
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ const GhosttyResources = @This();
|
|||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
const assert = std.debug.assert;
|
||||
const buildpkg = @import("main.zig");
|
||||
const Config = @import("Config.zig");
|
||||
const config_vim = @import("../config/vim.zig");
|
||||
|
|
@ -220,182 +221,176 @@ pub fn init(b: *std.Build, cfg: *const Config) !GhosttyResources {
|
|||
}
|
||||
|
||||
// App (Linux)
|
||||
if (cfg.target.result.os.tag == .linux) {
|
||||
// https://developer.gnome.org/documentation/guidelines/maintainer/integrating.html
|
||||
if (cfg.target.result.os.tag == .linux) try addLinuxAppResources(
|
||||
b,
|
||||
cfg,
|
||||
&steps,
|
||||
);
|
||||
|
||||
const name = b.fmt("Ghostty{s}", .{
|
||||
switch (cfg.optimize) {
|
||||
.Debug, .ReleaseSafe => " (Debug)",
|
||||
.ReleaseFast, .ReleaseSmall => "",
|
||||
},
|
||||
});
|
||||
return .{ .steps = steps.items };
|
||||
}
|
||||
|
||||
const app_id = b.fmt("com.mitchellh.ghostty{s}", .{
|
||||
switch (cfg.optimize) {
|
||||
.Debug, .ReleaseSafe => "-debug",
|
||||
.ReleaseFast, .ReleaseSmall => "",
|
||||
},
|
||||
});
|
||||
/// Add the resource files needed to make Ghostty a proper
|
||||
/// Linux desktop application (for various desktop environments).
|
||||
fn addLinuxAppResources(
|
||||
b: *std.Build,
|
||||
cfg: *const Config,
|
||||
steps: *std.ArrayList(*std.Build.Step),
|
||||
) !void {
|
||||
assert(cfg.target.result.os.tag == .linux);
|
||||
|
||||
// Background:
|
||||
// https://developer.gnome.org/documentation/guidelines/maintainer/integrating.html
|
||||
|
||||
const name = b.fmt("Ghostty{s}", .{
|
||||
switch (cfg.optimize) {
|
||||
.Debug, .ReleaseSafe => " (Debug)",
|
||||
.ReleaseFast, .ReleaseSmall => "",
|
||||
},
|
||||
});
|
||||
|
||||
const app_id = b.fmt("com.mitchellh.ghostty{s}", .{
|
||||
switch (cfg.optimize) {
|
||||
.Debug, .ReleaseSafe => "-debug",
|
||||
.ReleaseFast, .ReleaseSmall => "",
|
||||
},
|
||||
});
|
||||
|
||||
const exe_abs_path = b.fmt(
|
||||
"{s}/bin/ghostty",
|
||||
.{b.install_prefix},
|
||||
);
|
||||
|
||||
// The templates that we will process. The templates are in
|
||||
// cmake format and will be processed and saved to the
|
||||
// second element of the tuple.
|
||||
const Template = struct { std.Build.LazyPath, []const u8 };
|
||||
const templates: []const Template = templates: {
|
||||
var ts: std.ArrayList(Template) = .init(b.allocator);
|
||||
|
||||
// Desktop file so that we have an icon and other metadata
|
||||
try steps.append(
|
||||
formatService(
|
||||
b,
|
||||
cfg,
|
||||
name,
|
||||
app_id,
|
||||
b.path("dist/linux/app.desktop.in"),
|
||||
b.fmt(
|
||||
"share/applications/{s}.desktop",
|
||||
.{app_id},
|
||||
),
|
||||
),
|
||||
);
|
||||
try ts.append(.{
|
||||
b.path("dist/linux/app.desktop.in"),
|
||||
b.fmt("share/applications/{s}.desktop", .{app_id}),
|
||||
});
|
||||
|
||||
// Service for DBus activation.
|
||||
try steps.append(
|
||||
formatService(
|
||||
b,
|
||||
cfg,
|
||||
name,
|
||||
app_id,
|
||||
try ts.append(.{
|
||||
if (cfg.flatpak)
|
||||
b.path("dist/linux/dbus.service.flatpak.in")
|
||||
else
|
||||
b.path("dist/linux/dbus.service.in"),
|
||||
b.fmt(
|
||||
"share/dbus-1/services/{s}.service",
|
||||
.{app_id},
|
||||
),
|
||||
),
|
||||
);
|
||||
// systemd user service
|
||||
if (!cfg.flatpak)
|
||||
try steps.append(
|
||||
formatService(
|
||||
b,
|
||||
cfg,
|
||||
name,
|
||||
b.fmt("share/dbus-1/services/{s}.service", .{app_id}),
|
||||
});
|
||||
|
||||
// systemd user service. This is kind of nasty but systemd
|
||||
// looks for user services in different paths depending on
|
||||
// if we are installed as a system package or not (lib vs.
|
||||
// share) so we have to handle that here. We might be able
|
||||
// to get away with always installing to both because it
|
||||
// only ever searches in one... but I don't want to do that hack
|
||||
// until we have to.
|
||||
if (!cfg.flatpak) try ts.append(.{
|
||||
b.path("dist/linux/systemd.service.in"),
|
||||
b.fmt(
|
||||
"{s}/systemd/user/{s}.service",
|
||||
.{
|
||||
if (b.graph.system_package_mode) "lib" else "share",
|
||||
app_id,
|
||||
b.path("dist/linux/systemd.service.in"),
|
||||
b.fmt(
|
||||
"{s}/systemd/user/{s}.service",
|
||||
.{
|
||||
if (b.graph.system_package_mode) "lib" else "share",
|
||||
app_id,
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// AppStream metainfo so that application has rich metadata within app stores
|
||||
try steps.append(
|
||||
formatService(
|
||||
b,
|
||||
cfg,
|
||||
name,
|
||||
app_id,
|
||||
b.path("dist/linux/com.mitchellh.ghostty.metainfo.xml.in"),
|
||||
b.fmt(
|
||||
"share/metainfo/{s}.metainfo.xml",
|
||||
.{app_id},
|
||||
),
|
||||
},
|
||||
),
|
||||
});
|
||||
|
||||
// AppStream metainfo so that application has rich metadata
|
||||
// within app stores
|
||||
try ts.append(.{
|
||||
b.path("dist/linux/com.mitchellh.ghostty.metainfo.xml.in"),
|
||||
b.fmt("share/metainfo/{s}.metainfo.xml", .{app_id}),
|
||||
});
|
||||
|
||||
break :templates ts.items;
|
||||
};
|
||||
|
||||
// Process all our templates
|
||||
for (templates) |template| {
|
||||
const tpl = b.addConfigHeader(.{
|
||||
.style = .{ .cmake = template[0] },
|
||||
}, .{
|
||||
.NAME = name,
|
||||
.APPID = app_id,
|
||||
.GHOSTTY = exe_abs_path,
|
||||
});
|
||||
|
||||
const copy = b.addInstallFile(
|
||||
tpl.getOutput(),
|
||||
template[1],
|
||||
);
|
||||
|
||||
// Right click menu action for Plasma desktop
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("dist/linux/ghostty_dolphin.desktop"),
|
||||
"share/kio/servicemenus/com.mitchellh.ghostty.desktop",
|
||||
).step);
|
||||
try steps.append(©.step);
|
||||
}
|
||||
|
||||
// Right click menu action for Nautilus. Note that this _must_ be named
|
||||
// `ghostty.py`. Using the full app id causes problems (see #5468).
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("dist/linux/ghostty_nautilus.py"),
|
||||
"share/nautilus-python/extensions/ghostty.py",
|
||||
).step);
|
||||
// Right click menu action for Plasma desktop
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("dist/linux/ghostty_dolphin.desktop"),
|
||||
"share/kio/servicemenus/com.mitchellh.ghostty.desktop",
|
||||
).step);
|
||||
|
||||
// Various icons that our application can use, including the icon
|
||||
// that will be used for the desktop.
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_16.png"),
|
||||
"share/icons/hicolor/16x16/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_32.png"),
|
||||
"share/icons/hicolor/32x32/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_128.png"),
|
||||
"share/icons/hicolor/128x128/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_256.png"),
|
||||
"share/icons/hicolor/256x256/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_512.png"),
|
||||
"share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
// Flatpaks only support icons up to 512x512.
|
||||
if (!cfg.flatpak) {
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_1024.png"),
|
||||
"share/icons/hicolor/1024x1024/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
}
|
||||
// Right click menu action for Nautilus. Note that this _must_ be named
|
||||
// `ghostty.py`. Using the full app id causes problems (see #5468).
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("dist/linux/ghostty_nautilus.py"),
|
||||
"share/nautilus-python/extensions/ghostty.py",
|
||||
).step);
|
||||
|
||||
// Various icons that our application can use, including the icon
|
||||
// that will be used for the desktop.
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_16.png"),
|
||||
"share/icons/hicolor/16x16/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_32.png"),
|
||||
"share/icons/hicolor/32x32/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_128.png"),
|
||||
"share/icons/hicolor/128x128/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_256.png"),
|
||||
"share/icons/hicolor/256x256/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_512.png"),
|
||||
"share/icons/hicolor/512x512/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
// Flatpaks only support icons up to 512x512.
|
||||
if (!cfg.flatpak) {
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_16@2x.png"),
|
||||
"share/icons/hicolor/16x16@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_32@2x.png"),
|
||||
"share/icons/hicolor/32x32@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_128@2x.png"),
|
||||
"share/icons/hicolor/128x128@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_256@2x.png"),
|
||||
"share/icons/hicolor/256x256@2/apps/com.mitchellh.ghostty.png",
|
||||
b.path("images/icons/icon_1024.png"),
|
||||
"share/icons/hicolor/1024x1024/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
}
|
||||
|
||||
return .{ .steps = steps.items };
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_16@2x.png"),
|
||||
"share/icons/hicolor/16x16@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_32@2x.png"),
|
||||
"share/icons/hicolor/32x32@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_128@2x.png"),
|
||||
"share/icons/hicolor/128x128@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
try steps.append(&b.addInstallFile(
|
||||
b.path("images/icons/icon_256@2x.png"),
|
||||
"share/icons/hicolor/256x256@2/apps/com.mitchellh.ghostty.png",
|
||||
).step);
|
||||
}
|
||||
|
||||
pub fn install(self: *const GhosttyResources) void {
|
||||
const b = self.steps[0].owner;
|
||||
for (self.steps) |step| b.getInstallStep().dependOn(step);
|
||||
}
|
||||
|
||||
pub fn formatService(
|
||||
b: *std.Build,
|
||||
cfg: *const Config,
|
||||
name: []const u8,
|
||||
app_id: []const u8,
|
||||
src: std.Build.LazyPath,
|
||||
dest: []const u8,
|
||||
) *std.Build.Step {
|
||||
var cmd = b.addExecutable(
|
||||
.{
|
||||
.name = "desktop-template",
|
||||
.root_source_file = b.path("src/build/desktop_template.zig"),
|
||||
.target = b.graph.host,
|
||||
},
|
||||
);
|
||||
|
||||
const options = b.addOptions();
|
||||
|
||||
options.addOption([]const u8, "app_id", app_id);
|
||||
options.addOption([]const u8, "name", name);
|
||||
options.addOption([]const u8, "ghostty", b.fmt("{s}/bin/ghostty", .{b.install_prefix}));
|
||||
options.addOption(bool, "flatpak", cfg.flatpak);
|
||||
|
||||
cmd.root_module.addOptions("cfg", options);
|
||||
|
||||
const run = b.addRunArtifact(cmd);
|
||||
run.setStdIn(.{ .lazy_path = src });
|
||||
const output = run.captureStdOut();
|
||||
|
||||
return &b.addInstallFile(output, dest).step;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +0,0 @@
|
|||
const std = @import("std");
|
||||
const cfg = @import("cfg");
|
||||
|
||||
pub fn main() !void {
|
||||
var debug: std.heap.DebugAllocator(.{}) = .init;
|
||||
defer _ = debug.deinit();
|
||||
|
||||
const alloc = debug.allocator();
|
||||
|
||||
const stdin = std.io.getStdIn();
|
||||
const stdout = std.io.getStdOut();
|
||||
var input = stdin.reader();
|
||||
|
||||
while (try input.readUntilDelimiterOrEofAlloc(alloc, '\n', 4096)) |line| {
|
||||
defer alloc.free(line);
|
||||
|
||||
const buf1 = try std.mem.replaceOwned(u8, alloc, line, "@@APPID@@", cfg.app_id);
|
||||
defer alloc.free(buf1);
|
||||
|
||||
const buf2 = try std.mem.replaceOwned(u8, alloc, buf1, "@@NAME@@", cfg.name);
|
||||
defer alloc.free(buf2);
|
||||
|
||||
const buf3 = try std.mem.replaceOwned(u8, alloc, buf2, "@@GHOSTTY@@", cfg.ghostty);
|
||||
defer alloc.free(buf3);
|
||||
|
||||
if (cfg.flatpak and std.mem.startsWith(u8, buf3, "SystemdService=")) continue;
|
||||
|
||||
try stdout.writeAll(buf3);
|
||||
try stdout.writeAll("\n");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue