# HG changeset patch
# Node ID 3dd85ee993b7
# Parent  ffd3cb104c31
diff --git a/talkatu/data/talkatu.gresource.xml b/talkatu/data/talkatu.gresource.xml
--- a/talkatu/data/talkatu.gresource.xml
+++ b/talkatu/data/talkatu.gresource.xml
@@ -7,5 +7,6 @@
     <file compressed="true">historyrow.ui</file>
     <file compressed="true">linkdialog.ui</file>
     <file compressed="true">toolbar.ui</file>
+    <file compressed="true">typinglabel.ui</file>
   </gresource>
 </gresources>
diff --git a/talkatu/data/typinglabel.ui b/talkatu/data/typinglabel.ui
new file mode 100644
--- /dev/null
+++ b/talkatu/data/typinglabel.ui
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+Talkatu - GTK widgets for chat applications
+Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the terms of the GNU 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this library; if not, see <https://www.gnu.org/licenses/>.
+
+-->
+<interface>
+  <requires lib="gtk" version="4.0"/>
+  <!-- interface-license-type gplv2 -->
+  <!-- interface-name Talkatu -->
+  <!-- interface-description GTK widgets for chat applications -->
+  <!-- interface-copyright Gary Kramlich <grim@reaperworld.com> -->
+  <template id="TalkatuTypingLabel" class="GtkWidget">
+    <child>
+      <object class="GtkLabel" id="label">
+        <property name="xalign">0</property>
+      </object>
+    </child>
+  </template>
+</interface>
diff --git a/talkatu/talkatutypinglabel.h b/talkatu/talkatutypinglabel.h
--- a/talkatu/talkatutypinglabel.h
+++ b/talkatu/talkatutypinglabel.h
@@ -1,6 +1,6 @@
 /*
  * Talkatu - GTK widgets for chat applications
- * Copyright (C) 2017-2020 Gary Kramlich <grim@reaperworld.com>
+ * Copyright (C) 2017-2022 Gary Kramlich <grim@reaperworld.com>
  *
  * This library is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -31,18 +31,7 @@
 G_BEGIN_DECLS
 
 #define TALKATU_TYPE_TYPING_LABEL (talkatu_typing_label_get_type())
-G_DECLARE_DERIVABLE_TYPE(TalkatuTypingLabel, talkatu_typing_label, TALKATU, TYPING_LABEL, GtkLabel)
-
-struct _TalkatuTypingLabelClass {
-	/*< private >*/
-	GtkLabelClass parent;
-
-	/*< public >*/
-	void (*changed)(TalkatuTypingLabel *label, GList *typers);
-
-	/*< private >*/
-	gpointer reserved[4];
-};
+G_DECLARE_FINAL_TYPE(TalkatuTypingLabel, talkatu_typing_label, TALKATU, TYPING_LABEL, GtkWidget)
 
 GtkWidget *talkatu_typing_label_new(void);
 
diff --git a/talkatu/talkatutypinglabel.c b/talkatu/talkatutypinglabel.c
--- a/talkatu/talkatutypinglabel.c
+++ b/talkatu/talkatutypinglabel.c
@@ -37,11 +37,13 @@
  * Usernames are passed in as strings and their default display can be
  * overridden by connecting to the #TalkatuTypingLabel::changed signal.
  */
-typedef struct {
-	GtkLabel parent;
+struct _TalkatuTypingLabel {
+	GtkWidget parent;
+
+	GtkWidget *label;
 
 	GHashTable *typers;
-} TalkatuTypingLabelPrivate;
+};
 
 /**
  * TalkatuTypingLabelClass:
@@ -62,7 +64,7 @@
 };
 static guint signals[LAST_SIGNAL] = {0, };
 
-G_DEFINE_TYPE_WITH_PRIVATE(TalkatuTypingLabel, talkatu_typing_label, GTK_TYPE_LABEL)
+G_DEFINE_TYPE(TalkatuTypingLabel, talkatu_typing_label, GTK_TYPE_WIDGET)
 
 #define TALKATU_TYPING_LABEL_TIMEOUT (30)
 
@@ -126,7 +128,7 @@
 			                       (gchar *)typers->next->next->data);
 		}
 
-		gtk_label_set_text(GTK_LABEL(label), text);
+		gtk_label_set_text(GTK_LABEL(label->label), text);
 		g_free(text);
 	}
 }
@@ -136,24 +138,17 @@
  *****************************************************************************/
 static void
 talkatu_typing_label_init(TalkatuTypingLabel *label) {
-	TalkatuTypingLabelPrivate *priv = NULL;
-
-	/* set our xalign to 0 to make it left justified... */
-	gtk_label_set_xalign(GTK_LABEL(label), 0);
+	gtk_widget_init_template(GTK_WIDGET(label));
 
-	priv = talkatu_typing_label_get_instance_private(TALKATU_TYPING_LABEL(label));
-
-	priv->typers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-	                                     talkatu_typing_label_typer_value_free);
+	label->typers = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
+	                                      talkatu_typing_label_typer_value_free);
 }
 
 static void
 talkatu_typing_label_finalize(GObject *obj) {
-	TalkatuTypingLabelPrivate *priv = NULL;
+	TalkatuTypingLabel *label = TALKATU_TYPING_LABEL(obj);
 
-	priv = talkatu_typing_label_get_instance_private(TALKATU_TYPING_LABEL(obj));
-
-	g_hash_table_destroy(priv->typers);
+	g_hash_table_destroy(label->typers);
 
 	G_OBJECT_CLASS(talkatu_typing_label_parent_class)->finalize(obj);
 }
