# HG changeset patch
# Node ID 254823aad7b0
# Parent  a5047abeede9
diff --git a/po/POTFILES b/po/POTFILES
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -6,6 +6,7 @@
 talkatu/data/editor.ui
 talkatu/data/historyrow.ui
 talkatu/data/history.ui
+talkatu/data/input.ui
 talkatu/data/linkdialog.ui
 talkatu/data/scrolledwindow.ui
 talkatu/data/toolbar.ui
diff --git a/talkatu/data/input.ui b/talkatu/data/input.ui
new file mode 100644
--- /dev/null
+++ b/talkatu/data/input.ui
@@ -0,0 +1,37 @@
+<?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 Pidgin -->
+  <!-- interface-description Internet Messenger -->
+  <!-- interface-copyright Pidgin Developers <devel@pidgin.im> -->
+  <menu id="model">
+    <section>
+      <item>
+        <attribute name="label" translatable="yes">_Send Message</attribute>
+        <attribute name="action">message.send</attribute>
+      </item>
+    </section>
+  </menu>
+  <template class="TalkatuInput" parent="TalkatuView">
+    <property name="extra-menu">model</property>
+  </template>
+</interface>
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
@@ -6,6 +6,7 @@
     <file compressed="true">editor.ui</file>
     <file compressed="true">history.ui</file>
     <file compressed="true">historyrow.ui</file>
+    <file compressed="true">input.ui</file>
     <file compressed="true">linkdialog.ui</file>
     <file compressed="true">scrolledwindow.ui</file>
     <file compressed="true">toolbar.ui</file>
diff --git a/talkatu/talkatuinput.h b/talkatu/talkatuinput.h
--- a/talkatu/talkatuinput.h
+++ b/talkatu/talkatuinput.h
@@ -48,7 +48,6 @@
 	TalkatuViewClass parent;
 
 	/*< public >*/
-	void (*should_send_message)(TalkatuInput *input, TalkatuInputSendBinding binding);
 	void (*send_message)(TalkatuInput *input);
 
 	/*< private >*/
