mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-19 10:16:12 +03:00
apprt/gtk-ng: hook up all the bindings for the config errors dialog
This commit is contained in:
@ -21,6 +21,7 @@ const adw_version = @import("../adw_version.zig");
|
||||
const gtk_version = @import("../gtk_version.zig");
|
||||
const GhosttyConfig = @import("config.zig").GhosttyConfig;
|
||||
const GhosttyWindow = @import("window.zig").GhosttyWindow;
|
||||
const ConfigErrorsDialog = @import("config_errors_dialog.zig").ConfigErrorsDialog;
|
||||
|
||||
const log = std.log.scoped(.gtk_ghostty_application);
|
||||
|
||||
@ -320,6 +321,11 @@ pub const GhosttyApplication = extern struct {
|
||||
fn startup(self: *GhosttyApplication) callconv(.C) void {
|
||||
log.debug("startup", .{});
|
||||
|
||||
gio.Application.virtual_methods.startup.call(
|
||||
Class.parent,
|
||||
self.as(Parent),
|
||||
);
|
||||
|
||||
// Setup our event loop
|
||||
self.startupXev();
|
||||
|
||||
@ -331,10 +337,15 @@ pub const GhosttyApplication = extern struct {
|
||||
log.warn("TODO", .{});
|
||||
};
|
||||
|
||||
gio.Application.virtual_methods.startup.call(
|
||||
Class.parent,
|
||||
self.as(Parent),
|
||||
);
|
||||
// If we have any config diagnostics from loading, then we
|
||||
// show the diagnostics dialog. We show this one as a general
|
||||
// modal (not to any specific window) because we don't even
|
||||
// know if the window will load.
|
||||
const priv = self.private();
|
||||
if (priv.config.hasDiagnostics()) {
|
||||
const dialog: *ConfigErrorsDialog = .new(priv.config);
|
||||
dialog.present(null);
|
||||
}
|
||||
}
|
||||
|
||||
/// Configure libxev to use a specific backend.
|
||||
@ -474,8 +485,8 @@ pub const GhosttyApplication = extern struct {
|
||||
self.as(Parent),
|
||||
);
|
||||
|
||||
const win = GhosttyWindow.new(self);
|
||||
gtk.Window.present(win.as(gtk.Window));
|
||||
// const win = GhosttyWindow.new(self);
|
||||
// gtk.Window.present(win.as(gtk.Window));
|
||||
}
|
||||
|
||||
fn finalize(self: *GhosttyApplication) callconv(.C) void {
|
||||
|
@ -29,6 +29,36 @@ pub const GhosttyConfig = extern struct {
|
||||
.private = .{ .Type = Private, .offset = &Private.offset },
|
||||
});
|
||||
|
||||
pub const properties = struct {
|
||||
pub const @"diagnostics-buffer" = gobject.ext.defineProperty(
|
||||
"diagnostics-buffer",
|
||||
Self,
|
||||
?*gtk.TextBuffer,
|
||||
.{
|
||||
.nick = "Dignostics Buffer",
|
||||
.blurb = "A TextBuffer that contains the diagnostics.",
|
||||
.default = null,
|
||||
.accessor = .{
|
||||
.getter = Self.diagnosticsBuffer,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
pub const @"has-diagnostics" = gobject.ext.defineProperty(
|
||||
"has-diagnostics",
|
||||
Self,
|
||||
bool,
|
||||
.{
|
||||
.nick = "has-diagnostics",
|
||||
.blurb = "Whether the configuration has diagnostics.",
|
||||
.default = false,
|
||||
.accessor = .{
|
||||
.getter = Self.hasDiagnostics,
|
||||
},
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const Private = struct {
|
||||
config: Config,
|
||||
|
||||
@ -55,6 +85,48 @@ pub const GhosttyConfig = extern struct {
|
||||
return &self.private().config;
|
||||
}
|
||||
|
||||
/// Get the mutable configuration. This is usually NOT recommended
|
||||
/// because any changes to the config won't be propagated to anyone
|
||||
/// with a reference to this object. If you know what you're doing, then
|
||||
/// you can use this.
|
||||
pub fn getMut(self: *Self) *Config {
|
||||
return &self.private().config;
|
||||
}
|
||||
|
||||
/// Returns whether this configuration has any diagnostics.
|
||||
pub fn hasDiagnostics(self: *Self) bool {
|
||||
const config = self.get();
|
||||
return !config._diagnostics.empty();
|
||||
}
|
||||
|
||||
/// Reads the diagnostics of this configuration as a TextBuffer,
|
||||
/// or returns null if there are no diagnostics.
|
||||
pub fn diagnosticsBuffer(self: *Self) ?*gtk.TextBuffer {
|
||||
const config = self.get();
|
||||
if (config._diagnostics.empty()) return null;
|
||||
|
||||
const text_buf: *gtk.TextBuffer = .new(null);
|
||||
errdefer text_buf.unref();
|
||||
|
||||
var buf: [4095:0]u8 = undefined;
|
||||
var fbs = std.io.fixedBufferStream(&buf);
|
||||
for (config._diagnostics.items()) |diag| {
|
||||
fbs.reset();
|
||||
diag.write(fbs.writer()) catch |err| {
|
||||
log.warn(
|
||||
"error writing diagnostic to buffer err={}",
|
||||
.{err},
|
||||
);
|
||||
continue;
|
||||
};
|
||||
|
||||
text_buf.insertAtCursor(&buf, @intCast(fbs.pos));
|
||||
text_buf.insertAtCursor("\n", 1);
|
||||
}
|
||||
|
||||
return text_buf;
|
||||
}
|
||||
|
||||
fn finalize(self: *Self) callconv(.C) void {
|
||||
self.private().config.deinit();
|
||||
|
||||
@ -91,6 +163,10 @@ pub const GhosttyConfig = extern struct {
|
||||
|
||||
fn init(class: *Class) callconv(.C) void {
|
||||
gobject.Object.virtual_methods.finalize.implement(class, &finalize);
|
||||
gobject.ext.registerProperties(class, &.{
|
||||
properties.@"diagnostics-buffer",
|
||||
properties.@"has-diagnostics",
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
@ -5,11 +5,11 @@ const gtk = @import("gtk");
|
||||
|
||||
const gresource = @import("../build/gresource.zig");
|
||||
const adw_version = @import("../adw_version.zig");
|
||||
const GhosttyConfig = @import("config.zig").GhosttyConfig;
|
||||
const Config = @import("config.zig").GhosttyConfig;
|
||||
|
||||
const log = std.log.scoped(.gtk_ghostty_window);
|
||||
|
||||
pub const GhosttyConfigErrors = extern struct {
|
||||
pub const ConfigErrorsDialog = extern struct {
|
||||
const Self = @This();
|
||||
parent_instance: Parent,
|
||||
|
||||
@ -19,18 +19,38 @@ pub const GhosttyConfigErrors = extern struct {
|
||||
adw.MessageDialog;
|
||||
|
||||
pub const getGObjectType = gobject.ext.defineClass(Self, .{
|
||||
.name = "GhosttyConfigErrorsDialog",
|
||||
.instanceInit = &init,
|
||||
.classInit = &Class.init,
|
||||
.parent_class = &Class.parent,
|
||||
.private = .{ .Type = Private, .offset = &Private.offset },
|
||||
});
|
||||
|
||||
pub const properties = struct {
|
||||
pub const config = gobject.ext.defineProperty(
|
||||
"config",
|
||||
Self,
|
||||
?*Config,
|
||||
.{
|
||||
.nick = "config",
|
||||
.blurb = "The configuration that this dialog is showing errors for.",
|
||||
.default = null,
|
||||
.accessor = gobject.ext.privateFieldAccessor(
|
||||
Self,
|
||||
Private,
|
||||
&Private.offset,
|
||||
"config",
|
||||
),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const Private = struct {
|
||||
_todo: u8 = 0,
|
||||
config: ?*Config,
|
||||
var offset: c_int = 0;
|
||||
};
|
||||
|
||||
pub fn new(config: *GhosttyConfig) *Self {
|
||||
pub fn new(config: *Config) *Self {
|
||||
return gobject.ext.newInstance(Self, .{
|
||||
.config = config,
|
||||
});
|
||||
@ -40,6 +60,13 @@ pub const GhosttyConfigErrors = extern struct {
|
||||
gtk.Widget.initTemplate(self.as(gtk.Widget));
|
||||
}
|
||||
|
||||
pub fn present(self: *Self, parent: ?*gtk.Widget) void {
|
||||
switch (Parent) {
|
||||
adw.AlertDialog => self.as(adw.Dialog).present(parent),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as(win: *Self, comptime T: type) *T {
|
||||
return gobject.ext.as(T, win);
|
||||
}
|
||||
@ -58,9 +85,14 @@ pub const GhosttyConfigErrors = extern struct {
|
||||
.minor = 5,
|
||||
.name = "config-errors-dialog",
|
||||
}),
|
||||
|
||||
else => unreachable,
|
||||
},
|
||||
);
|
||||
|
||||
gobject.ext.registerProperties(class, &.{
|
||||
properties.config,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn as(class: *Class, comptime T: type) *T {
|
@ -20,7 +20,7 @@ pub const GhosttyWindow = extern struct {
|
||||
});
|
||||
|
||||
const Private = struct {
|
||||
_todo: u8 = 0,
|
||||
_todo: u8,
|
||||
var offset: c_int = 0;
|
||||
};
|
||||
|
||||
@ -28,12 +28,20 @@ pub const GhosttyWindow = extern struct {
|
||||
return gobject.ext.newInstance(Self, .{ .application = app });
|
||||
}
|
||||
|
||||
fn init(win: *GhosttyWindow, _: *Class) callconv(.C) void {
|
||||
gtk.Widget.initTemplate(win.as(gtk.Widget));
|
||||
fn init(self: *GhosttyWindow, _: *Class) callconv(.C) void {
|
||||
gtk.Widget.initTemplate(self.as(gtk.Widget));
|
||||
}
|
||||
|
||||
pub fn as(win: *Self, comptime T: type) *T {
|
||||
return gobject.ext.as(T, win);
|
||||
pub fn as(self: *Self, comptime T: type) *T {
|
||||
return gobject.ext.as(T, self);
|
||||
}
|
||||
|
||||
fn private(self: *Self) *Private {
|
||||
return gobject.ext.impl_helpers.getPrivate(
|
||||
self,
|
||||
Private,
|
||||
Private.offset,
|
||||
);
|
||||
}
|
||||
|
||||
pub const Class = extern struct {
|
||||
|
@ -1,7 +1,7 @@
|
||||
using Gtk 4.0;
|
||||
using Adw 1;
|
||||
|
||||
Adw.AlertDialog config_errors_dialog {
|
||||
template $GhosttyConfigErrorsDialog: Adw.AlertDialog {
|
||||
heading: _("Configuration Errors");
|
||||
body: _("One or more configuration errors were found. Please review the errors below, and either reload your configuration or ignore these errors.");
|
||||
|
||||
@ -21,6 +21,7 @@ Adw.AlertDialog config_errors_dialog {
|
||||
bottom-margin: 8;
|
||||
left-margin: 8;
|
||||
right-margin: 8;
|
||||
buffer: bind (template.config as <$GhosttyConfig>).diagnostics-buffer;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user