mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-09-05 19:08:17 +00:00
208 lines
5.9 KiB
Zig
208 lines
5.9 KiB
Zig
const std = @import("std");
|
|
const adw = @import("adw");
|
|
const gobject = @import("gobject");
|
|
const gtk = @import("gtk");
|
|
|
|
const gresource = @import("../build/gresource.zig");
|
|
const i18n = @import("../../../os/main.zig").i18n;
|
|
const adw_version = @import("../adw_version.zig");
|
|
const Common = @import("../class.zig").Common;
|
|
const Config = @import("config.zig").Config;
|
|
const Dialog = @import("dialog.zig").Dialog;
|
|
|
|
const log = std.log.scoped(.gtk_ghostty_close_confirmation_dialog);
|
|
|
|
pub const CloseConfirmationDialog = extern struct {
|
|
const Self = @This();
|
|
parent_instance: Parent,
|
|
pub const Parent = Dialog;
|
|
pub const getGObjectType = gobject.ext.defineClass(Self, .{
|
|
.name = "GhosttyCloseConfirmationDialog",
|
|
.instanceInit = &init,
|
|
.classInit = &Class.init,
|
|
.parent_class = &Class.parent,
|
|
.private = .{ .Type = Private, .offset = &Private.offset },
|
|
});
|
|
|
|
pub const properties = struct {
|
|
pub const target = struct {
|
|
pub const name = "target";
|
|
const impl = gobject.ext.defineProperty(
|
|
name,
|
|
Self,
|
|
Target,
|
|
.{
|
|
.default = .app,
|
|
.accessor = gobject.ext.privateFieldAccessor(
|
|
Self,
|
|
Private,
|
|
&Private.offset,
|
|
"target",
|
|
),
|
|
},
|
|
);
|
|
};
|
|
};
|
|
|
|
pub const signals = struct {
|
|
pub const @"close-request" = struct {
|
|
pub const name = "close-request";
|
|
pub const connect = impl.connect;
|
|
const impl = gobject.ext.defineSignal(
|
|
name,
|
|
Self,
|
|
&.{},
|
|
void,
|
|
);
|
|
};
|
|
|
|
pub const cancel = struct {
|
|
pub const name = "cancel";
|
|
pub const connect = impl.connect;
|
|
const impl = gobject.ext.defineSignal(
|
|
name,
|
|
Self,
|
|
&.{},
|
|
void,
|
|
);
|
|
};
|
|
};
|
|
|
|
const Private = struct {
|
|
target: Target,
|
|
pub var offset: c_int = 0;
|
|
};
|
|
|
|
pub fn new(target: Target) *Self {
|
|
return gobject.ext.newInstance(Self, .{
|
|
.target = target,
|
|
});
|
|
}
|
|
|
|
fn init(self: *Self, _: *Class) callconv(.c) void {
|
|
gtk.Widget.initTemplate(self.as(gtk.Widget));
|
|
}
|
|
|
|
pub fn present(self: *Self, parent: ?*gtk.Widget) void {
|
|
// Setup our title/body text.
|
|
const priv = self.private();
|
|
self.as(Dialog.Parent).setHeading(priv.target.title());
|
|
self.as(Dialog.Parent).setBody(priv.target.body());
|
|
|
|
// Show it
|
|
self.as(Dialog).present(parent);
|
|
}
|
|
|
|
pub fn close(self: *Self) void {
|
|
self.as(Dialog).close();
|
|
}
|
|
|
|
fn response(
|
|
self: *Self,
|
|
response_id: [*:0]const u8,
|
|
) callconv(.c) void {
|
|
if (std.mem.orderZ(u8, response_id, "close") == .eq) {
|
|
signals.@"close-request".impl.emit(
|
|
self,
|
|
null,
|
|
.{},
|
|
null,
|
|
);
|
|
} else {
|
|
signals.cancel.impl.emit(
|
|
self,
|
|
null,
|
|
.{},
|
|
null,
|
|
);
|
|
}
|
|
}
|
|
|
|
fn dispose(self: *Self) callconv(.c) void {
|
|
gtk.Widget.disposeTemplate(
|
|
self.as(gtk.Widget),
|
|
getGObjectType(),
|
|
);
|
|
|
|
gobject.Object.virtual_methods.dispose.call(
|
|
Class.parent,
|
|
self.as(Parent),
|
|
);
|
|
}
|
|
|
|
const C = Common(Self, Private);
|
|
pub const as = C.as;
|
|
pub const ref = C.ref;
|
|
pub const refSink = C.refSink;
|
|
pub const unref = C.unref;
|
|
const private = C.private;
|
|
|
|
pub const Class = extern struct {
|
|
parent_class: Parent.Class,
|
|
var parent: *Parent.Class = undefined;
|
|
pub const Instance = Self;
|
|
|
|
fn init(class: *Class) callconv(.c) void {
|
|
gobject.ext.ensureType(Dialog);
|
|
gtk.Widget.Class.setTemplateFromResource(
|
|
class.as(gtk.Widget.Class),
|
|
comptime gresource.blueprint(.{
|
|
.major = 1,
|
|
.minor = 2,
|
|
.name = "close-confirmation-dialog",
|
|
}),
|
|
);
|
|
|
|
// Properties
|
|
gobject.ext.registerProperties(class, &.{
|
|
properties.target.impl,
|
|
});
|
|
|
|
// Signals
|
|
signals.@"close-request".impl.register(.{});
|
|
signals.cancel.impl.register(.{});
|
|
|
|
// Virtual methods
|
|
gobject.Object.virtual_methods.dispose.implement(class, &dispose);
|
|
Dialog.virtual_methods.response.implement(class, &response);
|
|
}
|
|
|
|
pub const as = C.Class.as;
|
|
};
|
|
};
|
|
|
|
/// The target of a close dialog.
|
|
///
|
|
/// This is here so that we can consolidate all logic related to
|
|
/// prompting the user and closing windows/tabs/surfaces/etc.
|
|
/// together into one struct that is the sole source of truth.
|
|
pub const Target = enum(c_int) {
|
|
app,
|
|
tab,
|
|
window,
|
|
surface,
|
|
|
|
pub fn title(self: Target) [*:0]const u8 {
|
|
return switch (self) {
|
|
.app => i18n._("Quit Ghostty?"),
|
|
.tab => i18n._("Close Tab?"),
|
|
.window => i18n._("Close Window?"),
|
|
.surface => i18n._("Close Split?"),
|
|
};
|
|
}
|
|
|
|
pub fn body(self: Target) [*:0]const u8 {
|
|
return switch (self) {
|
|
.app => i18n._("All terminal sessions will be terminated."),
|
|
.tab => i18n._("All terminal sessions in this tab will be terminated."),
|
|
.window => i18n._("All terminal sessions in this window will be terminated."),
|
|
.surface => i18n._("The currently running process in this split will be terminated."),
|
|
};
|
|
}
|
|
|
|
pub const getGObjectType = gobject.ext.defineEnum(
|
|
Target,
|
|
.{ .name = "GhosttyCloseConfirmationDialogTarget" },
|
|
);
|
|
};
|