diff --git a/talkatu/talkatuinput.c b/talkatu/talkatuinput.c
--- a/talkatu/talkatuinput.c
+++ b/talkatu/talkatuinput.c
@@ -45,8 +45,6 @@
 
 /**
  * TalkatuInputClass:
- * @should_send_message: The class handler for the
- *                       #TalkatuInput::should_send_message signal.
  * @send_message: The class handler for the #TalkatuInput::send_message signal.
  *
  * The backing class to #TalkatuInput instances.
@@ -64,8 +62,6 @@
  */
 
 typedef struct {
-	TalkatuView parent;
-
 	GHashTable *attachments;
 	guint64 attachment_id;
 
@@ -361,47 +357,30 @@
  * Callbacks
  *****************************************************************************/
 static void
-talkatu_input_send_message_cb(GtkMenuItem *item, gpointer data) {
-	talkatu_input_send_message(TALKATU_INPUT(data));
+talkatu_input_send_message_cb(GtkWidget *widget,
+                              G_GNUC_UNUSED const gchar *action_name,
+                              G_GNUC_UNUSED GVariant *parameter)
+{
+	talkatu_input_send_message(TALKATU_INPUT(widget));
 
-	gtk_widget_grab_focus(GTK_WIDGET(data));
+	gtk_widget_grab_focus(widget);
 }
 
-
 static void
-talkatu_input_populate_popup_cb(GtkTextView *view, GtkWidget *popup) {
-	TalkatuInputPrivate *priv = NULL;
-	GtkTextBuffer *buffer = NULL;
-	GtkTextIter iter;
-	GtkWidget *item = NULL;
-	gint pos = 0;
-
-	/* if the popup isn't a menu, bail */
-	if(!GTK_IS_MENU(popup)) {
-		return;
-	}
-
-	priv = talkatu_input_get_instance_private(TALKATU_INPUT(view));
-
-	buffer = gtk_text_view_get_buffer(view);
+talkatu_input_should_send_message_cb(GtkWidget *widget,
+                                     G_GNUC_UNUSED const gchar *action_name,
+                                     GVariant *parameter)
+{
+	TalkatuInput *input = TALKATU_INPUT(widget);
+	TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
+	TalkatuInputSendBinding binding = g_variant_get_uint32(parameter);
 
-	gtk_text_buffer_get_iter_at_mark(buffer, &iter, priv->context_mark);
+	if((priv->send_binding & binding) != 0) {
+		talkatu_input_send_message(input);
+	} else if(gtk_text_view_get_editable(GTK_TEXT_VIEW(input))) {
+		GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
 
-	/* add the send message item */
-	if(gtk_text_view_get_editable(view)) {
-		item = gtk_menu_item_new_with_label(_("Send message"));
-		g_signal_connect_after(
-			G_OBJECT(item),
-			"activate",
-			G_CALLBACK(talkatu_input_send_message_cb),
-			view
-		);
-		gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item, pos++);
-		gtk_widget_show(item);
-
-		item = gtk_separator_menu_item_new();
-		gtk_menu_shell_insert(GTK_MENU_SHELL(popup), item , pos++);
-		gtk_widget_show(item);
+		gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
 	}
 }
 
@@ -442,7 +421,7 @@
 		/* we call this separately for GTK_RESPONSE_CANCEL because
 		 * GTK_RESPONSE_DELETE_EVENT already destroys the dialog.
 		 */
-		gtk_widget_destroy(GTK_WIDGET(dialog));
+		gtk_window_destroy(GTK_WINDOW(dialog));
 	} else if(response == GTK_RESPONSE_ACCEPT) {
 		GtkTextBuffer *buffer = NULL;
 		TalkatuAttachment *attachment = NULL;
@@ -468,10 +447,13 @@
 		talkatu_input_send_message(input);
 
 		/* kill the dialog */
-		gtk_widget_destroy(GTK_WIDGET(dialog));
+		gtk_window_destroy(GTK_WINDOW(dialog));
 	}
+
+	g_object_unref(dialog);
 }
 
+#if 0
 static void
 talkatu_input_image_received_cb(GtkClipboard *clipboard, GdkPixbuf *pixbuf,
                                 gpointer data)
@@ -559,56 +541,25 @@
 	g_free(comment);
 	g_object_unref(G_OBJECT(stream));
 }
-
-/******************************************************************************
- * Default Signal Handlers
- *****************************************************************************/
-static gboolean
-talkatu_input_popup_menu(GtkWidget *widget) {
-	TalkatuInputPrivate *priv = talkatu_input_get_instance_private(TALKATU_INPUT(widget));
-	GtkTextBuffer *buffer = NULL;
-	GtkTextIter iter;
-
-	buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
-
-	gtk_text_buffer_get_iter_at_mark(
-		buffer,
-		&iter,
-		gtk_text_buffer_get_insert(buffer)
-	);
-
-	gtk_text_buffer_move_mark(buffer, priv->context_mark, &iter);
-
-	return GTK_WIDGET_CLASS(talkatu_input_parent_class)->popup_menu(widget);
-}
-
-static void
-talkatu_input_should_send_message(TalkatuInput *input, TalkatuInputSendBinding binding) {
-	TalkatuInputPrivate *priv = talkatu_input_get_instance_private(input);
-
-	if((priv->send_binding & binding) != 0) {
-		talkatu_input_send_message(input);
-	} else if(gtk_text_view_get_editable(GTK_TEXT_VIEW(input))) {
-		GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(input));
-
-		gtk_text_buffer_insert_at_cursor(buffer, "\n", 1);
-	}
-}
+#endif
 
 /******************************************************************************
  * GtkTextViewClass overrides
  *****************************************************************************/
 static void
 talkatu_input_paste_clipboard(GtkTextView *view) {
-	GtkClipboard *clipboard =
-		gtk_widget_get_clipboard(GTK_WIDGET(view), GDK_SELECTION_CLIPBOARD);
+#if 0
+	GdkClipboard *clipboard = gtk_widget_get_clipboard(GTK_WIDGET(view));
 
 	if(gtk_clipboard_wait_is_image_available(clipboard)) {
 		gtk_clipboard_request_image(clipboard, talkatu_input_image_received_cb,
 		                            view);
 	} else {
+#endif
 		GTK_TEXT_VIEW_CLASS(talkatu_input_parent_class)->paste_clipboard(view);
+#if 0
 	}
+#endif
 }
 
 /******************************************************************************
@@ -700,16 +651,6 @@
 		G_CALLBACK(talkatu_input_buffer_set_cb),
 		NULL
 	);
-
-	/* we need to connect this signal *AFTER* everything to make sure our items
-	 * end up in the correct place.
-	 */
-	g_signal_connect_after(
-		G_OBJECT(input),
-		"populate-popup",
-		G_CALLBACK(talkatu_input_populate_popup_cb),
-		NULL
-	);
 }
 
 static void
