mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-25 08:43:55 +00:00
gtk: build gtk4-layer-shell ourselves
As of now `gtk4-layer-shell` is unavailable on recent, stable releases of many distros (Debian 12, Ubuntu 24.04, openSUSE Leap & Tumbleweed, etc.) and outdated on many others (Nixpkgs 24.11/unstable, Fedora 41, etc.) This is inconvenient for our users and severely limits where the quick terminal can be used. As a result we then build gtk4-layer-shell ourselves by default unless `--system` or `-fsys=gtk4-layer-shell` are specified. This also allows me to add an idiomatic Zig API on top of the library and avoiding adding even more raw C code in the GTK apprt. Since we now build gtk4-layer-shell it should be theoretically available on all Linux systems we target. As such, the `-Dgtk-layer-shell` build option has been removed. This is somewhat of an experimental change as I don't know if gtk4-layer-shell works perfectly across all distros, and we can always add the option back if need be.
This commit is contained in:
106
pkg/gtk4-layer-shell/build.zig
Normal file
106
pkg/gtk4-layer-shell/build.zig
Normal file
@@ -0,0 +1,106 @@
|
||||
const std = @import("std");
|
||||
|
||||
// TODO: Import this from build.zig.zon when possible
|
||||
const version: std.SemanticVersion = .{ .major = 1, .minor = 1, .patch = 0 };
|
||||
|
||||
pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const upstream = b.dependency("gtk4_layer_shell", .{});
|
||||
const wayland_protocols = b.dependency("wayland_protocols", .{});
|
||||
|
||||
// Zig API
|
||||
const module = b.addModule("gtk4-layer-shell", .{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
module.addIncludePath(upstream.path("include"));
|
||||
// Needs the gtk.h header
|
||||
module.linkSystemLibrary("gtk4", dynamic_link_opts);
|
||||
|
||||
// Shared library
|
||||
const lib = b.addSharedLibrary(.{
|
||||
.name = "gtk4-layer-shell",
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
lib.linkLibC();
|
||||
lib.addIncludePath(upstream.path("include"));
|
||||
lib.addIncludePath(upstream.path("src"));
|
||||
|
||||
// GTK
|
||||
lib.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||
|
||||
// Wayland headers and source files
|
||||
{
|
||||
const protocols = [_]struct { []const u8, std.Build.LazyPath }{
|
||||
.{
|
||||
"wlr-layer-shell-unstable-v1",
|
||||
upstream.path("protocol/wlr-layer-shell-unstable-v1.xml"),
|
||||
},
|
||||
.{
|
||||
"xdg-shell",
|
||||
wayland_protocols.path("stable/xdg-shell/xdg-shell.xml"),
|
||||
},
|
||||
// Even though we don't use session lock, we still need its headers
|
||||
.{
|
||||
"ext-session-lock-v1",
|
||||
wayland_protocols.path("staging/ext-session-lock/ext-session-lock-v1.xml"),
|
||||
},
|
||||
};
|
||||
|
||||
const wf = b.addWriteFiles();
|
||||
for (protocols) |protocol| {
|
||||
const name, const xml = protocol;
|
||||
|
||||
const header_scanner = b.addSystemCommand(&.{ "wayland-scanner", "client-header" });
|
||||
header_scanner.addFileArg(xml);
|
||||
_ = wf.addCopyFile(
|
||||
header_scanner.addOutputFileArg(name),
|
||||
b.fmt("{s}-client.h", .{name}),
|
||||
);
|
||||
|
||||
const source_scanner = b.addSystemCommand(&.{ "wayland-scanner", "private-code" });
|
||||
source_scanner.addFileArg(xml);
|
||||
const source = source_scanner.addOutputFileArg(b.fmt("{s}.c", .{name}));
|
||||
lib.addCSourceFile(.{ .file = source });
|
||||
}
|
||||
lib.addIncludePath(wf.getDirectory());
|
||||
}
|
||||
|
||||
lib.installHeadersDirectory(
|
||||
upstream.path("include"),
|
||||
"",
|
||||
.{ .include_extensions = &.{".h"} },
|
||||
);
|
||||
|
||||
lib.addCSourceFiles(.{
|
||||
.root = upstream.path("src"),
|
||||
.files = srcs,
|
||||
.flags = &.{
|
||||
b.fmt("-DGTK_LAYER_SHELL_MAJOR={}", .{version.major}),
|
||||
b.fmt("-DGTK_LAYER_SHELL_MINOR={}", .{version.minor}),
|
||||
b.fmt("-DGTK_LAYER_SHELL_MICRO={}", .{version.patch}),
|
||||
},
|
||||
});
|
||||
|
||||
b.installArtifact(lib);
|
||||
}
|
||||
|
||||
// Certain files relating to session lock were removed as we don't use them
|
||||
const srcs: []const []const u8 = &.{
|
||||
"gtk4-layer-shell.c",
|
||||
"layer-surface.c",
|
||||
"libwayland-shim.c",
|
||||
"registry.c",
|
||||
"stolen-from-libwayland.c",
|
||||
"stubbed-surface.c",
|
||||
"xdg-surface-server.c",
|
||||
};
|
||||
|
||||
const dynamic_link_opts: std.Build.Module.LinkSystemLibraryOptions = .{
|
||||
.preferred_link_mode = .dynamic,
|
||||
.search_strategy = .mode_first,
|
||||
};
|
||||
15
pkg/gtk4-layer-shell/build.zig.zon
Normal file
15
pkg/gtk4-layer-shell/build.zig.zon
Normal file
@@ -0,0 +1,15 @@
|
||||
.{
|
||||
.name = "gtk4-layer-shell",
|
||||
.version = "1.1.0",
|
||||
.paths = .{""},
|
||||
.dependencies = .{
|
||||
.gtk4_layer_shell = .{
|
||||
.url = "https://github.com/wmww/gtk4-layer-shell/archive/refs/tags/v1.1.0.tar.gz",
|
||||
.hash = "12203eff4829ad8afdd828eb323d48e5ba8dbb44d224e9e314d4ab1533c2bec20f4b",
|
||||
},
|
||||
.wayland_protocols = .{
|
||||
.url = "https://deps.files.ghostty.org/wayland-protocols-258d8f88f2c8c25a830c6316f87d23ce1a0f12d9.tar.gz",
|
||||
.hash = "12201a57c6ce0001aa034fa80fba3e1cd2253c560a45748f4f4dd21ff23b491cddef",
|
||||
},
|
||||
},
|
||||
}
|
||||
48
pkg/gtk4-layer-shell/src/main.zig
Normal file
48
pkg/gtk4-layer-shell/src/main.zig
Normal file
@@ -0,0 +1,48 @@
|
||||
const c = @cImport({
|
||||
@cInclude("gtk4-layer-shell.h");
|
||||
});
|
||||
const gtk = @import("gtk");
|
||||
|
||||
pub const ShellLayer = enum(c_uint) {
|
||||
background = c.GTK_LAYER_SHELL_LAYER_BACKGROUND,
|
||||
bottom = c.GTK_LAYER_SHELL_LAYER_BOTTOM,
|
||||
top = c.GTK_LAYER_SHELL_LAYER_TOP,
|
||||
overlay = c.GTK_LAYER_SHELL_LAYER_OVERLAY,
|
||||
};
|
||||
|
||||
pub const ShellEdge = enum(c_uint) {
|
||||
left = c.GTK_LAYER_SHELL_EDGE_LEFT,
|
||||
right = c.GTK_LAYER_SHELL_EDGE_RIGHT,
|
||||
top = c.GTK_LAYER_SHELL_EDGE_TOP,
|
||||
bottom = c.GTK_LAYER_SHELL_EDGE_BOTTOM,
|
||||
};
|
||||
|
||||
pub const KeyboardMode = enum(c_uint) {
|
||||
none = c.GTK_LAYER_SHELL_KEYBOARD_MODE_NONE,
|
||||
exclusive = c.GTK_LAYER_SHELL_KEYBOARD_MODE_EXCLUSIVE,
|
||||
on_demand = c.GTK_LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND,
|
||||
};
|
||||
|
||||
pub fn isSupported() bool {
|
||||
return c.gtk_layer_is_supported() != 0;
|
||||
}
|
||||
|
||||
pub fn initForWindow(window: *gtk.Window) void {
|
||||
c.gtk_layer_init_for_window(@ptrCast(window));
|
||||
}
|
||||
|
||||
pub fn setLayer(window: *gtk.Window, layer: ShellLayer) void {
|
||||
c.gtk_layer_set_layer(@ptrCast(window), @intFromEnum(layer));
|
||||
}
|
||||
|
||||
pub fn setAnchor(window: *gtk.Window, edge: ShellEdge, anchor_to_edge: bool) void {
|
||||
c.gtk_layer_set_anchor(@ptrCast(window), @intFromEnum(edge), @intFromBool(anchor_to_edge));
|
||||
}
|
||||
|
||||
pub fn setMargin(window: *gtk.Window, edge: ShellEdge, margin_size: c_int) void {
|
||||
c.gtk_layer_set_margin(@ptrCast(window), @intFromEnum(edge), margin_size);
|
||||
}
|
||||
|
||||
pub fn setKeyboardMode(window: *gtk.Window, mode: KeyboardMode) void {
|
||||
c.gtk_layer_set_keyboard_mode(@ptrCast(window), @intFromEnum(mode));
|
||||
}
|
||||
Reference in New Issue
Block a user