mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-05-19 11:31:19 +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:
@@ -781,10 +781,7 @@ fn toggleQuickTerminal(self: *App) !bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!self.winproto.supportsQuickTerminal()) {
|
||||
log.err("quick terminal not supported on current platform", .{});
|
||||
return false;
|
||||
}
|
||||
if (!self.winproto.supportsQuickTerminal()) return false;
|
||||
|
||||
const qt = Window.create(self.core_app.alloc, self) catch |err| {
|
||||
log.err("failed to initialize quick terminal={}", .{err});
|
||||
|
||||
@@ -15,7 +15,6 @@ pub const c = @cImport({
|
||||
@cInclude("X11/XKBlib.h");
|
||||
}
|
||||
if (build_options.wayland) {
|
||||
if (build_options.layer_shell) @cInclude("gtk4-layer-shell/gtk4-layer-shell.h");
|
||||
@cInclude("gdk/wayland/gdkwayland.h");
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ const Allocator = std.mem.Allocator;
|
||||
|
||||
const build_options = @import("build_options");
|
||||
const wayland = @import("wayland");
|
||||
const gtk = @import("gtk");
|
||||
const gtk4_layer_shell = @import("gtk4-layer-shell");
|
||||
|
||||
const c = @import("../c.zig").c;
|
||||
const Config = @import("../../../config.zig").Config;
|
||||
@@ -90,17 +92,19 @@ pub const App = struct {
|
||||
}
|
||||
|
||||
pub fn supportsQuickTerminal(_: App) bool {
|
||||
if (comptime !build_options.layer_shell) return false;
|
||||
|
||||
return c.gtk_layer_is_supported() != 0;
|
||||
if (!gtk4_layer_shell.isSupported()) {
|
||||
log.warn("your compositor does not support the wlr-layer-shell protocol; disabling quick terminal", .{});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
pub fn initQuickTerminal(_: *App, apprt_window: *ApprtWindow) !void {
|
||||
if (comptime !build_options.layer_shell) unreachable;
|
||||
const window: *gtk.Window = @ptrCast(apprt_window.window);
|
||||
|
||||
c.gtk_layer_init_for_window(apprt_window.window);
|
||||
c.gtk_layer_set_layer(apprt_window.window, c.GTK_LAYER_SHELL_LAYER_TOP);
|
||||
c.gtk_layer_set_keyboard_mode(apprt_window.window, c.GTK_LAYER_SHELL_KEYBOARD_MODE_ON_DEMAND);
|
||||
gtk4_layer_shell.initForWindow(window);
|
||||
gtk4_layer_shell.setLayer(window, .top);
|
||||
gtk4_layer_shell.setKeyboardMode(window, .on_demand);
|
||||
}
|
||||
|
||||
fn registryListener(
|
||||
@@ -336,11 +340,10 @@ pub const Window = struct {
|
||||
}
|
||||
|
||||
fn syncQuickTerminal(self: *Window) !void {
|
||||
if (comptime !build_options.layer_shell) return;
|
||||
const window: *gtk.Window = @ptrCast(self.apprt_window.window);
|
||||
const position = self.apprt_window.config.quick_terminal_position;
|
||||
|
||||
const window = self.apprt_window.window;
|
||||
|
||||
const anchored_edge: ?LayerShellEdge = switch (self.apprt_window.config.quick_terminal_position) {
|
||||
const anchored_edge: ?gtk4_layer_shell.ShellEdge = switch (position) {
|
||||
.left => .left,
|
||||
.right => .right,
|
||||
.top => .top,
|
||||
@@ -348,23 +351,23 @@ pub const Window = struct {
|
||||
.center => null,
|
||||
};
|
||||
|
||||
for (std.meta.tags(LayerShellEdge)) |edge| {
|
||||
for (std.meta.tags(gtk4_layer_shell.ShellEdge)) |edge| {
|
||||
if (anchored_edge) |anchored| {
|
||||
if (edge == anchored) {
|
||||
c.gtk_layer_set_margin(window, @intFromEnum(edge), 0);
|
||||
c.gtk_layer_set_anchor(window, @intFromEnum(edge), @intFromBool(true));
|
||||
gtk4_layer_shell.setMargin(window, edge, 0);
|
||||
gtk4_layer_shell.setAnchor(window, edge, true);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Arbitrary margin - could be made customizable?
|
||||
c.gtk_layer_set_margin(window, @intFromEnum(edge), 20);
|
||||
c.gtk_layer_set_anchor(window, @intFromEnum(edge), @intFromBool(false));
|
||||
gtk4_layer_shell.setMargin(window, edge, 20);
|
||||
gtk4_layer_shell.setAnchor(window, edge, false);
|
||||
}
|
||||
|
||||
switch (self.apprt_window.config.quick_terminal_position) {
|
||||
.top, .bottom, .center => c.gtk_window_set_default_size(window, 800, 400),
|
||||
.left, .right => c.gtk_window_set_default_size(window, 400, 800),
|
||||
switch (position) {
|
||||
.top, .bottom, .center => window.setDefaultSize(800, 400),
|
||||
.left, .right => window.setDefaultSize(400, 800),
|
||||
}
|
||||
|
||||
if (self.apprt_window.isQuickTerminal()) {
|
||||
@@ -377,26 +380,18 @@ pub const Window = struct {
|
||||
log.warn("could not create slide object={}", .{err});
|
||||
break :slide null;
|
||||
};
|
||||
slide.setLocation(@intCast(@intFromEnum(anchored.toKdeSlideLocation())));
|
||||
|
||||
const slide_location: org.KdeKwinSlide.Location = switch (anchored) {
|
||||
.top => .top,
|
||||
.bottom => .bottom,
|
||||
.left => .left,
|
||||
.right => .right,
|
||||
};
|
||||
|
||||
slide.setLocation(@intCast(@intFromEnum(slide_location)));
|
||||
slide.commit();
|
||||
break :slide slide;
|
||||
} else null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const LayerShellEdge = 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,
|
||||
|
||||
fn toKdeSlideLocation(self: LayerShellEdge) org.KdeKwinSlide.Location {
|
||||
return switch (self) {
|
||||
.left => .left,
|
||||
.top => .top,
|
||||
.right => .right,
|
||||
.bottom => .bottom,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -150,6 +150,7 @@ pub const App = struct {
|
||||
}
|
||||
|
||||
pub fn supportsQuickTerminal(_: App) bool {
|
||||
log.warn("quick terminal is not yet supported on X11", .{});
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user