@@ -161,11 +156,10 @@
 static void
 talkatu_typing_label_class_init(TalkatuTypingLabelClass *klass) {
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 
 	obj_class->finalize = talkatu_typing_label_finalize;
 
-	klass->changed = talkatu_typing_label_default_changed;
-
 	/**
 	 * TalkatuTypingLabel::changed:
 	 * @talkatutypinglabel: The #TalkatuTypingLabel instance.
@@ -174,11 +168,11 @@
 	 *
 	 * Emitted when the typing state of an individual has changed.
 	 */
-	signals[SIG_CHANGED] = g_signal_new(
+	signals[SIG_CHANGED] = g_signal_new_class_handler(
 		"changed",
 		G_TYPE_FROM_CLASS(klass),
 		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		G_STRUCT_OFFSET(TalkatuTypingLabelClass, changed),
+		G_CALLBACK(talkatu_typing_label_default_changed),
 		NULL,
 		NULL,
 		NULL,
@@ -186,6 +180,14 @@
 		1,
 		G_TYPE_POINTER
 	);
+
+	gtk_widget_class_set_template_from_resource(
+		GTK_WIDGET_CLASS(klass),
+		"/org/imfreedom/keep/talkatu/talkatu/ui/typinglabel.ui"
+	);
+
+	gtk_widget_class_bind_template_child(widget_class, TalkatuTypingLabel,
+	                                     label);
 }
 
 /******************************************************************************
@@ -200,10 +202,10 @@
  * Returns: (transfer full): The new #TalkatuTypingLabel instance.
  */
 GtkWidget *talkatu_typing_label_new(void) {
-	return GTK_WIDGET(g_object_new(
+	return g_object_new(
 		TALKATU_TYPE_TYPING_LABEL,
 		NULL
-	));
+	);
 }
 
 /**
@@ -215,7 +217,6 @@
  */
 void
 talkatu_typing_label_start_typing(TalkatuTypingLabel *label, const gchar *who) {
-	TalkatuTypingLabelPrivate *priv = NULL;
 	TalkatuTypingLabelTimeoutData *typing_data = NULL;
 	guint timeout_id = 0;
 	gpointer value = NULL;
@@ -223,8 +224,6 @@
 	g_return_if_fail(TALKATU_IS_TYPING_LABEL(label));
 	g_return_if_fail(who != NULL);
 
-	priv = talkatu_typing_label_get_instance_private(label);
-
 	/* create a timeout to remove this person from the list */
 	typing_data = g_new(TalkatuTypingLabelTimeoutData, 1);
 	typing_data->label = label;
@@ -240,9 +239,9 @@
 
 	value = GUINT_TO_POINTER(timeout_id);
 
-	if(g_hash_table_replace(priv->typers, typing_data->who, value)) {
+	if(g_hash_table_replace(label->typers, typing_data->who, value)) {
 		/* the user wasn't in the list so we need to emit our changed signal */
-		GList *typers = g_hash_table_get_keys(priv->typers);
+		GList *typers = g_hash_table_get_keys(label->typers);
 
 		g_signal_emit(label, signals[SIG_CHANGED], 0, typers);
 
@@ -261,15 +260,11 @@
 talkatu_typing_label_finish_typing(TalkatuTypingLabel *label,
                                    const gchar* who)
 {
-	TalkatuTypingLabelPrivate *priv = NULL;
-
 	g_return_if_fail(TALKATU_IS_TYPING_LABEL(label));
 	g_return_if_fail(who != NULL);
 
-	priv = talkatu_typing_label_get_instance_private(label);
-
-	if(g_hash_table_remove(priv->typers, who)) {
-		GList *typers = g_hash_table_get_keys(priv->typers);
+	if(g_hash_table_remove(label->typers, who)) {
+		GList *typers = g_hash_table_get_keys(label->typers);
 
 		/* emit our changed signal */
 		g_signal_emit(label, signals[SIG_CHANGED], 0, typers);
@@ -277,4 +272,3 @@
 		g_list_free(typers);
 	}
 }
-