@@ -732,18 +673,13 @@
 	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
 	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass);
 	GtkTextViewClass *text_view_class = GTK_TEXT_VIEW_CLASS(klass);
-	GtkBindingSet *binding_set = NULL;
 
 	obj_class->get_property = talkatu_input_get_property;
 	obj_class->set_property = talkatu_input_set_property;
 	obj_class->finalize = talkatu_input_finalize;
 
-	widget_class->popup_menu = talkatu_input_popup_menu;
-
 	text_view_class->paste_clipboard = talkatu_input_paste_clipboard;
 
-	klass->should_send_message = talkatu_input_should_send_message;
-
 	/* add our properties */
 	properties[PROP_SEND_BINDING] = g_param_spec_flags(
 		"send-binding", "send-binding", "The keybindings that will trigger the send signal",
@@ -763,28 +699,6 @@
 	g_object_class_override_property(obj_class, PROP_EDITED, "edited");
 
 	/**
-	 * TalkatuInput::should-send-message:
-	 * @talkatuinput: The #TalkatuInput instance.
-	 * @arg1: The #TalkatuInputSendBinding that was entered.
-	 * @user_data: User supplied data.
-	 *
-	 * Emitted when a potential keybinding to send the message is entered to
-	 * determine if the message should be sent.
-	 */
-	signals[SIG_SHOULD_SEND_MESSAGE] = g_signal_new(
-		"should-send-message",
-		G_TYPE_FROM_CLASS(klass),
-		G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
-		G_STRUCT_OFFSET(TalkatuInputClass, should_send_message),
-		NULL,
-		NULL,
-		NULL,
-		G_TYPE_NONE,
-		1,
-		TALKATU_TYPE_INPUT_SEND_BINDING
-	);
-
-	/**
 	 * TalkatuInput::send-message:
 	 * @talkatuinput: The #TalkatuInput instance.
 	 * @user_data: User supplied data.
@@ -803,13 +717,33 @@
 		0
 	);
 
-	/* setup key bindings */
-	binding_set = gtk_binding_set_by_class(talkatu_input_parent_class);
+	/* Setup actions */
+	gtk_widget_class_install_action(widget_class, "message.send", NULL,
+	                                talkatu_input_send_message_cb);
+	gtk_widget_class_install_action(widget_class, "message.should-send", NULL,
+	                                talkatu_input_should_send_message_cb);
+
+	/* Template setup */
+	gtk_widget_class_set_template_from_resource(
+		widget_class,
+		"/org/imfreedom/keep/talkatu/talkatu/ui/input.ui"
+	);
 
-	gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, 0, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_RETURN);
-	gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_SHIFT_MASK, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_SHIFT_RETURN);
-	gtk_binding_entry_add_signal(binding_set, GDK_KEY_Return, GDK_CONTROL_MASK, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_CONTROL_RETURN);
-	gtk_binding_entry_add_signal(binding_set, GDK_KEY_KP_Enter, 0, "should-send-message", 1, TALKATU_TYPE_INPUT_SEND_BINDING, TALKATU_INPUT_SEND_BINDING_KP_ENTER);
+	/* setup key bindings */
+	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",
+	                                    TALKATU_INPUT_SEND_BINDING_SHIFT_RETURN);
+	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,
+	                                    "message.should-send", "u",
+	                                    TALKATU_INPUT_SEND_BINDING_KP_ENTER);
 }
 
 /******************************************************************************
