Create a full widget for the new instant message window
This now uses AdwMessageDialog and is self contained but PidginApplication
manages a singleton of it.
Previously this used the request api. I'm not sure why, as the request fields
were created by the ui itself.
Testing Done:
Created an im with `Echo` on a `demo` account and was able to send and receive messages.
Reviewed at https://reviews.imfreedom.org/r/2896/
--- a/ChangeLog.API Tue Jan 02 00:33:16 2024 -0600
+++ b/ChangeLog.API Tue Jan 02 00:36:32 2024 -0600
@@ -1067,6 +1067,7 @@
* pidgin_dialogs_alias_chat
* pidgin_dialogs_alias_contact
* pidgin_dialogs_destroy_all
* pidgin_dialogs_merge_groups
* pidgin_dialogs_remove_buddy
--- a/pidgin/gtkdialogs.c Tue Jan 02 00:33:16 2024 -0600
+++ b/pidgin/gtkdialogs.c Tue Jan 02 00:36:32 2024 -0600
@@ -31,81 +31,6 @@
-pidgin_dialogs_im_cb(G_GNUC_UNUSED gpointer data, PurpleRequestPage *page) {
- PurpleAccount *account;
- account = purple_request_page_get_account(page, "account");
- username = purple_request_page_get_string(page, "screenname");
- pidgin_dialogs_im_with_user(account, username);
-pidgin_dialogs_im_name_validator(PurpleRequestField *field, char **errmsg,
- PurpleRequestFieldAccount *account_field = data;
- PurpleAccount *account;
- PurpleProtocol *protocol;
- gboolean valid = FALSE;
- account = purple_request_field_account_get_value(account_field);
- protocol = purple_account_get_protocol(account);
- username = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
- valid = purple_validate(protocol, username);
- *errmsg = g_strdup(_("Invalid username"));
- PurpleRequestPage *page;
- PurpleRequestGroup *group;
- PurpleRequestField *username_field = NULL;
- PurpleRequestField *account_field = NULL;
- page = purple_request_page_new();
- group = purple_request_group_new(NULL);
- purple_request_page_add_group(page, group);
- account_field = purple_request_field_account_new("account", _("_Account"),
- purple_request_field_set_type_hint(account_field, "account");
- purple_request_field_set_visible(account_field,
- (purple_connections_get_all() != NULL &&
- purple_connections_get_all()->next != NULL));
- purple_request_field_set_required(account_field, TRUE);
- purple_request_group_add_field(group, account_field);
- purple_request_field_set_validator(username_field,
- pidgin_dialogs_im_name_validator,
- username_field = purple_request_field_string_new("screenname", _("_Name"),
- purple_request_field_set_type_hint(username_field, "screenname");
- purple_request_field_set_required(username_field, TRUE);
- purple_request_group_add_field(group, username_field);
- purple_blist_get_default(), _("New Instant Message"), NULL,
- _("Please enter the username or alias of the person "
- "you would like to IM."),
- page, _("OK"), G_CALLBACK(pidgin_dialogs_im_cb), _("Cancel"),
pidgin_dialogs_im_with_user(PurpleAccount *account, const char *username)
--- a/pidgin/gtkdialogs.h Tue Jan 02 00:33:16 2024 -0600
+++ b/pidgin/gtkdialogs.h Tue Jan 02 00:36:32 2024 -0600
@@ -33,9 +33,6 @@
-void pidgin_dialogs_im(void);
void pidgin_dialogs_im_with_user(PurpleAccount *account, const char *username);
--- a/pidgin/meson.build Tue Jan 02 00:33:16 2024 -0600
+++ b/pidgin/meson.build Tue Jan 02 00:36:32 2024 -0600
@@ -37,6 +37,7 @@
@@ -94,6 +95,7 @@
--- a/pidgin/pidginapplication.c Tue Jan 02 00:33:16 2024 -0600
+++ b/pidgin/pidginapplication.c Tue Jan 02 00:36:32 2024 -0600
@@ -44,6 +44,7 @@
#include "pidgindisplaywindow.h"
+#include "pidginimwindow.h" #include "pidginpluginsdialog.h"
#include "pidginpluginsmenu.h"
@@ -447,9 +448,18 @@
pidgin_application_new_message(G_GNUC_UNUSED GSimpleAction *simple,
G_GNUC_UNUSED GVariant *parameter,
- G_GNUC_UNUSED gpointer data)
+ PidginApplication *application = data; + static GtkWidget *dialog = NULL; + if(!PIDGIN_IS_IM_WINDOW(dialog)) { + dialog = pidgin_im_window_new(); + g_object_add_weak_pointer(G_OBJECT(dialog), (gpointer)&dialog); + pidgin_application_present_transient_window(application, --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginimwindow.c Tue Jan 02 00:36:32 2024 -0600
@@ -0,0 +1,143 @@
+ * Pidgin - Internet Messenger + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * Pidgin is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * This program 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 program 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 program; if not, see <https://www.gnu.org/licenses/>. +#include "pidginimwindow.h" +#include "pidginaccountrow.h" +struct _PidginIMWindow { + AdwMessageDialog parent; + GtkCustomFilter *filter; +/****************************************************************************** + *****************************************************************************/ +pidgin_im_window_filter_accounts(gpointer item, G_GNUC_UNUSED gpointer data) { + if(PURPLE_IS_ACCOUNT(item)) { + PurpleAccount *account = PURPLE_ACCOUNT(item); + PurpleProtocol *protocol = purple_account_get_protocol(account); + if(PURPLE_IS_PROTOCOL(protocol)) { + return PURPLE_PROTOCOL_IMPLEMENTS(protocol, CONVERSATION, +/****************************************************************************** + *****************************************************************************/ +pidgin_im_window_username_changed_cb(GtkEditable *self, gpointer data) { + const char *text = NULL; + gboolean enabled = FALSE; + text = gtk_editable_get_text(self); + enabled = !purple_strempty(text); + adw_message_dialog_set_response_enabled(data, "okay", enabled); +pidgin_im_window_response_cb(AdwMessageDialog *self, + G_GNUC_UNUSED gpointer data) + PidginIMWindow *window = PIDGIN_IM_WINDOW(self); + PurpleAccount *account = NULL; + PurpleConversation *im = NULL; + PurpleConversationManager *manager = NULL; + const char *username = NULL; + if(!purple_strequal(response, "okay")) { + account = pidgin_account_row_get_account(PIDGIN_ACCOUNT_ROW(window->account)) ; + username = gtk_editable_get_text(GTK_EDITABLE(window->username)); + manager = purple_conversation_manager_get_default(); + im = purple_conversation_manager_find_im(manager, account, username); + if(!PURPLE_IS_IM_CONVERSATION(im)) { + /* This constructor automagically registers the conversation with the + purple_im_conversation_new(account, username); +/****************************************************************************** + * GObject Implementation + *****************************************************************************/ +G_DEFINE_TYPE(PidginIMWindow, pidgin_im_window, ADW_TYPE_MESSAGE_DIALOG) +pidgin_im_window_init(PidginIMWindow *window) { + gtk_widget_init_template(GTK_WIDGET(window)); + gtk_custom_filter_set_filter_func(window->filter, + pidgin_im_window_filter_accounts, +pidgin_im_window_class_init(PidginIMWindowClass *klass) { + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); + gtk_widget_class_set_template_from_resource( + "/im/pidgin/Pidgin3/imwindow.ui" + gtk_widget_class_bind_template_child(widget_class, PidginIMWindow, + gtk_widget_class_bind_template_child(widget_class, PidginIMWindow, + gtk_widget_class_bind_template_child(widget_class, PidginIMWindow, + gtk_widget_class_bind_template_callback(widget_class, + pidgin_im_window_username_changed_cb); + gtk_widget_class_bind_template_callback(widget_class, + pidgin_im_window_response_cb); +/****************************************************************************** + *****************************************************************************/ +pidgin_im_window_new(void) { + return g_object_new(PIDGIN_TYPE_IM_WINDOW, NULL); --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/pidginimwindow.h Tue Jan 02 00:36:32 2024 -0600
@@ -0,0 +1,65 @@
+ * Pidgin - Internet Messenger + * Copyright (C) Pidgin Developers <devel@pidgin.im> + * Pidgin is the legal property of its developers, whose names are too numerous + * to list here. Please refer to the COPYRIGHT file distributed with this + * This program 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 program 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 program; if not, see <https://www.gnu.org/licenses/>. +#if !defined(PIDGIN_GLOBAL_HEADER_INSIDE) && !defined(PIDGIN_COMPILATION) +# error "only <pidgin.h> may be included directly" +#ifndef PIDGIN_IM_WINDOW_H +#define PIDGIN_IM_WINDOW_H +#include "pidginversion.h" + * A window used to start a new direct message. +#define PIDGIN_TYPE_IM_WINDOW (pidgin_im_window_get_type()) +G_DECLARE_FINAL_TYPE(PidginIMWindow, pidgin_im_window, + PIDGIN, IM_WINDOW, AdwMessageDialog) + * pidgin_im_window_new: + * Creates a new #PidginIMWindow instance. + * Returns: (transfer full): The new #PidginIMWindow instance. +GtkWidget *pidgin_im_window_new(void); +#endif /* PIDGIN_IM_WINDOW_H */ --- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pidgin/resources/imwindow.ui Tue Jan 02 00:36:32 2024 -0600
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?> +Pidgin - Internet Messenger +Copyright (C) Pidgin Developers <devel@pidgin.im> +This program 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 program 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/>. + <requires lib="gtk" version="4.0"/> + <!-- interface-license-type gplv2 --> + <!-- interface-name Pidgin --> + <!-- interface-description Internet Messenger --> + <!-- interface-copyright Pidgin Developers <devel@pidgin.im> --> + <template class="PidginIMWindow" parent="AdwMessageDialog"> + <property name="heading" translatable="yes">New Instant Message</property> + <property name="body" translatable="yes">Please enter the username or alias of the person you would like to IM.</property> + <property name="extra-child"> + <object class="AdwPreferencesGroup"> + <property name="vexpand">true</property> + <property name="hexpand">true</property> + <object class="PidginAccountRow" id="account"> + <property name="filter"> + <object class="GtkEveryFilter"> + <object class="GtkCustomFilter" id="filter"/> + <object class="PidginAccountFilterConnected"/> + <object class="AdwEntryRow" id="username"> + <property name="focusable">no</property> + <property name="title" translatable="yes">_Username</property> + <property name="use-underline">yes</property> + <property name="activates-default">yes</property> + <signal name="changed" handler="pidgin_im_window_username_changed_cb"/> + <property name="default-response">okay</property> + <property name="close-response">cancel</property> + <response id="cancel" translatable="yes">_Cancel</response> + <response id="okay" translatable="yes" appearance="suggested" enabled="false">_Okay</response> + <signal name="response" handler="pidgin_im_window_response_cb"/> --- a/pidgin/resources/pidgin.gresource.xml Tue Jan 02 00:33:16 2024 -0600
+++ b/pidgin/resources/pidgin.gresource.xml Tue Jan 02 00:36:32 2024 -0600
@@ -43,6 +43,7 @@
<file compressed="true" preprocess="xml-stripblanks">channeljoindialog.ui</file>
<file compressed="true" preprocess="xml-stripblanks">contactlistitem.ui</file>
<file compressed="true" preprocess="xml-stripblanks">conversationmemberlistitem.ui</file>
+ <file compressed="true" preprocess="xml-stripblanks">imwindow.ui</file> <file compressed="true" preprocess="xml-stripblanks">presenceicon.ui</file>
<file>icons/16x16/status/pidgin-user-available.png</file>
<file>icons/16x16/status/pidgin-user-away.png</file>