# HG changeset patch
# Node ID 2eb69d01f7b6dc1172fdddf71fd0ea388602e8fe
# Parent  c6ca43acffbb27749fad75ff59d3697051c8861f
diff --git a/libpurple/purpleconversation.c b/libpurple/purpleconversation.c
--- a/libpurple/purpleconversation.c
+++ b/libpurple/purpleconversation.c
@@ -72,6 +72,7 @@
 	GDateTime *last_typing;
 
 	gboolean logging;
+	gboolean drafting;
 };
 
 enum {
@@ -103,6 +104,7 @@
 	PROP_NEEDS_ATTENTION,
 	PROP_TYPING_STATE,
 	PROP_LOGGING,
+	PROP_DRAFTING,
 	N_PROPERTIES,
 };
 static GParamSpec *properties[N_PROPERTIES] = {NULL, };
@@ -475,6 +477,10 @@
 		purple_conversation_set_logging(conversation,
 		                                g_value_get_boolean(value));
 		break;
+	case PROP_DRAFTING:
+		purple_conversation_set_drafting(conversation,
+		                                 g_value_get_boolean(value));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 		break;
@@ -590,6 +596,10 @@
 		g_value_set_boolean(value,
 		                    purple_conversation_get_logging(conversation));
 		break;
+	case PROP_DRAFTING:
+		g_value_set_boolean(value,
+		                    purple_conversation_get_drafting(conversation));
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
 		break;
@@ -1104,6 +1114,22 @@
 		FALSE,
 		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
+	/**
+	 * PurpleConversation:drafting:
+	 *
+	 * Whether or not the user has drafted a message for this conversation.
+	 *
+	 * This will not be set to false after a call to
+	 * [method@Conversation.write_message] as anything can call that which
+	 * could break the accounting of this property.
+	 *
+	 * Since: 3.0
+	 */
+	properties[PROP_DRAFTING] = g_param_spec_boolean(
+		"drafting", NULL, NULL,
+		FALSE,
+		G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
 	g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
 
 	/**
@@ -1875,3 +1901,24 @@
 		                         properties[PROP_LOGGING]);
 	}
 }
+
+gboolean
+purple_conversation_get_drafting(PurpleConversation *conversation) {
+	g_return_val_if_fail(PURPLE_IS_CONVERSATION(conversation), FALSE);
+
+	return conversation->drafting;
+}
+
+void
+purple_conversation_set_drafting(PurpleConversation *conversation,
+                                 gboolean drafting)
+{
+	g_return_if_fail(PURPLE_IS_CONVERSATION(conversation));
+
+	if(conversation->drafting != drafting) {
+		conversation->drafting = drafting;
+
+		g_object_notify_by_pspec(G_OBJECT(conversation),
+		                         properties[PROP_DRAFTING]);
+	}
+}
diff --git a/libpurple/purpleconversation.h b/libpurple/purpleconversation.h
--- a/libpurple/purpleconversation.h
+++ b/libpurple/purpleconversation.h
@@ -884,6 +884,41 @@
 PURPLE_AVAILABLE_IN_3_0
 void purple_conversation_set_logging(PurpleConversation *conversation, gboolean logging);
 
+/**
+ * purple_conversation_get_drafting:
+ * @conversation: The instance.
+ *
+ * Gets whether or not the user is currently drafting a message in
+ * @conversation.
+ *
+ * This is similar to [property@Conversation:typing-state] except there is no
+ * timeout.
+ *
+ * This is typically just for user interfaces, but might be useful elsewhere.
+ *
+ * Returns: %TRUE if the user has entered text into the input widget for
+ *          @conversation otherwise %FALSE.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+gboolean purple_conversation_get_drafting(PurpleConversation *conversation);
+
+/**
+ * purple_conversation_set_drafting:
+ * @conversation: The instance.
+ * @drafting: The new state.
+ *
+ * Sets the drafting state of @conversation to @drafting.
+ *
+ * This can be used by user interfaces to keep track of whether the user has
+ * started drafting a message for this conversation.
+ *
+ * Since: 3.0
+ */
+PURPLE_AVAILABLE_IN_3_0
+void purple_conversation_set_drafting(PurpleConversation *conversation, gboolean drafting);
+
 G_END_DECLS
 
 #endif /* PURPLE_CONVERSATION_H */
diff --git a/libpurple/tests/test_conversation.c b/libpurple/tests/test_conversation.c
--- a/libpurple/tests/test_conversation.c
+++ b/libpurple/tests/test_conversation.c
@@ -72,6 +72,7 @@
 	gboolean favorite = FALSE;
 	gboolean needs_attention = FALSE;
 	gboolean logging = FALSE;
+	gboolean drafting = FALSE;
 
 	account = g_object_new(
 		PURPLE_TYPE_ACCOUNT,
@@ -98,6 +99,7 @@
 		"created-on", created_on,
 		"creator", creator,
 		"description", "to describe or not to describe...",
+		"drafting", TRUE,
 		"favorite", TRUE,
 		"id", "id1",
 		"logging", TRUE,
@@ -121,6 +123,7 @@
 		"created-on", &created_on1,
 		"creator", &creator1,
 		"description", &description,
+		"drafting", &drafting,
 		"favorite", &favorite,
 		"global-id", &global_id,
 		"id", &id,
@@ -161,6 +164,8 @@
 	g_assert_cmpstr(description, ==, "to describe or not to describe...");
 	g_clear_pointer(&description, g_free);
 
+	g_assert_true(drafting);
+
 	g_assert_true(favorite);
 
 	g_assert_cmpstr(global_id, ==, "test-id1");
