[gnome-software: 95/110] gs-description-box: Subclass GtkWidget
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software: 95/110] gs-description-box: Subclass GtkWidget
- Date: Tue, 5 Oct 2021 20:32:44 +0000 (UTC)
commit 3332c288c718e97201c04ed8cfc97b2b55836b0e
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri Aug 27 16:42:14 2021 -0300
gs-description-box: Subclass GtkWidget
GsDescriptionBox currently subclasses GtkBox, which
in GTK4 has a layout manager set. This is problematic
for us because having a layout manager means GTK won't
call GtkWidget.size_allocate, and GsDescriptionBox
relies on this vfunc being called.
Work around this by subclassing GtkWidget directly, and
implementing a very rudimentary size_allocate and
measure vfuncs. Add a new GtkBox child to GsDescriptionBox
doing what the very class was doing before.
Update the description box in idle after size_allocate is
called, otherwise we potentially run into a layout loop,
and GTK4 stops it all there.
src/gs-description-box.c | 66 ++++++++++++++++++++++++++++++++++++++----------
src/gs-description-box.h | 2 +-
src/gs-details-page.ui | 2 --
3 files changed, 54 insertions(+), 16 deletions(-)
---
diff --git a/src/gs-description-box.c b/src/gs-description-box.c
index f60198b84..e42cb89b8 100644
--- a/src/gs-description-box.c
+++ b/src/gs-description-box.c
@@ -27,7 +27,8 @@
#define MAX_COLLAPSED_LINES 4
struct _GsDescriptionBox {
- GtkBox parent;
+ GtkWidget parent;
+ GtkWidget *box;
GtkLabel *label;
GtkButton *button;
gchar *text;
@@ -35,9 +36,10 @@ struct _GsDescriptionBox {
gboolean needs_recalc;
gint last_width;
gint last_height;
+ guint idle_update_id;
};
-G_DEFINE_TYPE (GsDescriptionBox, gs_description_box, GTK_TYPE_BOX)
+G_DEFINE_TYPE (GsDescriptionBox, gs_description_box, GTK_TYPE_WIDGET)
static void
gs_description_box_update_content (GsDescriptionBox *box)
@@ -115,6 +117,35 @@ gs_description_box_read_button_clicked_cb (GtkButton *button,
gs_description_box_update_content (box);
}
+static void
+gs_description_box_measure (GtkWidget *widget,
+ GtkOrientation orientation,
+ gint for_size,
+ gint *minimum,
+ gint *natural,
+ gint *minimum_baseline,
+ gint *natural_baseline)
+{
+ GsDescriptionBox *box = GS_DESCRIPTION_BOX (widget);
+
+ gtk_widget_measure (box->box, orientation,
+ for_size,
+ minimum, natural,
+ minimum_baseline,
+ natural_baseline);
+}
+
+static gboolean
+update_description_in_idle_cb (gpointer data)
+{
+ GsDescriptionBox *box = GS_DESCRIPTION_BOX (data);
+
+ gs_description_box_update_content (box);
+ box->idle_update_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
static void
gs_description_box_size_allocate (GtkWidget *widget,
int width,
@@ -123,12 +154,19 @@ gs_description_box_size_allocate (GtkWidget *widget,
{
GsDescriptionBox *box = GS_DESCRIPTION_BOX (widget);
- GTK_WIDGET_CLASS (gs_description_box_parent_class)->size_allocate (widget,
- width,
- height,
- baseline);
+ gtk_widget_allocate (box->box, width, height, baseline, NULL);
+ box->idle_update_id = g_idle_add (update_description_in_idle_cb, box);
+}
- gs_description_box_update_content (box);
+static void
+gs_description_box_dispose (GObject *object)
+{
+ GsDescriptionBox *box = GS_DESCRIPTION_BOX (object);
+
+ g_clear_handle_id (&box->idle_update_id, g_source_remove);
+ g_clear_pointer (&box->box, gtk_widget_unparent);
+
+ G_OBJECT_CLASS (gs_description_box_parent_class)->dispose (object);
}
static void
@@ -149,6 +187,9 @@ gs_description_box_init (GsDescriptionBox *box)
box->is_collapsed = TRUE;
+ box->box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 24);
+ gtk_widget_set_parent (GTK_WIDGET (box->box), GTK_WIDGET (box));
+
style_context = gtk_widget_get_style_context (GTK_WIDGET (box));
gtk_style_context_add_class (style_context, "application-details-description");
@@ -166,7 +207,7 @@ gs_description_box_init (GsDescriptionBox *box)
"xalign", 0.0,
NULL);
- gtk_box_append (GTK_BOX (box), widget);
+ gtk_box_append (GTK_BOX (box->box), widget);
style_context = gtk_widget_get_style_context (widget);
gtk_style_context_add_class (style_context, "label");
@@ -183,7 +224,7 @@ gs_description_box_init (GsDescriptionBox *box)
"visible", TRUE,
NULL);
- gtk_box_append (GTK_BOX (box), widget);
+ gtk_box_append (GTK_BOX (box->box), widget);
style_context = gtk_widget_get_style_context (widget);
gtk_style_context_add_class (style_context, "button");
@@ -202,19 +243,18 @@ gs_description_box_class_init (GsDescriptionBoxClass *klass)
GtkWidgetClass *widget_class;
object_class = G_OBJECT_CLASS (klass);
+ object_class->dispose = gs_description_box_dispose;
object_class->finalize = gs_description_box_finalize;
widget_class = GTK_WIDGET_CLASS (klass);
+ widget_class->measure = gs_description_box_measure;
widget_class->size_allocate = gs_description_box_size_allocate;
}
GtkWidget *
gs_description_box_new (void)
{
- return g_object_new (GS_TYPE_DESCRIPTION_BOX,
- "orientation", GTK_ORIENTATION_VERTICAL,
- "spacing", 24,
- NULL);
+ return g_object_new (GS_TYPE_DESCRIPTION_BOX, NULL);
}
const gchar *
diff --git a/src/gs-description-box.h b/src/gs-description-box.h
index ebcb60174..667b2143d 100644
--- a/src/gs-description-box.h
+++ b/src/gs-description-box.h
@@ -14,7 +14,7 @@ G_BEGIN_DECLS
#define GS_TYPE_DESCRIPTION_BOX (gs_description_box_get_type ())
-G_DECLARE_FINAL_TYPE (GsDescriptionBox, gs_description_box, GS, DESCRIPTION_BOX, GtkBox)
+G_DECLARE_FINAL_TYPE (GsDescriptionBox, gs_description_box, GS, DESCRIPTION_BOX, GtkWidget)
GtkWidget *gs_description_box_new (void);
const gchar *gs_description_box_get_text (GsDescriptionBox *box);
diff --git a/src/gs-details-page.ui b/src/gs-details-page.ui
index 9a157c410..dfd120826 100644
--- a/src/gs-details-page.ui
+++ b/src/gs-details-page.ui
@@ -414,8 +414,6 @@
</child>
<child>
<object class="GsDescriptionBox" id="box_details_description">
- <property name="orientation">vertical</property>
- <property name="spacing">12</property>
<property name="halign">fill</property>
<property name="hexpand">True</property>
<property name="valign">start</property>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]