Skip to content

Commit

Permalink
gtk: add option to not link against libX11
Browse files Browse the repository at this point in the history
  • Loading branch information
jcollie committed Dec 28, 2024
1 parent 6cbd69d commit 814e58b
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 24 deletions.
6 changes: 6 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ pub fn build(b: *std.Build) !void {
"Enables the use of Adwaita when using the GTK rendering backend.",
) orelse true;

config.x11 = b.option(
bool,
"gtk-x11",
"Enables the linking against X11 libraries when using the GTK rendering backend.",
) orelse true;

const pie = b.option(
bool,
"pie",
Expand Down
26 changes: 18 additions & 8 deletions nix/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
pandoc,
revision ? "dirty",
optimize ? "Debug",
x11 ? false,
}: let
# The Zig hook has no way to select the release type without actual
# overriding of the default flags.
Expand Down Expand Up @@ -136,15 +137,16 @@ in
oniguruma
zlib

libX11
libXcursor
libXi
libXrandr

libadwaita
gtk4
glib
gsettings-desktop-schemas
]
++ lib.optionals x11 [
libX11
libXcursor
libXi
libXrandr
];

dontConfigure = true;
Expand All @@ -157,7 +159,12 @@ in
chmod u+rwX -R $ZIG_GLOBAL_CACHE_DIR
'';

outputs = ["out" "terminfo" "shell_integration" "vim"];
outputs = [
"out"
"terminfo"
"shell_integration"
"vim"
];

