diff options
author | António Fernandes <antoniof@gnome.org> | 2022-05-07 12:41:49 +0100 |
---|---|---|
committer | António Fernandes <antoniof@gnome.org> | 2022-05-07 18:10:44 +0100 |
commit | 64347f2c79d46950595e2689dd774832310742ca (patch) | |
tree | 038b9f33598fa63389c31563c9bd5693502e3aec /gtk/gtkplacessidebar.c | |
parent | aa4e8334ee9a76c14ee5fb43748d2de53f16ebe3 (diff) | |
download | gtk+-64347f2c79d46950595e2689dd774832310742ca.tar.gz |
placessidebar: Point to row instead or reparenting popovers
In GTK 3 we used to move the popovers around using set_relative_to();
this is gone in GTK 4 and the apparent direct replacement is setting
the target widget as the new parent.
But this requires a lot of careful handling least the popover become
orphan, which gets us ready to crash at any moment.
Since we only care about positioning the popovers relative to a row,
let's use the set_pointing_to() instead of reparenting. Now, the
sidebar is always the parent.
Diffstat (limited to 'gtk/gtkplacessidebar.c')
-rw-r--r-- | gtk/gtkplacessidebar.c | 47 |
1 files changed, 33 insertions, 14 deletions
diff --git a/gtk/gtkplacessidebar.c b/gtk/gtkplacessidebar.c index 89f5b69ff1..ff427fe854 100644 --- a/gtk/gtkplacessidebar.c +++ b/gtk/gtkplacessidebar.c @@ -2351,22 +2351,41 @@ update_popover_shadowing (GtkWidget *row, } static void -set_prelight (GtkPopover *popover) +set_prelight (GtkPlacesSidebar *sidebar) { - update_popover_shadowing (gtk_widget_get_parent (GTK_WIDGET (popover)), TRUE); + update_popover_shadowing (GTK_WIDGET (sidebar->context_row), TRUE); } static void -unset_prelight (GtkPopover *popover) +unset_prelight (GtkPlacesSidebar *sidebar) { - update_popover_shadowing (gtk_widget_get_parent (GTK_WIDGET (popover)), FALSE); + update_popover_shadowing (GTK_WIDGET (sidebar->context_row), FALSE); } static void -setup_popover_shadowing (GtkWidget *popover) +setup_popover_shadowing (GtkWidget *popover, + GtkPlacesSidebar *sidebar) { - g_signal_connect (popover, "map", G_CALLBACK (set_prelight), NULL); - g_signal_connect (popover, "unmap", G_CALLBACK (unset_prelight), NULL); + g_signal_connect_swapped (popover, "map", G_CALLBACK (set_prelight), sidebar); + g_signal_connect_swapped (popover, "unmap", G_CALLBACK (unset_prelight), sidebar); +} + +static void +_popover_set_pointing_to_widget (GtkPopover *popover, + GtkWidget *target) +{ + GtkWidget *parent; + double x, y, w, h; + + parent = gtk_widget_get_parent (GTK_WIDGET (popover)); + + if (!gtk_widget_translate_coordinates (target, parent, 0, 0, &x, &y)) + return; + + w = gtk_widget_get_allocated_width (GTK_WIDGET (target)); + h = gtk_widget_get_allocated_height (GTK_WIDGET (target)); + + gtk_popover_set_pointing_to (popover, &(GdkRectangle){x, y, w, h}); } static void @@ -2389,12 +2408,11 @@ show_rename_popover (GtkSidebarRow *row) sidebar->rename_uri = g_strdup (uri); gtk_editable_set_text (GTK_EDITABLE (sidebar->rename_entry), name); - g_object_ref (sidebar->rename_popover); - gtk_widget_unparent (sidebar->rename_popover); - gtk_widget_set_parent (sidebar->rename_popover, GTK_WIDGET (row)); - g_object_unref (sidebar->rename_popover); - setup_popover_shadowing (sidebar->rename_popover); + _popover_set_pointing_to_widget (GTK_POPOVER (sidebar->rename_popover), + GTK_WIDGET (row)); + + setup_popover_shadowing (sidebar->rename_popover, sidebar); gtk_popover_popup (GTK_POPOVER (sidebar->rename_popover)); gtk_widget_grab_focus (sidebar->rename_entry); @@ -3325,9 +3343,10 @@ create_row_popover (GtkPlacesSidebar *sidebar, sidebar->popover = gtk_popover_menu_new_from_model (G_MENU_MODEL (menu)); g_object_unref (menu); + gtk_widget_set_parent (sidebar->popover, GTK_WIDGET (sidebar)); g_signal_connect (sidebar->popover, "destroy", G_CALLBACK (on_row_popover_destroy), sidebar); - setup_popover_shadowing (sidebar->popover); + setup_popover_shadowing (sidebar->popover, sidebar); } static void @@ -3341,7 +3360,7 @@ show_row_popover (GtkSidebarRow *row) create_row_popover (sidebar, row); - gtk_widget_set_parent (sidebar->popover, GTK_WIDGET (row)); + _popover_set_pointing_to_widget (GTK_POPOVER (sidebar->popover), GTK_WIDGET (row)); sidebar->context_row = row; gtk_popover_popup (GTK_POPOVER (sidebar->popover)); |