# HG changeset patch
# Node ID 149bb8afdda3
# Parent  bfd93f3bfba1
diff --git a/talkatu/data/input.ui b/talkatu/data/input.ui
--- a/talkatu/data/input.ui
+++ b/talkatu/data/input.ui
@@ -32,6 +32,9 @@
     </section>
   </menu>
   <template class="TalkatuInput" parent="TalkatuView">
+    <property name="editable">1</property>
+    <property name="cursor-visible">1</property>
     <property name="extra-menu">model</property>
+    <signal name="notify::buffer" handler="talkatu_input_buffer_set_cb"/>
   </template>
 </interface>
diff --git a/talkatu/data/view.ui b/talkatu/data/view.ui
--- a/talkatu/data/view.ui
+++ b/talkatu/data/view.ui
@@ -37,11 +37,26 @@
     </section>
   </menu>
   <template class="TalkatuView" parent="GtkTextView">
+    <property name="has-tooltip">1</property>
+    <property name="wrap-mode">3</property>
+
+    <signal name="notify::buffer" handler="talkatu_view_buffer_set_cb"/>
     <child>
       <object class="GtkPopoverMenu" id="menu">
         <property name="has-arrow">0</property>
         <property name="menu-model">model</property>
       </object>
     </child>
+    <child>
+      <object class="GtkGestureClick">
+        <property name="button">0</property>
+        <signal name="pressed" handler="talkatu_view_pressed_cb"/>
+      </object>
+    </child>
+    <child>
+      <object class="GtkEventControllerMotion">
+        <signal name="motion" handler="talkatu_view_motion_cb"/>
+      </object>
+    </child>
   </template>
 </interface>
diff --git a/talkatu/talkatuinput.c b/talkatu/talkatuinput.c
--- a/talkatu/talkatuinput.c
+++ b/talkatu/talkatuinput.c
@@ -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
@@ -395,7 +395,8 @@
 
 	/* grab our context_mark */
 	gtk_text_buffer_get_start_iter(buffer, &start);
-	priv->context_mark = gtk_text_buffer_create_mark(buffer, NULL, &start, TRUE);
+	priv->context_mark = gtk_text_buffer_create_mark(buffer, NULL, &start,
+	                                                 TRUE);
 
 	if(TALKATU_IS_BUFFER(buffer)) {
 		GSimpleActionGroup *ag = NULL;
@@ -639,18 +640,10 @@
 talkatu_input_init(TalkatuInput *input) {
 	TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
 
+	gtk_widget_init_template(GTK_WIDGET(input));
+
 	priv->attachments = g_hash_table_new_full(g_int64_hash, g_int64_equal,
 	                                          NULL, g_object_unref);
-
-	/* we need to know when the buffer is changed in our parent so we can
-	 * update our actions and other stuff.
-	 */
-	g_signal_connect(
-		G_OBJECT(input),
-		"notify::buffer",
-		G_CALLBACK(talkatu_input_buffer_set_cb),
-		NULL
-	);
 }
 
 static void
@@ -682,7 +675,8 @@
 
 	/* add our properties */
 	properties[PROP_SEND_BINDING] = g_param_spec_flags(
-		"send-binding", "send-binding", "The keybindings that will trigger the send signal",
+		"send-binding", "send-binding",
+		"The keybindings that will trigger the send signal",
 		TALKATU_TYPE_INPUT_SEND_BINDING,
 		TALKATU_INPUT_SEND_BINDING_RETURN | TALKATU_INPUT_SEND_BINDING_KP_ENTER,
 		G_PARAM_READWRITE | G_PARAM_CONSTRUCT
@@ -729,19 +723,24 @@
 		"/org/imfreedom/keep/talkatu/talkatu/ui/input.ui"
 	);
 
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        talkatu_input_buffer_set_cb);
+
 	/* setup key bindings */