postInstall = ''
terminfo_src=${
Expand All @@ -183,14 +190,17 @@ in
echo "$vim" >> "$out/nix-support/propagated-user-env-packages"
'';

postFixup = ''
postFixup = lib.optionalString x11 ''
patchelf --add-rpath "${lib.makeLibraryPath [libX11]}" "$out/bin/.ghostty-wrapped"
'';

meta = {
homepage = "https://github.com/ghostty-org/ghostty";
license = lib.licenses.mit;
platforms = ["x86_64-linux" "aarch64-linux"];
platforms = [
"x86_64-linux"
"aarch64-linux"
];
mainProgram = "ghostty";
};
})
2 changes: 2 additions & 0 deletions src/apprt/gtk/App.zig
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const builtin = @import("builtin");
const build_config = @import("../../build_config.zig");
const build_options = @import("build_options");
const apprt = @import("../../apprt.zig");
const configpkg = @import("../../config.zig");
const input = @import("../../input.zig");
Expand Down Expand Up @@ -360,6 +361,7 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
// keyboard state but the block does more than that (i.e. setting up
// WM_CLASS).
const x11_xkb: ?x11.Xkb = x11_xkb: {
if (comptime !build_options.x11) break :x11_xkb null;
if (!x11.is_display(display)) break :x11_xkb null;

// Set the X11 window class property (WM_CLASS) if are are on an X11
Expand Down
1 change: 1 addition & 0 deletions src/apprt/gtk/Surface.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const Surface = @This();
const std = @import("std");
const Allocator = std.mem.Allocator;
const build_config = @import("../../build_config.zig");
const build_options = @import("build_options");
const configpkg = @import("../../config.zig");
const apprt = @import("../../apprt.zig");
const font = @import("../../font/main.zig");
Expand Down
12 changes: 9 additions & 3 deletions src/apprt/gtk/c.zig
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
const build_options = @import("build_options");

/// Imported C API directly from header files
pub const c = @cImport({
@cInclude("gtk/gtk.h");
if (@import("build_options").adwaita) {
if (build_options.adwaita) {
@cInclude("libadwaita-1/adwaita.h");
}

// Add in X11-specific GDK backend which we use for specific things
// (e.g. X11 window class).
@cInclude("gdk/x11/gdkx.h");
if (build_options.x11) {
@cInclude("gdk/x11/gdkx.h");
}
// Xkb for X11 state handling
@cInclude("X11/XKBlib.h");
if (build_options.x11) {
@cInclude("X11/XKBlib.h");
}

// generated header files
@cInclude("ghostty_resources.h");
Expand Down
8 changes: 8 additions & 0 deletions src/apprt/gtk/ghostty_gtk_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,11 @@
#ifndef G_APPLICATION_DEFAULT_FLAGS
#define G_APPLICATION_DEFAULT_FLAGS G_APPLICATION_FLAGS_NONE
#endif

#ifndef False
#define False 0
#endif

#ifndef True
#define True 1
#endif
27 changes: 16 additions & 11 deletions src/apprt/gtk/key.zig
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const std = @import("std");
const build_options = @import("build_options");
const input = @import("../../input.zig");
const c = @import("c.zig").c;
const x11 = @import("x11.zig");
Expand Down Expand Up @@ -111,21 +112,25 @@ pub fn eventMods(
x11_xkb: ?*x11.Xkb,
) input.Mods {
const device = c.gdk_event_get_device(event);
const display = c.gtk_widget_get_display(widget);

var mods = if (x11_xkb) |xkb|
// Add any modifier state events from Xkb if we have them (X11
// only). Null back from the Xkb call means there was no modifier
// event to read. This likely means that the key event did not
// result in a modifier change and we can safely rely on the GDK
// state.
xkb.modifier_state_from_notify(display) orelse
translateMods(gtk_mods)
else
var mods = mods: {
if (build_options.x11) {
const display = c.gtk_widget_get_display(widget);
if (x11_xkb) |xkb| {
// Add any modifier state events from Xkb if we have them (X11
// only). Null back from the Xkb call means there was no modifier
// event to read. This likely means that the key event did not
// result in a modifier change and we can safely rely on the GDK
// state.
if (xkb.modifier_state_from_notify(display)) |x11_mods| break :mods x11_mods;
break :mods translateMods(gtk_mods);
}
}
// On Wayland, we have to use the GDK device because the mods sent
// to this event do not have the modifier key applied if it was
// presssed (i.e. left control).
translateMods(c.gdk_device_get_modifier_state(device));
break :mods translateMods(c.gdk_device_get_modifier_state(device));
};

mods.num_lock = c.gdk_device_get_num_lock_state(device) == 1;

Expand Down
7 changes: 5 additions & 2 deletions src/apprt/gtk/x11.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/// Utility functions for X11 handling.
const std = @import("std");
const build_options = @import("build_options");
const c = @import("c.zig").c;
const input = @import("../../input.zig");

const log = std.log.scoped(.gtk_x11);

/// Returns true if the passed in display is an X11 display.
pub fn is_display(display: ?*c.GdkDisplay) bool {
if (comptime !build_options.x11) return false;
return c.g_type_check_instance_is_a(
@ptrCast(@alignCast(display orelse return false)),
c.gdk_x11_display_get_type(),
Expand All @@ -15,11 +17,12 @@ pub fn is_display(display: ?*c.GdkDisplay) bool {

/// Returns true if the app is running on X11
pub fn is_current_display_server() bool {
if (comptime !build_options.x11) return false;
const display = c.gdk_display_get_default();
return is_display(display);
}

pub const Xkb = struct {
pub const Xkb = if (build_options.x11) struct {
base_event_code: c_int,
funcs: Funcs,

Expand Down Expand Up @@ -111,7 +114,7 @@ pub const Xkb = struct {

return mods;
}
};
} else struct {};

/// The functions that we load dynamically from libX11.so.
const Funcs = struct {
Expand Down
2 changes: 2 additions & 0 deletions src/build_config.zig
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub const BuildConfig = struct {
version: std.SemanticVersion = .{ .major = 0, .minor = 0, .patch = 0 },
flatpak: bool = false,
adwaita: bool = false,
x11: bool = false,
app_runtime: apprt.Runtime = .none,
renderer: rendererpkg.Impl = .opengl,
font_backend: font.Backend = .freetype,
Expand All @@ -41,6 +42,7 @@ pub const BuildConfig = struct {
// support all types.
step.addOption(bool, "flatpak", self.flatpak);
step.addOption(bool, "adwaita", self.adwaita);
step.addOption(bool, "x11", self.x11);
step.addOption(apprt.Runtime, "app_runtime", self.app_runtime);
step.addOption(font.Backend, "font_backend", self.font_backend);
step.addOption(rendererpkg.Impl, "renderer", self.renderer);
Expand Down

0 comments on commit 814e58b

Please sign in to comment.