mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-08-02 14:57:31 +03:00
gtk: get 'Change Title' working with older distros
This commit is contained in:
@ -25,7 +25,7 @@ pub fn init(comptime name: []const u8, comptime kind: enum { blp, ui }) Builder
|
||||
// GResource.
|
||||
const gresource = @import("gresource.zig");
|
||||
for (gresource.blueprint_files) |blueprint_file| {
|
||||
if (std.mem.eql(u8, blueprint_file, name)) break;
|
||||
if (std.mem.eql(u8, blueprint_file.name, name)) break;
|
||||
} else @compileError("missing blueprint file '" ++ name ++ "' in gresource.zig");
|
||||
},
|
||||
.ui => {
|
||||
|
@ -31,6 +31,7 @@ const inspector = @import("inspector.zig");
|
||||
const gtk_key = @import("key.zig");
|
||||
const c = @import("c.zig").c;
|
||||
const Builder = @import("Builder.zig");
|
||||
const adwaita = @import("adwaita.zig");
|
||||
|
||||
const log = std.log.scoped(.gtk_surface);
|
||||
|
||||
@ -1020,16 +1021,17 @@ fn resolveTitle(self: *Surface, title: [:0]const u8) [:0]const u8 {
|
||||
}
|
||||
|
||||
pub fn promptTitle(self: *Surface) !void {
|
||||
if (!adwaita.versionAtLeast(1, 5, 0)) return;
|
||||
const window = self.container.window() orelse return;
|
||||
|
||||
var builder = Builder.init("prompt-title-dialog", .blp);
|
||||
defer builder.deinit();
|
||||
|
||||
const entry: *gtk.Entry = @ptrCast(builder.getObject("title_entry"));
|
||||
const entry = gobject.ext.cast(gtk.Entry, builder.getObject("title_entry").?).?;
|
||||
entry.getBuffer().setText(self.getTitle() orelse "", -1);
|
||||
|
||||
const dialog: *adw.AlertDialog = @ptrCast(builder.getObject("prompt_title_dialog"));
|
||||
dialog.choose(@ptrCast(window.window), null, >kPromptTitleResponse, self);
|
||||
const dialog = gobject.ext.cast(adw.AlertDialog, builder.getObject("prompt_title_dialog").?).?;
|
||||
dialog.choose(@ptrCast(window.window), null, gtkPromptTitleResponse, self);
|
||||
}
|
||||
|
||||
/// Set the current working directory of the surface.
|
||||
@ -2320,12 +2322,13 @@ fn g_value_holds(value_: ?*c.GValue, g_type: c.GType) bool {
|
||||
}
|
||||
|
||||
fn gtkPromptTitleResponse(source_object: ?*gobject.Object, result: *gio.AsyncResult, ud: ?*anyopaque) callconv(.C) void {
|
||||
const dialog: *adw.AlertDialog = @ptrCast(source_object.?);
|
||||
const self = userdataSelf(ud.?);
|
||||
if (!adwaita.versionAtLeast(1, 5, 0)) return;
|
||||
const dialog = gobject.ext.cast(adw.AlertDialog, source_object.?).?;
|
||||
const self = userdataSelf(ud orelse return);
|
||||
|
||||
const response = dialog.chooseFinish(result);
|
||||
if (std.mem.orderZ(u8, "ok", response) == .eq) {
|
||||
const title_entry: *gtk.Entry = gobject.ext.cast(gtk.Entry, dialog.getExtraChild().?).?;
|
||||
const title_entry = gobject.ext.cast(gtk.Entry, dialog.getExtraChild().?).?;
|
||||
const title = std.mem.span(title_entry.getBuffer().getText());
|
||||
|
||||
// if the new title is empty and the user has set the title previously, restore the terminal provided title
|
||||
|
57
src/apprt/gtk/blueprint_compiler.zig
Normal file
57
src/apprt/gtk/blueprint_compiler.zig
Normal file
@ -0,0 +1,57 @@
|
||||
const std = @import("std");
|
||||
|
||||
pub const c = @cImport({
|
||||
@cInclude("adwaita.h");
|
||||
});
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
const alloc = gpa.allocator();
|
||||
|
||||
var it = try std.process.argsWithAllocator(alloc);
|
||||
defer it.deinit();
|
||||
|
||||
_ = it.next();
|
||||
|
||||
const major = try std.fmt.parseUnsigned(u8, it.next() orelse return error.NoMajorVersion, 10);
|
||||
const minor = try std.fmt.parseUnsigned(u8, it.next() orelse return error.NoMinorVersion, 10);
|
||||
const micro = try std.fmt.parseUnsigned(u8, it.next() orelse return error.NoMicroVersion, 10);
|
||||
const output = it.next() orelse return error.NoOutput;
|
||||
const input = it.next() orelse return error.NoInput;
|
||||
|
||||
if (c.ADW_MAJOR_VERSION < major or
|
||||
(c.ADW_MAJOR_VERSION == major and c.ADW_MINOR_VERSION < minor) or
|
||||
(c.ADW_MAJOR_VERSION == major and c.ADW_MINOR_VERSION == minor and c.ADW_MICRO_VERSION < micro))
|
||||
{
|
||||
// If the Adwaita version is too old, generate an "empty" file.
|
||||
const file = try std.fs.createFileAbsolute(output, .{
|
||||
.truncate = true,
|
||||
});
|
||||
try file.writeAll(
|
||||
\\<?xml version="1.0" encoding="UTF-8"?>
|
||||
\\<interface domain="com.mitchellh.ghostty"/>
|
||||
);
|
||||
defer file.close();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
var compiler = std.process.Child.init(
|
||||
&.{
|
||||
"blueprint-compiler",
|
||||
"compile",
|
||||
"--output",
|
||||
output,
|
||||
input,
|
||||
},
|
||||
alloc,
|
||||
);
|
||||
|
||||
const term = try compiler.spawnAndWait();
|
||||
switch (term) {
|
||||
.Exited => |rc| {
|
||||
if (rc != 0) std.posix.exit(1);
|
||||
},
|
||||
else => std.posix.exit(1),
|
||||
}
|
||||
}
|
@ -57,7 +57,17 @@ pub const ui_files = [_][]const u8{
|
||||
"menu-window-titlebar_menu",
|
||||
"menu-surface-context_menu",
|
||||
};
|
||||
pub const blueprint_files = [_][]const u8{"prompt-title-dialog"};
|
||||
|
||||
pub const VersionedBlueprint = struct {
|
||||
major: u16,
|
||||
minor: u16,
|
||||
micro: u16,
|
||||
name: []const u8,
|
||||
};
|
||||
|
||||
pub const blueprint_files = [_]VersionedBlueprint{
|
||||
.{ .major = 1, .minor = 5, .micro = 0, .name = "prompt-title-dialog" },
|
||||
};
|
||||
|
||||
pub fn main() !void {
|
||||
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
|
||||
@ -72,9 +82,9 @@ pub fn main() !void {
|
||||
var it = try std.process.argsWithAllocator(alloc);
|
||||
defer it.deinit();
|
||||
|
||||
while (it.next()) |filename| {
|
||||
if (std.mem.eql(u8, std.fs.path.extension(filename), ".ui")) {
|
||||
try extra_ui_files.append(try alloc.dupe(u8, filename));
|
||||
while (it.next()) |argument| {
|
||||
if (std.mem.eql(u8, std.fs.path.extension(argument), ".ui")) {
|
||||
try extra_ui_files.append(try alloc.dupe(u8, argument));
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,7 +154,7 @@ pub const dependencies = deps: {
|
||||
index += 1;
|
||||
}
|
||||
for (blueprint_files) |blueprint_file| {
|
||||
deps[index] = std.fmt.comptimePrint("src/apprt/gtk/ui/{s}.blp", .{blueprint_file});
|
||||
deps[index] = std.fmt.comptimePrint("src/apprt/gtk/ui/{s}.blp", .{blueprint_file.name});
|
||||
index += 1;
|
||||
}
|
||||
break :deps deps;
|
||||
|
@ -6,8 +6,8 @@ Adw.AlertDialog prompt_title_dialog {
|
||||
body: _("Leave blank to restore the default title.");
|
||||
|
||||
responses [
|
||||
cancel: _("Cancel"),
|
||||
ok: _("OK") suggested
|
||||
cancel: _("Cancel") suggested,
|
||||
ok: _("OK") destructive
|
||||
]
|
||||
|
||||
focus-widget: title_entry;
|
||||
|
@ -443,6 +443,7 @@ pub fn add(
|
||||
.{ "glib", "glib2" },
|
||||
.{ "gtk", "gtk4" },
|
||||
.{ "gdk", "gdk4" },
|
||||
.{ "adw", "adw1" },
|
||||
};
|
||||
inline for (gobject_imports) |import| {
|
||||
const name, const module = import;
|
||||
@ -451,7 +452,6 @@ pub fn add(
|
||||
|
||||
step.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||
step.linkSystemLibrary2("libadwaita-1", dynamic_link_opts);
|
||||
step.root_module.addImport("adw", gobject.module("adw1"));
|
||||
|
||||
if (self.config.x11) {
|
||||
step.linkSystemLibrary2("X11", dynamic_link_opts);
|
||||
@ -500,14 +500,24 @@ pub fn add(
|
||||
|
||||
const generate = b.addRunArtifact(generate_gresource_xml);
|
||||
|
||||
const gtk_blueprint_compiler = b.addExecutable(.{
|
||||
.name = "gtk_blueprint_compiler",
|
||||
.root_source_file = b.path("src/apprt/gtk/blueprint_compiler.zig"),
|
||||
.target = b.host,
|
||||
});
|
||||
gtk_blueprint_compiler.linkSystemLibrary2("gtk4", dynamic_link_opts);
|
||||
gtk_blueprint_compiler.linkSystemLibrary2("libadwaita-1", dynamic_link_opts);
|
||||
gtk_blueprint_compiler.linkLibC();
|
||||
|
||||
for (gresource.blueprint_files) |blueprint_file| {
|
||||
const blueprint_compiler = b.addSystemCommand(&.{
|
||||
"blueprint-compiler",
|
||||
"compile",
|
||||
"--output",
|
||||
const blueprint_compiler = b.addRunArtifact(gtk_blueprint_compiler);
|
||||
blueprint_compiler.addArgs(&.{
|
||||
b.fmt("{d}", .{blueprint_file.major}),
|
||||
b.fmt("{d}", .{blueprint_file.minor}),
|
||||
b.fmt("{d}", .{blueprint_file.micro}),
|
||||
});
|
||||
const ui_file = blueprint_compiler.addOutputFileArg(b.fmt("{s}.ui", .{blueprint_file}));
|
||||
blueprint_compiler.addFileArg(b.path(b.fmt("src/apprt/gtk/ui/{s}.blp", .{blueprint_file})));
|
||||
const ui_file = blueprint_compiler.addOutputFileArg(b.fmt("{s}.ui", .{blueprint_file.name}));
|
||||
blueprint_compiler.addFileArg(b.path(b.fmt("src/apprt/gtk/ui/{s}.blp", .{blueprint_file.name})));
|
||||
generate.addFileArg(ui_file);
|
||||
}
|
||||
|
||||
|
@ -5,9 +5,11 @@ FROM docker.io/library/debian:${DISTRO_VERSION}
|
||||
RUN DEBIAN_FRONTEND="noninteractive" apt-get -qq update && \
|
||||
apt-get -qq -y --no-install-recommends install \
|
||||
# Build Tools
|
||||
blueprint-compiler \
|
||||
build-essential \
|
||||
libbz2-dev \
|
||||
libonig-dev \
|
||||
libxml2-utils \
|
||||
lintian \
|
||||
lsb-release \
|
||||
libxml2-utils \
|
||||
|
Reference in New Issue
Block a user