From c2f811dd2982a8796709e745d8c097f6e76acdab Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 16 Feb 2021 23:47:20 -0500 Subject: [PATCH] popover: Add a popover content class Instead of bending GtkGizmo to the breaking point, split off a GtkPopoverContent class that just does what is needed here. Its simpler, and lets us keep GtkGizmo simpler too. --- gtk/gtkpopover.c | 17 ++----- gtk/gtkpopovercontent.c | 88 ++++++++++++++++++++++++++++++++++ gtk/gtkpopovercontentprivate.h | 51 ++++++++++++++++++++ gtk/meson.build | 1 + 4 files changed, 143 insertions(+), 14 deletions(-) create mode 100644 gtk/gtkpopovercontent.c create mode 100644 gtk/gtkpopovercontentprivate.h diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c index b00cdd3827..3f3412ba8e 100644 --- a/gtk/gtkpopover.c +++ b/gtk/gtkpopover.c @@ -107,7 +107,7 @@ #include "gtkbinlayout.h" #include "gtkenums.h" #include "gtktypebuiltins.h" -#include "gtkgizmoprivate.h" +#include "gtkpopovercontentprivate.h" #include "gtkintl.h" #include "gtkprivate.h" #include "gtkmain.h" @@ -880,15 +880,6 @@ node_style_changed_cb (GtkCssNode *node, gtk_widget_queue_draw (widget); } -static void -contents_css_changed (GtkGizmo *contents, - GtkCssStyleChange *change) -{ - if (change == NULL || - gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_BOX_SHADOW)) - gtk_widget_queue_resize (gtk_widget_get_parent (GTK_WIDGET (contents))); -} - static void gtk_popover_init (GtkPopover *popover) { @@ -921,10 +912,8 @@ gtk_popover_init (GtkPopover *popover) G_CALLBACK (node_style_changed_cb), popover, 0); g_object_unref (priv->arrow_node); - priv->contents_widget = gtk_gizmo_new ("contents", NULL, NULL, NULL, NULL, - (GtkGizmoFocusFunc)gtk_widget_focus_child, - (GtkGizmoGrabFocusFunc)gtk_widget_grab_focus_child); - gtk_gizmo_set_css_changed_func (GTK_GIZMO (priv->contents_widget), contents_css_changed); + priv->contents_widget = gtk_popover_content_new (); + gtk_widget_set_layout_manager (priv->contents_widget, gtk_bin_layout_new ()); gtk_widget_set_parent (priv->contents_widget, GTK_WIDGET (popover)); gtk_widget_set_overflow (priv->contents_widget, GTK_OVERFLOW_HIDDEN); diff --git a/gtk/gtkpopovercontent.c b/gtk/gtkpopovercontent.c new file mode 100644 index 0000000000..92a299d571 --- /dev/null +++ b/gtk/gtkpopovercontent.c @@ -0,0 +1,88 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2021 Red Hat, Inc. + * + * Authors: + * - Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "gtkpopovercontentprivate.h" +#include "gtkstylecontextprivate.h" + +#include "gtkwidgetprivate.h" + +/* A private class used as the child of GtkPopover. The only thing + * special here is that we need to queue a resize on the popover when + * our shadow changes. + */ + +G_DEFINE_TYPE (GtkPopoverContent, gtk_popover_content, GTK_TYPE_WIDGET); + +static void +gtk_popover_content_css_changed (GtkWidget *widget, + GtkCssStyleChange *change) +{ + GTK_WIDGET_CLASS (gtk_popover_content_parent_class)->css_changed (widget, change); + + if (change == NULL || + gtk_css_style_change_changes_property (change, GTK_CSS_PROPERTY_BOX_SHADOW)) + gtk_widget_queue_resize (gtk_widget_get_parent (widget)); +} + +static void +gtk_popover_content_finalize (GObject *object) +{ + GtkPopoverContent *self = GTK_POPOVER_CONTENT (object); + GtkWidget *widget; + + widget = _gtk_widget_get_first_child (GTK_WIDGET (self)); + while (widget != NULL) + { + GtkWidget *next = _gtk_widget_get_next_sibling (widget); + + gtk_widget_unparent (widget); + + widget = next; + } + + G_OBJECT_CLASS (gtk_popover_content_parent_class)->finalize (object); +} + +static void +gtk_popover_content_class_init (GtkPopoverContentClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->finalize = gtk_popover_content_finalize; + + widget_class->focus = gtk_widget_focus_child; + widget_class->grab_focus = gtk_widget_grab_focus_child; + widget_class->css_changed = gtk_popover_content_css_changed; +} + +static void +gtk_popover_content_init (GtkPopoverContent *self) +{ +} + +GtkWidget * +gtk_popover_content_new (void) +{ + return g_object_new (GTK_TYPE_POPOVER_CONTENT, + "css-name", "contents", + "accessible-role", GTK_ACCESSIBLE_ROLE_WIDGET, + NULL); +} diff --git a/gtk/gtkpopovercontentprivate.h b/gtk/gtkpopovercontentprivate.h new file mode 100644 index 0000000000..69fe9e387c --- /dev/null +++ b/gtk/gtkpopovercontentprivate.h @@ -0,0 +1,51 @@ +/* GTK - The GIMP Toolkit + * Copyright (C) 2021 Red Hat, Inc. + * + * Authors: + * - Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __GTK_POPOVER_CONTENT_H__ +#define __GTK_POPOVER_CONTENT_H__ + +#include "gtkwidget.h" +#include "gtkenums.h" + +#define GTK_TYPE_POPOVER_CONTENT (gtk_popover_content_get_type ()) +#define GTK_POPOVER_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_POPOVER_CONTENT, GtkPopoverContent)) +#define GTK_POPOVER_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_POPOVER_CONTENT, GtkPopoverContentClass)) +#define GTK_IS_POPOVER_CONTENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_POPOVER_CONTENT)) +#define GTK_IS_POPOVER_CONTENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_POPOVER_CONTENT)) +#define GTK_POPOVER_CONTENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_POPOVER_CONTENT, GtkPopoverContentClass)) + +typedef struct _GtkPopoverContent GtkPopoverContent; +typedef struct _GtkPopoverContentClass GtkPopoverContentClass; + +struct _GtkPopoverContent +{ + GtkWidget parent_instance; +}; + +struct _GtkPopoverContentClass +{ + GtkWidgetClass parent_class; +}; + +GType gtk_popover_content_get_type (void) G_GNUC_CONST; + +GtkWidget *gtk_popover_content_new (void); + +#endif diff --git a/gtk/meson.build b/gtk/meson.build index 42cb07a205..5526cd7c5e 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -127,6 +127,7 @@ gtk_private_sources = files([ 'gtkplacesview.c', 'gtkplacesviewrow.c', 'gtkpointerfocus.c', + 'gtkpopovercontent.c', 'gtkprintutils.c', 'gtkprivate.c', 'gtkprogresstracker.c',