apprt/gtk-ng: implement remember

This commit is contained in:
Mitchell Hashimoto
2025-07-22 13:27:02 -07:00
parent 58a5f3f1f8
commit 4d39f2728a
5 changed files with 117 additions and 13 deletions

View File

@ -33,7 +33,8 @@ pub const icon_sizes: []const comptime_int = &.{ 16, 32, 128, 256, 512, 1024 };
///
/// These will be asserted to exist at runtime.
pub const blueprints: []const Blueprint = &.{
.{ .major = 1, .minor = 2, .name = "clipboard-confirmation-dialog" },
.{ .major = 1, .minor = 0, .name = "clipboard-confirmation-dialog" },
.{ .major = 1, .minor = 4, .name = "clipboard-confirmation-dialog" },
.{ .major = 1, .minor = 2, .name = "close-confirmation-dialog" },
.{ .major = 1, .minor = 2, .name = "config-errors-dialog" },
.{ .major = 1, .minor = 2, .name = "resize-overlay" },

View File

@ -8,11 +8,15 @@ const gtk = @import("gtk");
const apprt = @import("../../../apprt.zig");
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 Dialog = @import("dialog.zig").Dialog;
const log = std.log.scoped(.gtk_ghostty_clipboard_confirmation);
/// Whether we're able to have the remember switch
const can_remember = adw_version.supportsSwitchRow();
pub const ClipboardConfirmationDialog = extern struct {
const Self = @This();
parent_instance: Parent,
@ -147,6 +151,7 @@ pub const ClipboardConfirmationDialog = extern struct {
text_view: *gtk.TextView,
reveal_button: *gtk.Button,
hide_button: *gtk.Button,
remember_choice: if (can_remember) *adw.SwitchRow else void,
pub var offset: c_int = 0;
};
@ -279,8 +284,10 @@ pub const ClipboardConfirmationDialog = extern struct {
self: *Self,
response_id: [*:0]const u8,
) callconv(.C) void {
// TODO: remember
const remember = false;
const remember: bool = if (comptime can_remember) remember: {
const priv = self.private();
break :remember priv.remember_choice.getActive() != 0;
} else false;
if (std.mem.orderZ(u8, response_id, "cancel") == .eq) {
signals.deny.impl.emit(
@ -344,11 +351,18 @@ pub const ClipboardConfirmationDialog = extern struct {
fn init(class: *Class) callconv(.C) void {
gtk.Widget.Class.setTemplateFromResource(
class.as(gtk.Widget.Class),
comptime gresource.blueprint(.{
.major = 1,
.minor = 2,
.name = "clipboard-confirmation-dialog",
}),
if (comptime adw_version.atLeast(1, 4, 0))
comptime gresource.blueprint(.{
.major = 1,
.minor = 4,
.name = "clipboard-confirmation-dialog",
})
else
comptime gresource.blueprint(.{
.major = 1,
.minor = 0,
.name = "clipboard-confirmation-dialog",
}),
);
// Bindings
@ -356,6 +370,9 @@ pub const ClipboardConfirmationDialog = extern struct {
class.bindTemplateChildPrivate("text_view", .{});
class.bindTemplateChildPrivate("hide_button", .{});
class.bindTemplateChildPrivate("reveal_button", .{});
if (comptime can_remember) {
class.bindTemplateChildPrivate("remember_choice", .{});
}
// Properties
gobject.ext.registerProperties(class, &.{

View File

@ -2119,12 +2119,17 @@ const Clipboard = struct {
remember: bool,
self: *Surface,
) callconv(.c) void {
_ = remember;
const priv = self.private();
const surface = priv.core_surface orelse return;
const req = dialog.getRequest() orelse return;
// Handle remember
if (remember) switch (req.*) {
.osc_52_read => surface.config.clipboard_read = .allow,
.osc_52_write => surface.config.clipboard_write = .allow,
.paste => {},
};
// Get our text
const text_buf = dialog.getClipboardContents() orelse return;
var text_val = gobject.ext.Value.new(?[:0]const u8);
@ -2153,9 +2158,16 @@ const Clipboard = struct {
remember: bool,
self: *Surface,
) callconv(.c) void {
_ = dialog;
_ = remember;
_ = self;
const priv = self.private();
const surface = priv.core_surface orelse return;
const req = dialog.getRequest() orelse return;
// Handle remember
if (remember) switch (req.*) {
.osc_52_read => surface.config.clipboard_read = .deny,
.osc_52_write => surface.config.clipboard_write = .deny,
.paste => {},
};
}
fn clipboardReadText(

View File

@ -0,0 +1,74 @@
using Gtk 4.0;
// This is unused but if we remove it we get a blueprint-compiler error.
using Adw 1;
template $GhosttyClipboardConfirmationDialog: $GhosttyDialog {
styles [
"clipboard-confirmation-dialog",
]
heading: _("Authorize Clipboard Access");
// Not localized because this is a placeholder users never see.
body: "If you see this text, there is a bug in Ghostty. Please report it.";
responses [
cancel: _("Deny") suggested,
ok: _("Allow") destructive,
]
default-response: "cancel";
close-response: "cancel";
extra-child: ListBox {
selection-mode: none;
Overlay {
styles [
"osd",
"clipboard-overlay",
]
ScrolledWindow text_view_scroll {
width-request: 500;
height-request: 200;
TextView text_view {
styles [
"clipboard-contents",
]
cursor-visible: false;
editable: false;
monospace: true;
top-margin: 8;
left-margin: 8;
bottom-margin: 8;
right-margin: 8;
buffer: bind template.clipboard-contents;
}
}
[overlay]
Button reveal_button {
visible: false;
halign: end;
valign: start;
margin-end: 12;
margin-top: 12;
Image {
icon-name: "view-reveal-symbolic";
}
}
[overlay]
Button hide_button {
visible: false;
halign: end;
valign: start;
margin-end: 12;
margin-top: 12;
}
}
};
}