aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheJackiMonster <thejackimonster@gmail.com>2022-03-10 02:19:37 +0100
committerTheJackiMonster <thejackimonster@gmail.com>2022-03-10 02:19:37 +0100
commit4065995bbc9f0c605b63e57574753e7c7ee9985c (patch)
treedee9eddc5f5b79bbbf2e755d3ef7b044d41b8be7
parent3090047dcd647bd1daddf904472a7f909b00f875 (diff)
downloadmessenger-gtk-4065995bbc9f0c605b63e57574753e7c7ee9985c.tar.gz
messenger-gtk-4065995bbc9f0c605b63e57574753e7c7ee9985c.zip
Replaced unstable bindings with glib quark data
Signed-off-by: TheJackiMonster <thejackimonster@gmail.com>
-rw-r--r--Makefile1
-rw-r--r--src/application.c6
-rw-r--r--src/application.h7
-rw-r--r--src/bindings.c129
-rw-r--r--src/bindings.h60
-rw-r--r--src/event.c17
-rw-r--r--src/ui/accounts.c51
-rw-r--r--src/ui/accounts.h2
-rw-r--r--src/ui/chat.c73
-rw-r--r--src/ui/chat_entry.c4
-rw-r--r--src/ui/chat_entry.h5
-rw-r--r--src/ui/contacts.c60
-rw-r--r--src/ui/contacts.h3
-rw-r--r--src/ui/invite_contact.c64
-rw-r--r--src/ui/invite_contact.h3
-rw-r--r--src/ui/message.c16
-rw-r--r--src/ui/messenger.c68
-rw-r--r--src/ui/new_group.c4
-rw-r--r--src/ui/send_file.c4
19 files changed, 160 insertions, 417 deletions
diff --git a/Makefile b/Makefile
index b19a57a..0ccef0c 100644
--- a/Makefile
+++ b/Makefile
@@ -8,7 +8,6 @@ INSTALL_DIR ?= /usr/local/
8BINARY = messenger-gtk 8BINARY = messenger-gtk
9SOURCES = messenger_gtk.c\ 9SOURCES = messenger_gtk.c\
10 application.c\ 10 application.c\
11 bindings.c\
12 contact.c\ 11 contact.c\
13 event.c\ 12 event.c\
14 file.c\ 13 file.c\
diff --git a/src/application.c b/src/application.c
index 397621c..fd6b86f 100644
--- a/src/application.c
+++ b/src/application.c
@@ -100,7 +100,9 @@ application_init(MESSENGER_Application *app,
100 100
101 pthread_mutex_init(&(app->chat.mutex), NULL); 101 pthread_mutex_init(&(app->chat.mutex), NULL);
102 102
103 app->bindings = bindings_create(); 103 app->quarks.widget = g_quark_from_string("messenger_widget");
104 app->quarks.data = g_quark_from_string("messenger_data");
105 app->quarks.ui = g_quark_from_string("messenger_ui");
104 106
105 g_application_add_main_option( 107 g_application_add_main_option(
106 G_APPLICATION(app->application), 108 G_APPLICATION(app->application),
@@ -195,8 +197,6 @@ application_run(MESSENGER_Application *app)
195 197
196 pthread_join(app->chat.tid, NULL); 198 pthread_join(app->chat.tid, NULL);
197 199
198 bindings_destroy(app->bindings);
199
200 close(app->chat.pipe[0]); 200 close(app->chat.pipe[0]);
201 close(app->chat.pipe[1]); 201 close(app->chat.pipe[1]);
202 202
diff --git a/src/application.h b/src/application.h
index 99fcc69..3520f09 100644
--- a/src/application.h
+++ b/src/application.h
@@ -42,7 +42,6 @@
42#include "ui/send_file.h" 42#include "ui/send_file.h"
43#include "ui/settings.h" 43#include "ui/settings.h"
44 44
45#include "bindings.h"
46#include "util.h" 45#include "util.h"
47 46
48typedef enum MESSENGER_ApplicationSignal 47typedef enum MESSENGER_ApplicationSignal
@@ -60,7 +59,11 @@ typedef struct MESSENGER_Application
60 GtkApplication *application; 59 GtkApplication *application;
61 GList *notifications; 60 GList *notifications;
62 61
63 MESSENGER_Bindings *bindings; 62 struct {
63 GQuark widget;
64 GQuark data;
65 GQuark ui;
66 } quarks;
64 67
65 struct { 68 struct {
66 int status; 69 int status;
diff --git a/src/bindings.c b/src/bindings.c
deleted file mode 100644
index b7325d4..0000000
--- a/src/bindings.c
+++ /dev/null
@@ -1,129 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file bindings.h
23 */
24
25#include "bindings.h"
26#include "util.h"
27
28MESSENGER_Bindings*
29bindings_create()
30{
31 MESSENGER_Bindings *bindings = GNUNET_new(MESSENGER_Bindings);
32
33 bindings->map = GNUNET_CONTAINER_multishortmap_create(8, GNUNET_NO);
34
35 return bindings;
36}
37
38void
39bindings_put(MESSENGER_Bindings *bindings,
40 gconstpointer key,
41 gpointer value)
42{
43 struct GNUNET_ShortHashCode hash;
44 memset(&hash, 0, sizeof(hash));
45 memcpy(&hash, &key, sizeof(key));
46
47 GNUNET_CONTAINER_multishortmap_put(
48 bindings->map,
49 &hash,
50 (void*) value,
51 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE
52 );
53}
54
55int
56_bindings_append_list(void *cls,
57 UNUSED const struct GNUNET_ShortHashCode *key,
58 void *value)
59{
60 GList **list = (GList**) cls;
61 *list = g_list_append(*list, (gpointer) value);
62 return GNUNET_YES;
63}
64
65void
66bindings_remove(MESSENGER_Bindings *bindings,
67 const void *key,
68 void *value,
69 void (destroy)(void*))
70{
71 struct GNUNET_ShortHashCode hash;
72 memset(&hash, 0, sizeof(hash));
73 memcpy(&hash, &key, sizeof(key));
74
75 if (value)
76 {
77 GNUNET_CONTAINER_multishortmap_remove(
78 bindings->map,
79 &hash,
80 (void*) value
81 );
82
83 if (destroy)
84 destroy(value);
85 }
86 else
87 {
88 GList *values = NULL;
89
90 GNUNET_CONTAINER_multishortmap_get_multiple(
91 bindings->map,
92 &hash,
93 _bindings_append_list,
94 &values
95 );
96
97 GNUNET_CONTAINER_multishortmap_remove_all(
98 bindings->map,
99 &hash
100 );
101
102 if (destroy)
103 g_list_free_full(values, destroy);
104 else
105 g_list_free(values);
106 }
107}
108
109void*
110bindings_get(const MESSENGER_Bindings *bindings,
111 const void *key)
112{
113 struct GNUNET_ShortHashCode hash;
114 memset(&hash, 0, sizeof(hash));
115 memcpy(&hash, &key, sizeof(key));
116
117 return GNUNET_CONTAINER_multishortmap_get(
118 bindings->map,
119 &hash
120 );
121}
122
123void
124bindings_destroy(MESSENGER_Bindings *bindings)
125{
126 GNUNET_CONTAINER_multishortmap_destroy(bindings->map);
127
128 GNUNET_free(bindings);
129}
diff --git a/src/bindings.h b/src/bindings.h
deleted file mode 100644
index bf6e10b..0000000
--- a/src/bindings.h
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2022 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/*
21 * @author Tobias Frisch
22 * @file bindings.h
23 */
24
25#ifndef BINDINGS_H_
26#define BINDINGS_H_
27
28#include <gnunet/platform.h>
29#include <gnunet/gnunet_common.h>
30#include <gnunet/gnunet_container_lib.h>
31
32#include <glib.h>
33
34typedef struct MESSENGER_Bindings
35{
36 struct GNUNET_CONTAINER_MultiShortmap *map;
37} MESSENGER_Bindings;
38
39MESSENGER_Bindings*
40bindings_create();
41
42void
43bindings_put(MESSENGER_Bindings *bindings,
44 gconstpointer key,
45 gpointer value);
46
47void
48bindings_remove(MESSENGER_Bindings *bindings,
49 gconstpointer key,
50 gpointer value,
51 GDestroyNotify destroy);
52
53void*
54bindings_get(const MESSENGER_Bindings *bindings,
55 gconstpointer key);
56
57void
58bindings_destroy(MESSENGER_Bindings *bindings);
59
60#endif /* BINDINGS_H_ */
diff --git a/src/event.c b/src/event.c
index 71701db..c4f3a19 100644
--- a/src/event.c
+++ b/src/event.c
@@ -117,7 +117,11 @@ _add_new_chat_entry(MESSENGER_Application *app,
117 entry->chat->chat_box 117 entry->chat->chat_box
118 ); 118 );
119 119
120 bindings_put(app->bindings, entry->chat->send_text_view, context); 120 g_object_set_qdata(
121 G_OBJECT(entry->chat->send_text_view),
122 app->quarks.data,
123 context
124 );
121 125
122 ui->chat_entries = g_list_append(ui->chat_entries, entry); 126 ui->chat_entries = g_list_append(ui->chat_entries, entry);
123 127
@@ -125,7 +129,11 @@ _add_new_chat_entry(MESSENGER_Application *app,
125 gtk_widget_get_parent(entry->entry_box) 129 gtk_widget_get_parent(entry->entry_box)
126 ); 130 );
127 131
128 bindings_put(app->bindings, row, entry); 132 g_object_set_qdata(
133 G_OBJECT(row),
134 app->quarks.ui,
135 entry
136 );
129 137
130 gtk_list_box_select_row(ui->chats_listbox, row); 138 gtk_list_box_select_row(ui->chats_listbox, row);
131 gtk_list_box_invalidate_filter(ui->chats_listbox); 139 gtk_list_box_invalidate_filter(ui->chats_listbox);
@@ -252,7 +260,7 @@ event_joining_contact(MESSENGER_Application *app,
252 return; 260 return;
253 261
254 UI_MESSAGE_Handle *message = (UI_MESSAGE_Handle*) ( 262 UI_MESSAGE_Handle *message = (UI_MESSAGE_Handle*) (
255 bindings_get(handle->joining, contact) 263 GNUNET_CHAT_member_get_user_pointer(context, contact)
256 ); 264 );
257 265
258 if (message) 266 if (message)
@@ -288,7 +296,8 @@ event_joining_contact(MESSENGER_Application *app,
288 gtk_label_set_text(message->timestamp_label, time? time : ""); 296 gtk_label_set_text(message->timestamp_label, time? time : "");
289 297
290 ui_chat_add_message(handle->chat, app, message); 298 ui_chat_add_message(handle->chat, app, message);
291 bindings_put(handle->joining, contact, message); 299
300 GNUNET_CHAT_member_set_user_pointer(context, contact, message);
292 301
293 ui_chat_entry_update(handle, app, context); 302 ui_chat_entry_update(handle, app, context);
294} 303}
diff --git a/src/ui/accounts.c b/src/ui/accounts.c
index 0741654..969c23d 100644
--- a/src/ui/accounts.c
+++ b/src/ui/accounts.c
@@ -72,7 +72,7 @@ handle_accounts_listbox_row_activated(UNUSED GtkListBox* listbox,
72 } 72 }
73 73
74 struct GNUNET_CHAT_Account *account = (struct GNUNET_CHAT_Account*) ( 74 struct GNUNET_CHAT_Account *account = (struct GNUNET_CHAT_Account*) (
75 bindings_get(app->bindings, row) 75 g_object_get_qdata(G_OBJECT(row), app->quarks.data)
76 ); 76 );
77 77
78 if (!account) 78 if (!account)
@@ -119,8 +119,14 @@ _iterate_accounts(void *cls,
119 gtk_widget_get_parent(entry->entry_box) 119 gtk_widget_get_parent(entry->entry_box)
120 ); 120 );
121 121
122 bindings_put(app->bindings, row, account); 122 g_object_set_qdata(G_OBJECT(row), app->quarks.data, account);
123 bindings_put(app->ui.accounts.bindings, row, entry); 123
124 g_object_set_qdata_full(
125 G_OBJECT(row),
126 app->quarks.ui,
127 entry,
128 (GDestroyNotify) ui_account_entry_delete
129 );
124 130
125 return GNUNET_YES; 131 return GNUNET_YES;
126} 132}
@@ -129,7 +135,6 @@ void
129ui_accounts_dialog_init(MESSENGER_Application *app, 135ui_accounts_dialog_init(MESSENGER_Application *app,
130 UI_ACCOUNTS_Handle *handle) 136 UI_ACCOUNTS_Handle *handle)
131{ 137{
132 handle->bindings = bindings_create();
133 handle->show_queued = 0; 138 handle->show_queued = 0;
134 139
135 handle->builder = gtk_builder_new_from_resource( 140 handle->builder = gtk_builder_new_from_resource(
@@ -175,10 +180,13 @@ ui_accounts_dialog_init(MESSENGER_Application *app,
175 ); 180 );
176} 181}
177 182
178static void 183void
179_clear_accounts_listbox_rows(UI_ACCOUNTS_Handle *handle, 184ui_accounts_dialog_refresh(MESSENGER_Application *app,
180 gboolean bindings_only) 185 UI_ACCOUNTS_Handle *handle)
181{ 186{
187 if (!(handle->accounts_listbox))
188 return;
189
182 GList *list = gtk_container_get_children( 190 GList *list = gtk_container_get_children(
183 GTK_CONTAINER(handle->accounts_listbox) 191 GTK_CONTAINER(handle->accounts_listbox)
184 ); 192 );
@@ -190,32 +198,14 @@ _clear_accounts_listbox_rows(UI_ACCOUNTS_Handle *handle,
190 if ((!row) || (!gtk_list_box_row_get_selectable(row))) 198 if ((!row) || (!gtk_list_box_row_get_selectable(row)))
191 goto skip_row; 199 goto skip_row;
192 200
193 if (!bindings_only) 201 gtk_container_remove(
194 gtk_container_remove( 202 GTK_CONTAINER(handle->accounts_listbox),
195 GTK_CONTAINER(handle->accounts_listbox), 203 GTK_WIDGET(row)
196 GTK_WIDGET(row)
197 );
198
199 bindings_remove(
200 handle->bindings,
201 row,
202 NULL,
203 (GDestroyNotify) ui_account_entry_delete
204 ); 204 );
205 205
206 skip_row: 206 skip_row:
207 list = list->next; 207 list = list->next;
208 } 208 }
209}
210
211void
212ui_accounts_dialog_refresh(MESSENGER_Application *app,
213 UI_ACCOUNTS_Handle *handle)
214{
215 if (!(handle->accounts_listbox))
216 return;
217
218 _clear_accounts_listbox_rows(handle, FALSE);
219 209
220 GNUNET_CHAT_iterate_accounts( 210 GNUNET_CHAT_iterate_accounts(
221 app->chat.messenger.handle, 211 app->chat.messenger.handle,
@@ -227,12 +217,7 @@ ui_accounts_dialog_refresh(MESSENGER_Application *app,
227void 217void
228ui_accounts_dialog_cleanup(UI_ACCOUNTS_Handle *handle) 218ui_accounts_dialog_cleanup(UI_ACCOUNTS_Handle *handle)
229{ 219{
230 _clear_accounts_listbox_rows(handle, TRUE);
231
232 g_object_unref(handle->builder); 220 g_object_unref(handle->builder);
233 221
234 bindings_destroy(handle->bindings);
235 handle->bindings = NULL;
236
237 handle->accounts_listbox = NULL; 222 handle->accounts_listbox = NULL;
238} 223}
diff --git a/src/ui/accounts.h b/src/ui/accounts.h
index c8a8549..a71e31e 100644
--- a/src/ui/accounts.h
+++ b/src/ui/accounts.h
@@ -26,11 +26,9 @@
26#define UI_ACCOUNTS_H_ 26#define UI_ACCOUNTS_H_
27 27
28#include "messenger.h" 28#include "messenger.h"
29#include "../bindings.h"
30 29
31typedef struct UI_ACCOUNTS_Handle 30typedef struct UI_ACCOUNTS_Handle
32{ 31{
33 MESSENGER_Bindings *bindings;
34 guint show_queued; 32 guint show_queued;
35 33
36 GtkBuilder *builder; 34 GtkBuilder *builder;
diff --git a/src/ui/chat.c b/src/ui/chat.c
index cf0fa38..953bf7e 100644
--- a/src/ui/chat.c
+++ b/src/ui/chat.c
@@ -76,7 +76,7 @@ handle_chat_contacts_listbox_row_activated(GtkListBox *listbox,
76 MESSENGER_Application *app = (MESSENGER_Application*) user_data; 76 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
77 77
78 GtkTextView *text_view = GTK_TEXT_VIEW( 78 GtkTextView *text_view = GTK_TEXT_VIEW(
79 bindings_get(app->bindings, listbox) 79 g_object_get_qdata(G_OBJECT(listbox), app->quarks.widget)
80 ); 80 );
81 81
82 if (!text_view) 82 if (!text_view)
@@ -86,14 +86,18 @@ handle_chat_contacts_listbox_row_activated(GtkListBox *listbox,
86 { 86 {
87 ui_invite_contact_dialog_init(app, &(app->ui.invite_contact)); 87 ui_invite_contact_dialog_init(app, &(app->ui.invite_contact));
88 88
89 bindings_put(app->bindings, app->ui.invite_contact.contacts_listbox, text_view); 89 g_object_set_qdata(
90 G_OBJECT(app->ui.invite_contact.contacts_listbox),
91 app->quarks.widget,
92 text_view
93 );
90 94
91 gtk_widget_show(GTK_WIDGET(app->ui.invite_contact.dialog)); 95 gtk_widget_show(GTK_WIDGET(app->ui.invite_contact.dialog));
92 return; 96 return;
93 } 97 }
94 98
95 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) ( 99 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
96 bindings_get(app->bindings, row) 100 g_object_get_qdata(G_OBJECT(row), app->quarks.data)
97 ); 101 );
98 102
99 if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) || 103 if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) ||
@@ -155,11 +159,11 @@ handle_chat_messages_sort(GtkListBoxRow* row0,
155 MESSENGER_Application *app = (MESSENGER_Application*) user_data; 159 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
156 160
157 UI_MESSAGE_Handle *message0 = (UI_MESSAGE_Handle*) ( 161 UI_MESSAGE_Handle *message0 = (UI_MESSAGE_Handle*) (
158 bindings_get(app->bindings, row0) 162 g_object_get_qdata(G_OBJECT(row0), app->quarks.ui)
159 ); 163 );
160 164
161 UI_MESSAGE_Handle *message1 = (UI_MESSAGE_Handle*) ( 165 UI_MESSAGE_Handle *message1 = (UI_MESSAGE_Handle*) (
162 bindings_get(app->bindings, row1) 166 g_object_get_qdata(G_OBJECT(row1), app->quarks.ui)
163 ); 167 );
164 168
165 if ((!message0) || (!message1)) 169 if ((!message0) || (!message1))
@@ -225,7 +229,10 @@ _delete_messages_callback(MESSENGER_Application *app,
225 if (!row) 229 if (!row)
226 goto skip_row; 230 goto skip_row;
227 231
228 message = bindings_get(app->bindings, row); 232 message = (UI_MESSAGE_Handle*) g_object_get_qdata(
233 G_OBJECT(row),
234 app->quarks.ui
235 );
229 236
230 if ((!message) || (!(message->msg))) 237 if ((!message) || (!(message->msg)))
231 goto skip_row; 238 goto skip_row;
@@ -276,7 +283,7 @@ handle_attach_file_button_click(GtkButton *button,
276 MESSENGER_Application *app = (MESSENGER_Application*) user_data; 283 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
277 284
278 GtkTextView *text_view = GTK_TEXT_VIEW( 285 GtkTextView *text_view = GTK_TEXT_VIEW(
279 bindings_get(app->bindings, button) 286 g_object_get_qdata(G_OBJECT(button), app->quarks.widget)
280 ); 287 );
281 288
282 if (!text_view) 289 if (!text_view)
@@ -308,7 +315,11 @@ handle_attach_file_button_click(GtkButton *button,
308 315
309 g_free(filename); 316 g_free(filename);
310 317
311 bindings_put(app->bindings, app->ui.send_file.send_button, text_view); 318 g_object_set_qdata(
319 G_OBJECT(app->ui.send_file.send_button),
320 app->quarks.widget,
321 text_view
322 );
312 323
313 gtk_widget_show(GTK_WIDGET(app->ui.send_file.dialog)); 324 gtk_widget_show(GTK_WIDGET(app->ui.send_file.dialog));
314 325
@@ -353,7 +364,7 @@ _send_text_from_view(MESSENGER_Application *app,
353 return FALSE; 364 return FALSE;
354 365
355 struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) ( 366 struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) (
356 bindings_get(app->bindings, text_view) 367 g_object_get_qdata(G_OBJECT(text_view), app->quarks.data)
357 ); 368 );
358 369
359 if (context) 370 if (context)
@@ -370,7 +381,7 @@ handle_send_record_button_click(GtkButton *button,
370 MESSENGER_Application *app = (MESSENGER_Application*) user_data; 381 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
371 382
372 GtkTextView *text_view = GTK_TEXT_VIEW( 383 GtkTextView *text_view = GTK_TEXT_VIEW(
373 bindings_get(app->bindings, button) 384 g_object_get_qdata(G_OBJECT(button), app->quarks.widget)
374 ); 385 );
375 386
376 if (!_send_text_from_view(app, text_view)) 387 if (!_send_text_from_view(app, text_view))
@@ -646,9 +657,23 @@ ui_chat_new(MESSENGER_Application *app)
646 app 657 app
647 ); 658 );
648 659
649 bindings_put(app->bindings, handle->chat_contacts_listbox, handle->send_text_view); 660 g_object_set_qdata(
650 bindings_put(app->bindings, handle->attach_file_button, handle->send_text_view); 661 G_OBJECT(handle->chat_contacts_listbox),
651 bindings_put(app->bindings, handle->send_record_button, handle->send_text_view); 662 app->quarks.widget,
663 handle->send_text_view
664 );
665
666 g_object_set_qdata(
667 G_OBJECT(handle->attach_file_button),
668 app->quarks.widget,
669 handle->send_text_view
670 );
671
672 g_object_set_qdata(
673 G_OBJECT(handle->send_record_button),
674 app->quarks.widget,
675 handle->send_text_view
676 );
652 677
653 handle->picker_revealer = GTK_REVEALER( 678 handle->picker_revealer = GTK_REVEALER(
654 gtk_builder_get_object(handle->builder, "picker_revealer") 679 gtk_builder_get_object(handle->builder, "picker_revealer")
@@ -696,9 +721,14 @@ iterate_ui_chat_update_group_contacts(void *cls,
696 gtk_widget_get_parent(entry->entry_box) 721 gtk_widget_get_parent(entry->entry_box)
697 ); 722 );
698 723
699 bindings_put(closure->app->bindings, row, contact); 724 g_object_set_qdata(G_OBJECT(row), closure->app->quarks.data, contact);
725 g_object_set_qdata_full(
726 G_OBJECT(row),
727 closure->app->quarks.ui,
728 entry,
729 (GDestroyNotify) ui_account_entry_delete
730 );
700 731
701 ui_account_entry_delete(entry);
702 return GNUNET_YES; 732 return GNUNET_YES;
703} 733}
704 734
@@ -750,8 +780,6 @@ ui_chat_update(UI_CHAT_Handle *handle,
750 GtkWidget *widget = GTK_WIDGET(children->data); 780 GtkWidget *widget = GTK_WIDGET(children->data);
751 children = children->next; 781 children = children->next;
752 782
753 bindings_remove(app->bindings, widget, NULL, NULL);
754
755 gtk_container_remove( 783 gtk_container_remove(
756 GTK_CONTAINER(handle->chat_contacts_listbox), 784 GTK_CONTAINER(handle->chat_contacts_listbox),
757 widget 785 widget
@@ -840,7 +868,7 @@ ui_chat_add_message(UI_CHAT_Handle *handle,
840 868
841 GtkWidget *row = gtk_widget_get_parent(message->message_box); 869 GtkWidget *row = gtk_widget_get_parent(message->message_box);
842 870
843 bindings_put(app->bindings, row, message); 871 g_object_set_qdata(G_OBJECT(row), app->quarks.ui, message);
844 872
845 handle->messages = g_list_prepend(handle->messages, message); 873 handle->messages = g_list_prepend(handle->messages, message);
846 874
@@ -849,7 +877,7 @@ ui_chat_add_message(UI_CHAT_Handle *handle,
849 877
850void 878void
851ui_chat_remove_message(UI_CHAT_Handle *handle, 879ui_chat_remove_message(UI_CHAT_Handle *handle,
852 MESSENGER_Application *app, 880 UNUSED MESSENGER_Application *app,
853 UI_MESSAGE_Handle *message) 881 UI_MESSAGE_Handle *message)
854{ 882{
855 GNUNET_assert((handle) && (message)); 883 GNUNET_assert((handle) && (message));
@@ -858,12 +886,7 @@ ui_chat_remove_message(UI_CHAT_Handle *handle,
858 886
859 GtkWidget *row = gtk_widget_get_parent(message->message_box); 887 GtkWidget *row = gtk_widget_get_parent(message->message_box);
860 888
861 bindings_remove(app->bindings, row, NULL, NULL); 889 gtk_container_remove(GTK_CONTAINER(handle->messages_listbox), row);
862
863 gtk_container_remove(
864 GTK_CONTAINER(handle->messages_listbox),
865 gtk_widget_get_parent(GTK_WIDGET(message->message_box))
866 );
867 890
868 handle->messages = g_list_append(handle->messages, message); 891 handle->messages = g_list_append(handle->messages, message);
869} 892}
diff --git a/src/ui/chat_entry.c b/src/ui/chat_entry.c
index 99f03cc..3c9461e 100644
--- a/src/ui/chat_entry.c
+++ b/src/ui/chat_entry.c
@@ -34,8 +34,6 @@ ui_chat_entry_new(MESSENGER_Application *app)
34{ 34{
35 UI_CHAT_ENTRY_Handle* handle = g_malloc(sizeof(UI_CHAT_ENTRY_Handle)); 35 UI_CHAT_ENTRY_Handle* handle = g_malloc(sizeof(UI_CHAT_ENTRY_Handle));
36 36
37 handle->joining = bindings_create();
38
39 handle->chat = ui_chat_new(app); 37 handle->chat = ui_chat_new(app);
40 handle->builder = gtk_builder_new_from_resource( 38 handle->builder = gtk_builder_new_from_resource(
41 application_get_resource_path(app, "ui/chat_entry.ui") 39 application_get_resource_path(app, "ui/chat_entry.ui")
@@ -155,7 +153,5 @@ ui_chat_entry_delete(UI_CHAT_ENTRY_Handle *handle)
155 153
156 g_object_unref(handle->builder); 154 g_object_unref(handle->builder);
157 155
158 bindings_destroy(handle->joining);
159
160 g_free(handle); 156 g_free(handle);
161} 157}
diff --git a/src/ui/chat_entry.h b/src/ui/chat_entry.h
index d6d70ea..8c90624 100644
--- a/src/ui/chat_entry.h
+++ b/src/ui/chat_entry.h
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2021 GNUnet e.V. 3 Copyright (C) 2021--2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -26,12 +26,9 @@
26#define UI_CHAT_ENTRY_H_ 26#define UI_CHAT_ENTRY_H_
27 27
28#include "chat.h" 28#include "chat.h"
29#include "../bindings.h"
30 29
31typedef struct UI_CHAT_ENTRY_Handle 30typedef struct UI_CHAT_ENTRY_Handle
32{ 31{
33 MESSENGER_Bindings *joining;
34
35 UI_CHAT_Handle *chat; 32 UI_CHAT_Handle *chat;
36 GtkBuilder *builder; 33 GtkBuilder *builder;
37 34
diff --git a/src/ui/contacts.c b/src/ui/contacts.c
index 21d2f2f..68d18b4 100644
--- a/src/ui/contacts.c
+++ b/src/ui/contacts.c
@@ -61,7 +61,7 @@ handle_contacts_listbox_row_activated(UNUSED GtkListBox* listbox,
61 } 61 }
62 62
63 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) ( 63 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
64 bindings_get(app->bindings, row) 64 g_object_get_qdata(G_OBJECT(row), app->quarks.data)
65 ); 65 );
66 66
67 if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) || 67 if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) ||
@@ -86,20 +86,20 @@ static gboolean
86handle_contacts_listbox_filter_func(GtkListBoxRow *row, 86handle_contacts_listbox_filter_func(GtkListBoxRow *row,
87 gpointer user_data) 87 gpointer user_data)
88{ 88{
89 UI_CONTACTS_Handle *handle = (UI_CONTACTS_Handle*) user_data; 89 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
90 90
91 if ((!row) || (!gtk_list_box_row_get_selectable(row))) 91 if ((!row) || (!gtk_list_box_row_get_selectable(row)))
92 return TRUE; 92 return TRUE;
93 93
94 const gchar *filter = gtk_entry_get_text( 94 const gchar *filter = gtk_entry_get_text(
95 GTK_ENTRY(handle->contact_search_entry) 95 GTK_ENTRY(app->ui.contacts.contact_search_entry)
96 ); 96 );
97 97
98 if (!filter) 98 if (!filter)
99 return TRUE; 99 return TRUE;
100 100
101 UI_CONTACT_ENTRY_Handle *entry = (UI_CONTACT_ENTRY_Handle*) ( 101 UI_CONTACT_ENTRY_Handle *entry = (UI_CONTACT_ENTRY_Handle*) (
102 bindings_get(handle->bindings, row) 102 g_object_get_qdata(G_OBJECT(row), app->quarks.ui)
103 ); 103 );
104 104
105 if (!entry) 105 if (!entry)
@@ -151,8 +151,14 @@ _iterate_contacts(void *cls,
151 gtk_widget_get_parent(entry->entry_box) 151 gtk_widget_get_parent(entry->entry_box)
152 ); 152 );
153 153
154 bindings_put(app->bindings, row, contact); 154 g_object_set_qdata(G_OBJECT(row), app->quarks.data, contact);
155 bindings_put(app->ui.contacts.bindings, row, entry); 155
156 g_object_set_qdata_full(
157 G_OBJECT(row),
158 app->quarks.ui,
159 entry,
160 (GDestroyNotify) ui_contact_entry_delete
161 );
156 162
157 return GNUNET_YES; 163 return GNUNET_YES;
158} 164}
@@ -161,8 +167,6 @@ void
161ui_contacts_dialog_init(MESSENGER_Application *app, 167ui_contacts_dialog_init(MESSENGER_Application *app,
162 UI_CONTACTS_Handle *handle) 168 UI_CONTACTS_Handle *handle)
163{ 169{
164 handle->bindings = bindings_create();
165
166 handle->builder = gtk_builder_new_from_resource( 170 handle->builder = gtk_builder_new_from_resource(
167 application_get_resource_path(app, "ui/contacts.ui") 171 application_get_resource_path(app, "ui/contacts.ui")
168 ); 172 );
@@ -187,7 +191,7 @@ ui_contacts_dialog_init(MESSENGER_Application *app,
187 gtk_list_box_set_filter_func( 191 gtk_list_box_set_filter_func(
188 handle->contacts_listbox, 192 handle->contacts_listbox,
189 handle_contacts_listbox_filter_func, 193 handle_contacts_listbox_filter_func,
190 handle, 194 app,
191 NULL 195 NULL
192 ); 196 );
193 197
@@ -232,48 +236,10 @@ ui_contacts_dialog_init(MESSENGER_Application *app,
232 gtk_list_box_invalidate_filter(handle->contacts_listbox); 236 gtk_list_box_invalidate_filter(handle->contacts_listbox);
233} 237}
234 238
235static void
236_clear_contacts_listbox_rows(UI_CONTACTS_Handle *handle,
237 gboolean bindings_only)
238{
239 GList *list = gtk_container_get_children(
240 GTK_CONTAINER(handle->contacts_listbox)
241 );
242
243 while (list)
244 {
245 GtkListBoxRow *row = GTK_LIST_BOX_ROW(list->data);
246
247 if ((!row) || (!gtk_list_box_row_get_selectable(row)))
248 goto skip_row;
249
250 if (!bindings_only)
251 gtk_container_remove(
252 GTK_CONTAINER(handle->contacts_listbox),
253 GTK_WIDGET(row)
254 );
255
256 bindings_remove(
257 handle->bindings,
258 row,
259 NULL,
260 (GDestroyNotify) ui_contact_entry_delete
261 );
262
263 skip_row:
264 list = list->next;
265 }
266}
267
268void 239void
269ui_contacts_dialog_cleanup(UI_CONTACTS_Handle *handle) 240ui_contacts_dialog_cleanup(UI_CONTACTS_Handle *handle)
270{ 241{
271 _clear_contacts_listbox_rows(handle, TRUE);
272
273 g_object_unref(handle->builder); 242 g_object_unref(handle->builder);
274 243
275 bindings_destroy(handle->bindings);
276 handle->bindings = NULL;
277
278 handle->contacts_listbox = NULL; 244 handle->contacts_listbox = NULL;
279} 245}
diff --git a/src/ui/contacts.h b/src/ui/contacts.h
index 89e7946..6bb3475 100644
--- a/src/ui/contacts.h
+++ b/src/ui/contacts.h
@@ -26,12 +26,9 @@
26#define UI_CONTACTS_H_ 26#define UI_CONTACTS_H_
27 27
28#include "messenger.h" 28#include "messenger.h"
29#include "../bindings.h"
30 29
31typedef struct UI_CONTACTS_Handle 30typedef struct UI_CONTACTS_Handle
32{ 31{
33 MESSENGER_Bindings *bindings;
34
35 GtkBuilder *builder; 32 GtkBuilder *builder;
36 GtkDialog *dialog; 33 GtkDialog *dialog;
37 34
diff --git a/src/ui/invite_contact.c b/src/ui/invite_contact.c
index 4229067..272550f 100644
--- a/src/ui/invite_contact.c
+++ b/src/ui/invite_contact.c
@@ -44,11 +44,11 @@ handle_contacts_listbox_row_activated(GtkListBox* listbox,
44 MESSENGER_Application *app = (MESSENGER_Application*) user_data; 44 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
45 45
46 GtkTextView *text_view = GTK_TEXT_VIEW( 46 GtkTextView *text_view = GTK_TEXT_VIEW(
47 bindings_get(app->bindings, listbox) 47 g_object_get_qdata(G_OBJECT(listbox), app->quarks.widget)
48 ); 48 );
49 49
50 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) ( 50 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
51 bindings_get(app->bindings, row) 51 g_object_get_qdata(G_OBJECT(row), app->quarks.data)
52 ); 52 );
53 53
54 if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) || 54 if ((!contact) || (!GNUNET_CHAT_contact_get_key(contact)) ||
@@ -57,7 +57,7 @@ handle_contacts_listbox_row_activated(GtkListBox* listbox,
57 goto close_dialog; 57 goto close_dialog;
58 58
59 struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) ( 59 struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) (
60 bindings_get(app->bindings, text_view) 60 g_object_get_qdata(G_OBJECT(text_view), app->quarks.data)
61 ); 61 );
62 62
63 if (!context) 63 if (!context)
@@ -78,20 +78,20 @@ static gboolean
78handle_contacts_listbox_filter_func(GtkListBoxRow *row, 78handle_contacts_listbox_filter_func(GtkListBoxRow *row,
79 gpointer user_data) 79 gpointer user_data)
80{ 80{
81 UI_INVITE_CONTACT_Handle *handle = (UI_INVITE_CONTACT_Handle*) user_data; 81 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
82 82
83 if ((!row) || (!gtk_list_box_row_get_selectable(row))) 83 if ((!row) || (!gtk_list_box_row_get_selectable(row)))
84 return TRUE; 84 return TRUE;
85 85
86 const gchar *filter = gtk_entry_get_text( 86 const gchar *filter = gtk_entry_get_text(
87 GTK_ENTRY(handle->contact_search_entry) 87 GTK_ENTRY(app->ui.invite_contact.contact_search_entry)
88 ); 88 );
89 89
90 if (!filter) 90 if (!filter)
91 return TRUE; 91 return TRUE;
92 92
93 UI_CONTACT_ENTRY_Handle *entry = (UI_CONTACT_ENTRY_Handle*) ( 93 UI_CONTACT_ENTRY_Handle *entry = (UI_CONTACT_ENTRY_Handle*) (
94 bindings_get(handle->bindings, row) 94 g_object_get_qdata(G_OBJECT(row), app->quarks.ui)
95 ); 95 );
96 96
97 if (!entry) 97 if (!entry)
@@ -143,8 +143,14 @@ _iterate_contacts(void *cls,
143 gtk_widget_get_parent(entry->entry_box) 143 gtk_widget_get_parent(entry->entry_box)
144 ); 144 );
145 145
146 bindings_put(app->bindings, row, contact); 146 g_object_set_qdata(G_OBJECT(row), app->quarks.data, contact);
147 bindings_put(app->ui.invite_contact.bindings, row, entry); 147
148 g_object_set_qdata_full(
149 G_OBJECT(row),
150 app->quarks.ui,
151 entry,
152 (GDestroyNotify) ui_contact_entry_delete
153 );
148 154
149 return GNUNET_YES; 155 return GNUNET_YES;
150} 156}
@@ -153,8 +159,6 @@ void
153ui_invite_contact_dialog_init(MESSENGER_Application *app, 159ui_invite_contact_dialog_init(MESSENGER_Application *app,
154 UI_INVITE_CONTACT_Handle *handle) 160 UI_INVITE_CONTACT_Handle *handle)
155{ 161{
156 handle->bindings = bindings_create();
157
158 handle->builder = gtk_builder_new_from_resource( 162 handle->builder = gtk_builder_new_from_resource(
159 application_get_resource_path(app, "ui/invite_contact.ui") 163 application_get_resource_path(app, "ui/invite_contact.ui")
160 ); 164 );
@@ -179,7 +183,7 @@ ui_invite_contact_dialog_init(MESSENGER_Application *app,
179 gtk_list_box_set_filter_func( 183 gtk_list_box_set_filter_func(
180 handle->contacts_listbox, 184 handle->contacts_listbox,
181 handle_contacts_listbox_filter_func, 185 handle_contacts_listbox_filter_func,
182 handle, 186 app,
183 NULL 187 NULL
184 ); 188 );
185 189
@@ -224,48 +228,10 @@ ui_invite_contact_dialog_init(MESSENGER_Application *app,
224 gtk_list_box_invalidate_filter(handle->contacts_listbox); 228 gtk_list_box_invalidate_filter(handle->contacts_listbox);
225} 229}
226 230
227static void
228_clear_contacts_listbox_rows(UI_INVITE_CONTACT_Handle *handle,
229 gboolean bindings_only)
230{
231 GList *list = gtk_container_get_children(
232 GTK_CONTAINER(handle->contacts_listbox)
233 );
234
235 while (list)
236 {
237 GtkListBoxRow *row = GTK_LIST_BOX_ROW(list->data);
238
239 if ((!row) || (!gtk_list_box_row_get_selectable(row)))
240 goto skip_row;
241
242 if (!bindings_only)
243 gtk_container_remove(
244 GTK_CONTAINER(handle->contacts_listbox),
245 GTK_WIDGET(row)
246 );
247
248 bindings_remove(
249 handle->bindings,
250 row,
251 NULL,
252 (GDestroyNotify) ui_contact_entry_delete
253 );
254
255 skip_row:
256 list = list->next;
257 }
258}
259
260void 231void
261ui_invite_contact_dialog_cleanup(UI_INVITE_CONTACT_Handle *handle) 232ui_invite_contact_dialog_cleanup(UI_INVITE_CONTACT_Handle *handle)
262{ 233{
263 _clear_contacts_listbox_rows(handle, TRUE);
264
265 g_object_unref(handle->builder); 234 g_object_unref(handle->builder);
266 235
267 bindings_destroy(handle->bindings);
268 handle->bindings = NULL;
269
270 handle->contacts_listbox = NULL; 236 handle->contacts_listbox = NULL;
271} 237}
diff --git a/src/ui/invite_contact.h b/src/ui/invite_contact.h
index 4cf1f79..3c3175a 100644
--- a/src/ui/invite_contact.h
+++ b/src/ui/invite_contact.h
@@ -26,12 +26,9 @@
26#define UI_INVITE_CONTACT_H_ 26#define UI_INVITE_CONTACT_H_
27 27
28#include "messenger.h" 28#include "messenger.h"
29#include "../bindings.h"
30 29
31typedef struct UI_INVITE_CONTACT_Handle 30typedef struct UI_INVITE_CONTACT_Handle
32{ 31{
33 MESSENGER_Bindings *bindings;
34
35 GtkBuilder *builder; 32 GtkBuilder *builder;
36 GtkDialog *dialog; 33 GtkDialog *dialog;
37 34
diff --git a/src/ui/message.c b/src/ui/message.c
index c6a395e..c358e73 100644
--- a/src/ui/message.c
+++ b/src/ui/message.c
@@ -50,14 +50,14 @@ handle_file_button_click(GtkButton *button,
50 MESSENGER_Application *app = (MESSENGER_Application*) user_data; 50 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
51 51
52 UI_MESSAGE_Handle* handle = (UI_MESSAGE_Handle*) ( 52 UI_MESSAGE_Handle* handle = (UI_MESSAGE_Handle*) (
53 bindings_get(app->bindings, button) 53 g_object_get_qdata(G_OBJECT(button), app->quarks.ui)
54 ); 54 );
55 55
56 if (!handle) 56 if (!handle)
57 return; 57 return;
58 58
59 struct GNUNET_CHAT_File *file = (struct GNUNET_CHAT_File*) ( 59 struct GNUNET_CHAT_File *file = (struct GNUNET_CHAT_File*) (
60 bindings_get(app->bindings, handle->file_progress_bar) 60 g_object_get_qdata(G_OBJECT(handle->file_progress_bar), app->quarks.data)
61 ); 61 );
62 62
63 if (!file) 63 if (!file)
@@ -360,7 +360,7 @@ ui_message_new(MESSENGER_Application *app,
360 gtk_builder_get_object(handle->builder[1], "file_status_image") 360 gtk_builder_get_object(handle->builder[1], "file_status_image")
361 ); 361 );
362 362
363 bindings_put(app->bindings, handle->file_button, handle); 363 g_object_set_qdata(G_OBJECT(handle->file_button), app->quarks.ui, handle);
364 364
365 handle->preview_drawing_area = GTK_DRAWING_AREA( 365 handle->preview_drawing_area = GTK_DRAWING_AREA(
366 gtk_builder_get_object(handle->builder[1], "preview_drawing_area") 366 gtk_builder_get_object(handle->builder[1], "preview_drawing_area")
@@ -444,13 +444,13 @@ ui_message_update(UI_MESSAGE_Handle *handle,
444 } 444 }
445 else 445 else
446 file = (struct GNUNET_CHAT_File*) ( 446 file = (struct GNUNET_CHAT_File*) (
447 bindings_get(app->bindings, handle->message_box) 447 g_object_get_qdata(G_OBJECT(handle->message_box), app->quarks.data)
448 ); 448 );
449 449
450 if (!file) 450 if (!file)
451 return; 451 return;
452 452
453 bindings_put(app->bindings, handle->message_box, file); 453 g_object_set_qdata(G_OBJECT(handle->message_box), app->quarks.data, file);
454 454
455 uint64_t size = GNUNET_CHAT_file_get_size(file); 455 uint64_t size = GNUNET_CHAT_file_get_size(file);
456 uint64_t local_size = GNUNET_CHAT_file_get_local_size(file); 456 uint64_t local_size = GNUNET_CHAT_file_get_local_size(file);
@@ -519,7 +519,11 @@ file_content:
519 519
520 gtk_revealer_set_reveal_child(handle->file_revealer, TRUE); 520 gtk_revealer_set_reveal_child(handle->file_revealer, TRUE);
521 521
522 bindings_put(app->bindings, handle->file_progress_bar, file); 522 g_object_set_qdata(
523 G_OBJECT(handle->file_progress_bar),
524 app->quarks.data,
525 file
526 );
523} 527}
524 528
525void 529void
diff --git a/src/ui/messenger.c b/src/ui/messenger.c
index aff450e..246bb9c 100644
--- a/src/ui/messenger.c
+++ b/src/ui/messenger.c
@@ -106,7 +106,7 @@ handle_accounts_listbox_row_activated(UNUSED GtkListBox* listbox,
106 } 106 }
107 107
108 struct GNUNET_CHAT_Account *account = (struct GNUNET_CHAT_Account*) ( 108 struct GNUNET_CHAT_Account *account = (struct GNUNET_CHAT_Account*) (
109 bindings_get(app->bindings, row) 109 g_object_get_qdata(G_OBJECT(row), app->quarks.data)
110 ); 110 );
111 111
112 if (!account) 112 if (!account)
@@ -188,20 +188,20 @@ handle_chats_listbox_row_activated(UNUSED GtkListBox* listbox,
188 GtkListBoxRow* row, 188 GtkListBoxRow* row,
189 gpointer user_data) 189 gpointer user_data)
190{ 190{
191 UI_MESSENGER_Handle *handle = (UI_MESSENGER_Handle*) user_data; 191 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
192 192
193 if (!gtk_list_box_row_get_selectable(row)) 193 if (!gtk_list_box_row_get_selectable(row))
194 return; 194 return;
195 195
196 UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) ( 196 UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) (
197 bindings_get(handle->app->bindings, row) 197 g_object_get_qdata(G_OBJECT(row), app->quarks.ui)
198 ); 198 );
199 199
200 if ((!entry) || (!(entry->chat)) || (!(entry->chat->chat_box))) 200 if ((!entry) || (!(entry->chat)) || (!(entry->chat->chat_box)))
201 return; 201 return;
202 202
203 GtkStack *stack = handle->chats_stack; 203 GtkStack *stack = app->ui.messenger.chats_stack;
204 HdyLeaflet *leaflet = handle->leaflet_chat; 204 HdyLeaflet *leaflet = app->ui.messenger.leaflet_chat;
205 205
206 GList *children = gtk_container_get_children(GTK_CONTAINER(leaflet)); 206 GList *children = gtk_container_get_children(GTK_CONTAINER(leaflet));
207 207
@@ -216,21 +216,21 @@ static gboolean
216handle_chats_listbox_filter_func(GtkListBoxRow *row, 216handle_chats_listbox_filter_func(GtkListBoxRow *row,
217 gpointer user_data) 217 gpointer user_data)
218{ 218{
219 UI_MESSENGER_Handle *handle = (UI_MESSENGER_Handle*) user_data; 219 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
220 220
221 if ((!row) || (!gtk_list_box_row_get_selectable(row)) || 221 if ((!row) || (!gtk_list_box_row_get_selectable(row)) ||
222 (gtk_list_box_row_is_selected(row))) 222 (gtk_list_box_row_is_selected(row)))
223 return TRUE; 223 return TRUE;
224 224
225 const gchar *filter = gtk_entry_get_text( 225 const gchar *filter = gtk_entry_get_text(
226 GTK_ENTRY(handle->chats_search) 226 GTK_ENTRY(app->ui.messenger.chats_search)
227 ); 227 );
228 228
229 if (!filter) 229 if (!filter)
230 return TRUE; 230 return TRUE;
231 231
232 UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) ( 232 UI_CHAT_ENTRY_Handle *entry = (UI_CHAT_ENTRY_Handle*) (
233 bindings_get(handle->app->bindings, row) 233 g_object_get_qdata(G_OBJECT(row), app->quarks.ui)
234 ); 234 );
235 235
236 if ((!entry) || (!(entry->title_label))) 236 if ((!entry) || (!(entry->title_label)))
@@ -457,7 +457,7 @@ ui_messenger_init(MESSENGER_Application *app,
457 gtk_list_box_set_filter_func( 457 gtk_list_box_set_filter_func(
458 handle->chats_listbox, 458 handle->chats_listbox,
459 handle_chats_listbox_filter_func, 459 handle_chats_listbox_filter_func,
460 handle, 460 app,
461 NULL 461 NULL
462 ); 462 );
463 463
@@ -472,7 +472,7 @@ ui_messenger_init(MESSENGER_Application *app,
472 handle->chats_listbox, 472 handle->chats_listbox,
473 "row-activated", 473 "row-activated",
474 G_CALLBACK(handle_chats_listbox_row_activated), 474 G_CALLBACK(handle_chats_listbox_row_activated),
475 handle 475 app
476 ); 476 );
477 477
478 handle->chats_stack = GTK_STACK( 478 handle->chats_stack = GTK_STACK(
@@ -491,32 +491,6 @@ ui_messenger_init(MESSENGER_Application *app,
491 ); 491 );
492} 492}
493 493
494static void
495_messenger_clear_accounts_listbox_rows(UI_MESSENGER_Handle *handle)
496{
497 GList *list = gtk_container_get_children(
498 GTK_CONTAINER(handle->accounts_listbox)
499 );
500
501 while (list)
502 {
503 GtkListBoxRow *row = GTK_LIST_BOX_ROW(list->data);
504
505 if ((!row) || (!gtk_list_box_row_get_selectable(row)))
506 goto skip_row;
507
508 bindings_remove(handle->app->bindings, row, NULL, NULL);
509
510 gtk_container_remove(
511 GTK_CONTAINER(handle->accounts_listbox),
512 GTK_WIDGET(row)
513 );
514
515 skip_row:
516 list = list->next;
517 }
518}
519
520static int 494static int
521_messenger_iterate_accounts(void *cls, 495_messenger_iterate_accounts(void *cls,
522 const struct GNUNET_CHAT_Handle *handle, 496 const struct GNUNET_CHAT_Handle *handle,
@@ -538,7 +512,7 @@ _messenger_iterate_accounts(void *cls,
538 gtk_widget_get_parent(entry->entry_box) 512 gtk_widget_get_parent(entry->entry_box)
539 ); 513 );
540 514
541 bindings_put(app->bindings, row, account); 515 g_object_set_qdata(G_OBJECT(row), app->quarks.data, account);
542 516
543 if ((account == GNUNET_CHAT_get_connected(handle)) || 517 if ((account == GNUNET_CHAT_get_connected(handle)) ||
544 ((app->chat.identity) && (0 == g_strcmp0(app->chat.identity, name)))) 518 ((app->chat.identity) && (0 == g_strcmp0(app->chat.identity, name))))
@@ -555,7 +529,25 @@ ui_messenger_refresh(MESSENGER_Application *app,
555 if (!(handle->accounts_listbox)) 529 if (!(handle->accounts_listbox))
556 return; 530 return;
557 531
558 _messenger_clear_accounts_listbox_rows(handle); 532 GList *list = gtk_container_get_children(
533 GTK_CONTAINER(handle->accounts_listbox)
534 );
535
536 while (list)
537 {
538 GtkListBoxRow *row = GTK_LIST_BOX_ROW(list->data);
539
540 if ((!row) || (!gtk_list_box_row_get_selectable(row)))
541 goto skip_row;
542
543 gtk_container_remove(
544 GTK_CONTAINER(handle->accounts_listbox),
545 GTK_WIDGET(row)
546 );
547
548 skip_row:
549 list = list->next;
550 }
559 551
560 GNUNET_CHAT_iterate_accounts( 552 GNUNET_CHAT_iterate_accounts(
561 app->chat.messenger.handle, 553 app->chat.messenger.handle,
diff --git a/src/ui/new_group.c b/src/ui/new_group.c
index ed7f0a7..d2b287e 100644
--- a/src/ui/new_group.c
+++ b/src/ui/new_group.c
@@ -51,7 +51,7 @@ _open_new_group(GtkEntry *entry,
51 GtkListBoxRow *row = GTK_LIST_BOX_ROW(selected->data); 51 GtkListBoxRow *row = GTK_LIST_BOX_ROW(selected->data);
52 52
53 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) ( 53 struct GNUNET_CHAT_Contact *contact = (struct GNUNET_CHAT_Contact*) (
54 bindings_get(app->bindings, row) 54 g_object_get_qdata(G_OBJECT(row), app->quarks.data)
55 ); 55 );
56 56
57 GNUNET_CHAT_group_invite_contact(group, contact); 57 GNUNET_CHAT_group_invite_contact(group, contact);
@@ -170,7 +170,7 @@ _iterate_contacts(void *cls,
170 gtk_widget_get_parent(entry->entry_box) 170 gtk_widget_get_parent(entry->entry_box)
171 ); 171 );
172 172
173 bindings_put(app->bindings, row, contact); 173 g_object_set_qdata(G_OBJECT(row), app->quarks.data, contact);
174 174
175 app->ui.new_group.contact_entries = g_list_append( 175 app->ui.new_group.contact_entries = g_list_append(
176 app->ui.new_group.contact_entries, 176 app->ui.new_group.contact_entries,
diff --git a/src/ui/send_file.c b/src/ui/send_file.c
index 5555e73..991e8ce 100644
--- a/src/ui/send_file.c
+++ b/src/ui/send_file.c
@@ -65,7 +65,7 @@ handle_send_button_click(GtkButton *button,
65 MESSENGER_Application *app = (MESSENGER_Application*) user_data; 65 MESSENGER_Application *app = (MESSENGER_Application*) user_data;
66 66
67 GtkTextView *text_view = GTK_TEXT_VIEW( 67 GtkTextView *text_view = GTK_TEXT_VIEW(
68 bindings_get(app->bindings, button) 68 g_object_get_qdata(G_OBJECT(button), app->quarks.widget)
69 ); 69 );
70 70
71 if (!text_view) 71 if (!text_view)
@@ -79,7 +79,7 @@ handle_send_button_click(GtkButton *button,
79 return; 79 return;
80 80
81 struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) ( 81 struct GNUNET_CHAT_Context *context = (struct GNUNET_CHAT_Context*) (
82 bindings_get(app->bindings, text_view) 82 g_object_get_qdata(G_OBJECT(text_view), app->quarks.data)
83 ); 83 );
84 84
85 UI_CHAT_ENTRY_Handle *entry = GNUNET_CHAT_context_get_user_pointer(context); 85 UI_CHAT_ENTRY_Handle *entry = GNUNET_CHAT_context_get_user_pointer(context);