-	gtk_widget_class_add_binding_action(widget_class, GDK_KEY_Return, 0,
+	gtk_widget_class_add_binding_action(widget_class,
+	                                    GDK_KEY_Return, 0,
 	                                    "message.should-send", "u",
 	                                    TALKATU_INPUT_SEND_BINDING_RETURN);
-	gtk_widget_class_add_binding_action(widget_class, GDK_KEY_Return,
-	                                    GDK_SHIFT_MASK, "message.should-send",
-	                                    "u",
+	gtk_widget_class_add_binding_action(widget_class,
+	                                    GDK_KEY_Return, GDK_SHIFT_MASK,
+	                                    "message.should-send", "u",
 	                                    TALKATU_INPUT_SEND_BINDING_SHIFT_RETURN);
-	gtk_widget_class_add_binding_action(widget_class, GDK_KEY_Return,
-	                                    GDK_CONTROL_MASK, "message.should-send",
-	                                    "u",
+	gtk_widget_class_add_binding_action(widget_class,
+	                                    GDK_KEY_Return, GDK_CONTROL_MASK,
+	                                    "message.should-send", "u",
 	                                    TALKATU_INPUT_SEND_BINDING_CONTROL_RETURN);
-	gtk_widget_class_add_binding_action(widget_class, GDK_KEY_KP_Enter, 0,
+	gtk_widget_class_add_binding_action(widget_class,
+	                                    GDK_KEY_KP_Enter, 0,
 	                                    "message.should-send", "u",
 	                                    TALKATU_INPUT_SEND_BINDING_KP_ENTER);
 }
@@ -759,7 +758,7 @@
  */
 GtkWidget *
 talkatu_input_new(void) {
-	return GTK_WIDGET(g_object_new(TALKATU_TYPE_INPUT, NULL));
+	return g_object_new(TALKATU_TYPE_INPUT, NULL);
 }
 
 /**
diff --git a/talkatu/talkatuview.c b/talkatu/talkatuview.c
--- a/talkatu/talkatuview.c
+++ b/talkatu/talkatuview.c
@@ -46,17 +46,11 @@
 typedef struct {
 	GSimpleActionGroup *action_group;
 
-	/* we cache the cursor that's displayed while hovering over a link as well
-	 * the tag for links/anchors to avoid extra lookups.
-	 */
-	GdkCursor *cursor_hand;
-
 	GtkWidget *menu;
 	gchar *url;
 } TalkatuViewPrivate;
 
 enum {
-	SIG_FORMAT_ACTIVATE,
 	SIG_OPEN_URL,
 	LAST_SIGNAL,
 };
@@ -121,8 +115,8 @@
  * Signal Handlers
  *****************************************************************************/
 static void
-talkatu_view_released_cb(GtkGestureClick *gesture, guint n_press, double wx,
-                         double wy, gpointer data)
+talkatu_view_pressed_cb(GtkGestureClick *gesture, guint n_press, double wx,
+                        double wy, gpointer data)
 {
 	TalkatuView *view = TALKATU_VIEW(data);
 	GtkTextIter iter;
@@ -162,9 +156,7 @@
                        gdouble wy, gpointer data)
 {
 	TalkatuView *view = TALKATU_VIEW(data);
-	TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
 	GtkTextIter iter;
-	GdkCursor *cursor = NULL;
 	const gchar *url = NULL;
 	gint x, y;
 
@@ -179,11 +171,9 @@
 
 	url = talkatu_view_url_from_iter(view, &iter);
 	if(url != NULL) {
-		cursor = priv->cursor_hand;
-	}
-
-	if(cursor != gtk_widget_get_cursor(GTK_WIDGET(view))) {
-		gtk_widget_set_cursor(GTK_WIDGET(view), cursor);
+		gtk_widget_set_cursor_from_name(GTK_WIDGET(view), "pointer");
+	} else {
+		gtk_widget_set_cursor_from_name(GTK_WIDGET(view), "text");
 	}
 }
 
@@ -257,49 +247,24 @@
 talkatu_view_finalize(GObject *obj) {
 	TalkatuViewPrivate *priv = talkatu_view_get_instance_private(TALKATU_VIEW(obj));
 
-	g_clear_object(&priv->cursor_hand);
 	g_clear_pointer(&priv->url, g_free);
 
 	G_OBJECT_CLASS(talkatu_view_parent_class)->finalize(obj);
 }
 
 static void
-talkatu_view_init(TalkatuView *view) {
+talkatu_view_dispose(GObject *obj) {
+	TalkatuView *view = TALKATU_VIEW(obj);
 	TalkatuViewPrivate *priv = talkatu_view_get_instance_private(view);
-	GtkEventController *controller = NULL;
-
-	gtk_widget_init_template(GTK_WIDGET(view));
 
-	priv->cursor_hand = gdk_cursor_new_from_name("pointer", NULL);
-
-	/* tell the widget class that we support tooltips.  This is used to show
-	 * link targets, and probably other stuff at some point.
-	 */
-	gtk_widget_set_has_tooltip(GTK_WIDGET(view), TRUE);
-
+	g_clear_pointer(&priv->menu, gtk_widget_unparent);
 
-	/* Connect some signals we care about */
-	controller = gtk_event_controller_motion_new();
-	g_signal_connect(controller, "motion", G_CALLBACK(talkatu_view_motion_cb),
-	                 view);
-	gtk_widget_add_controller(GTK_WIDGET(view), controller);
+	G_OBJECT_CLASS(talkatu_view_parent_class)->dispose(obj);
+}
 
-	controller = GTK_EVENT_CONTROLLER(gtk_gesture_click_new());
-	/* check all buttons */
-	gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(controller), 0);
-	g_signal_connect(controller, "released",
-	                 G_CALLBACK(talkatu_view_released_cb), view);
-	gtk_widget_add_controller(GTK_WIDGET(view), controller);
-
-	/* we need to know when the buffer is changed in our parent so we can
-	 * update our actions and other stuff.
-	 */
-	g_signal_connect(
-		G_OBJECT(view),
-		"notify::buffer",
-		G_CALLBACK(talkatu_view_buffer_set_cb),
-		NULL
-	);
+static void
+talkatu_view_init(TalkatuView *view) {
+	gtk_widget_init_template(GTK_WIDGET(view));
 }
 
 static void
@@ -308,6 +273,7 @@
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 	GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass);
 
+	obj_class->dispose = talkatu_view_dispose;
 	obj_class->finalize = talkatu_view_finalize;
 
 	widget_class->query_tooltip = talkatu_view_query_tooltip;
@@ -342,6 +308,13 @@
 		G_TYPE_STRING
 	);
 
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        talkatu_view_pressed_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        talkatu_view_motion_cb);
+	gtk_widget_class_bind_template_callback(widget_class,
+	                                        talkatu_view_buffer_set_cb);
+
 	gtk_widget_class_bind_template_child_private(widget_class, TalkatuView, menu);
 
 	/* add our actions */
