Set the paste button as default in the GTK paste confirmation dialog (#4225)

A simple change to make it so that, in the GTK4 paste confirmation
dialog, the user can just hit enter/space to confirm the paste.

After some playing around, it seems as though GTK4 needs you to set the
focus on a widget after the entire view has been configured, meaning
that we have to create more references to pass the `confirm_button`
GtkWidget up and up. Not 100% certain if this is the best way to do so,
but:

1. Add the `ButtonsView` to the `PrimaryView` struct (as
`PrimaryView.buttons`)
2. Add the `confirm_button` to the `ButtonsView` struct (as
`ButtonsView.confirm_button`)
3. Call `c.gtk_widget_grab_focus` on (the now-accessible)
`view.buttons.confirm_button`

This seems to work as expected, but I'm not sure if:

1. We should also make `cancel_button` available?
2. There's a better way to expose `confirm_button` to `PrimaryView`?
3. I did a good Zig?

I've never written (or read) Zig code before today so I hope this makes
sense. Feedback welcome!
This commit is contained in:
Mitchell Hashimoto
2025-01-06 09:43:18 -08:00
committed by GitHub

View File

@ -89,6 +89,8 @@ fn init(
const view = try PrimaryView.init(self, data);
self.view = view;
c.gtk_window_set_child(@ptrCast(window), view.root);
_ = c.gtk_widget_grab_focus(view.buttons.cancel_button);
c.gtk_widget_show(window);
// Block the main window from input.
@ -104,6 +106,7 @@ fn gtkDestroy(_: *c.GtkWidget, ud: ?*anyopaque) callconv(.C) void {
const PrimaryView = struct {
root: *c.GtkWidget,
text: *c.GtkTextView,
buttons: ButtonsView,
pub fn init(root: *ClipboardConfirmation, data: []const u8) !PrimaryView {
// All our widgets
@ -135,7 +138,7 @@ const PrimaryView = struct {
c.gtk_text_view_set_right_margin(@ptrCast(text), 8);
c.gtk_text_view_set_monospace(@ptrCast(text), 1);
return .{ .root = view.root, .text = @ptrCast(text) };
return .{ .root = view.root, .text = @ptrCast(text), .buttons = buttons };
}
/// Returns the GtkTextBuffer for the data that was unsafe.
@ -158,6 +161,8 @@ const PrimaryView = struct {
const ButtonsView = struct {
root: *c.GtkWidget,
confirm_button: *c.GtkWidget,
cancel_button: *c.GtkWidget,
pub fn init(root: *ClipboardConfirmation) !ButtonsView {
const cancel_text, const confirm_text = switch (root.pending_req) {
@ -171,8 +176,8 @@ const ButtonsView = struct {
const confirm_button = c.gtk_button_new_with_label(confirm_text);
errdefer c.g_object_unref(confirm_button);
// TODO: Focus on the paste button
// c.gtk_widget_grab_focus(confirm_button);
c.gtk_widget_add_css_class(confirm_button, "destructive-action");
c.gtk_widget_add_css_class(cancel_button, "suggested-action");
// Create our view
const view = try View.init(&.{
@ -198,7 +203,7 @@ const ButtonsView = struct {
c.G_CONNECT_DEFAULT,
);
return .{ .root = view.root };
return .{ .root = view.root, .confirm_button = confirm_button, .cancel_button = cancel_button };
}
fn gtkCancelClick(_: *c.GtkWidget, ud: ?*anyopaque) callconv(.C) void {