changeset 13434:ffd724befbf8

[gaim-migrate @ 15809] Cleanup the busy cursor handling code to eliminate a bunch of these loops: while (gtk_events_pending()) gtk_main_iteration(); They seem like a race condition waiting to happen. This code is also simpler, and more generic. This leaves only one such loop, in src/gtkblist.c's gaim_gtk_blist_expand_contact_cb(). committer: Tailor Script <tailor@pidgin.im>
author Richard Laager <rlaager@wiktel.com>
date Tue, 07 Mar 2006 05:48:54 +0000
parents 7ef6a2d0d9da
children 5f6d2b22c18e
files plugins/ChangeLog.API src/gtkblist.c src/gtkconv.c src/gtkdialogs.c src/gtklog.c src/gtkplugin.c src/gtkrequest.c src/gtkutils.c src/gtkutils.h
diffstat 9 files changed, 86 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/plugins/ChangeLog.API	Tue Mar 07 05:09:51 2006 +0000
+++ b/plugins/ChangeLog.API	Tue Mar 07 05:48:54 2006 +0000
@@ -277,6 +277,8 @@
 	* GaimRequestUiOps: Added request_folder
 	* gaim_request_folder()
 	* gaim_gtk_setup_screenname_autocomplete()
+	* gaim_gtk_set_cursor()
+	* gaim_gtk_clear_cursor()
 
 	Signals - Changed:  (See the Doxygen docs for details on all signals.)
 	* Signal propagation now stops after a handler returns a non-NULL value.
--- a/src/gtkblist.c	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtkblist.c	Tue Mar 07 05:48:54 2006 +0000
@@ -387,10 +387,7 @@
 	GaimAccount *account;
 	char *name = NULL;
 
-	gdk_window_set_cursor(gtkblist->window->window, cursor);
-	gdk_cursor_unref(cursor);
-	while (gtk_events_pending())
-		gtk_main_iteration();
+	gaim_gtk_set_cursor(gtkblist->window, GDK_WATCH);
 
 	if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
 		GaimBuddy *b = (GaimBuddy*) node;
@@ -408,10 +405,10 @@
 		}
 	} else if (GAIM_BLIST_NODE_IS_CONTACT(node)) {
 		gaim_gtk_log_show_contact((GaimContact *)node);
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+		gaim_gtk_clear_cursor(gtkblist->window);
 		return;
 	} else {
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+		gaim_gtk_clear_cursor(gtkblist->window);
 
 		/* This callback should not have been registered for a node
 		 * that doesn't match the type of one of the blocks above. */
@@ -422,7 +419,7 @@
 		gaim_gtk_log_show(type, name, account);
 		g_free(name);
 
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+		gaim_gtk_clear_cursor(gtkblist->window);
 	}
 }
 
@@ -1330,75 +1327,43 @@
 
 static void gaim_gtk_blist_buddy_details_cb(gpointer data, guint action, GtkWidget *item)
 {
-	if (gtkblist->window->window)
-	{
-		GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
-		gdk_window_set_cursor(gtkblist->window->window, cursor);
-		while (gtk_events_pending())
-			gtk_main_iteration();
-		gdk_cursor_unref(cursor);
-	}
+	gaim_gtk_set_cursor(gtkblist->window, GDK_WATCH);
 
 	gaim_prefs_set_bool("/gaim/gtk/blist/show_buddy_icons",
 			    gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
 
-	if (gtkblist->window->window)
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+	gaim_gtk_clear_cursor(gtkblist->window);
 }
 
 static void gaim_gtk_blist_show_idle_time_cb(gpointer data, guint action, GtkWidget *item)
 {
-	if (gtkblist->window->window)
-	{
-		GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
-		gdk_window_set_cursor(gtkblist->window->window, cursor);
-		while (gtk_events_pending())
-			gtk_main_iteration();
-		gdk_cursor_unref(cursor);
-	}
+	gaim_gtk_set_cursor(gtkblist->window, GDK_WATCH);
 
 	gaim_prefs_set_bool("/gaim/gtk/blist/show_idle_time",
 			    gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
 
-	if (gtkblist->window->window)
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+	gaim_gtk_clear_cursor(gtkblist->window);
 }
 
 static void gaim_gtk_blist_show_empty_groups_cb(gpointer data, guint action, GtkWidget *item)
 {
-	if (gtkblist->window->window)
-	{
-		GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
-		gdk_window_set_cursor(gtkblist->window->window, cursor);
-		while (gtk_events_pending())
-			gtk_main_iteration();
-		gdk_cursor_unref(cursor);
-	}
+	gaim_gtk_set_cursor(gtkblist->window, GDK_WATCH);
 
 	gaim_prefs_set_bool("/gaim/gtk/blist/show_empty_groups",
 			gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item)));
 
-	if (gtkblist->window->window)
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+	gaim_gtk_clear_cursor(gtkblist->window);
 }
 
 static void gaim_gtk_blist_edit_mode_cb(gpointer callback_data, guint callback_action,
 		GtkWidget *checkitem)
 {
-	if (gtkblist->window->window)
-	{
-		GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
-		gdk_window_set_cursor(gtkblist->window->window, cursor);
-		while (gtk_events_pending())
-			gtk_main_iteration();
-		gdk_cursor_unref(cursor);
-	}
+	gaim_gtk_set_cursor(gtkblist->window, GDK_WATCH);
 
 	gaim_prefs_set_bool("/gaim/gtk/blist/show_offline_buddies",
 			gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(checkitem)));
 
-	if (gtkblist->window->window)
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+	gaim_gtk_clear_cursor(gtkblist->window);
 }
 
 static void gaim_gtk_blist_mute_sounds_cb(gpointer data, guint action, GtkWidget *item)
@@ -5766,21 +5731,12 @@
 {
 	if (gtk_check_menu_item_get_active(checkmenuitem))
 	{
-		if (gtkblist->window->window != NULL)
-		{
-			GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
-			gdk_window_set_cursor(gtkblist->window->window, cursor);
-			gdk_cursor_unref(cursor);
-		}
-
-		while (gtk_events_pending())
-			gtk_main_iteration();
+		gaim_gtk_set_cursor(gtkblist->window, GDK_WATCH);
 
 		gaim_gtk_blist_sort_method_set(id);
 		gaim_prefs_set_string("/gaim/gtk/blist/sort_type", id);
 
-		if (gtkblist->window->window != NULL)
-			gdk_window_set_cursor(gtkblist->window->window, NULL);
+		gaim_gtk_clear_cursor(gtkblist->window);
 	}
 }
 
--- a/src/gtkconv.c	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtkconv.c	Tue Mar 07 05:48:54 2006 +0000
@@ -1002,13 +1002,16 @@
 		return;
 
 	gtkblist = gaim_gtk_blist_get_default_gtk_blist();
+
 	cursor = gdk_cursor_new(GDK_WATCH);
-
 	gdk_window_set_cursor(gtkblist->window->window, cursor);
 	gdk_window_set_cursor(win->window->window, cursor);
 	gdk_cursor_unref(cursor);
-	while (gtk_events_pending())
-		gtk_main_iteration();
+#if GTK_CHECK_VERSION(2,4,0)
+	gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
+#else
+	gdk_flush();
+#endif
 
 	name = gaim_conversation_get_name(conv);
 	account = gaim_conversation_get_account(conv);
--- a/src/gtkdialogs.c	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtkdialogs.c	Tue Mar 07 05:48:54 2006 +0000
@@ -737,16 +737,12 @@
 	if (username != NULL && *username != '\0' && account != NULL)
 	{
 		GaimGtkBuddyList *gtkblist = gaim_gtk_blist_get_default_gtk_blist();
-		GdkCursor *cursor = gdk_cursor_new(GDK_WATCH);
 
-		gdk_window_set_cursor(gtkblist->window->window, cursor);
-		gdk_cursor_unref(cursor);
-		while (gtk_events_pending())
-			gtk_main_iteration();
+		gaim_gtk_set_cursor(gtkblist->window, GDK_WATCH);
 
 		gaim_gtk_log_show(GAIM_LOG_IM, username, account);
 
-		gdk_window_set_cursor(gtkblist->window->window, NULL);
+		gaim_gtk_clear_cursor(gtkblist->window);
 	}
 
 	g_free(username);
--- a/src/gtklog.c	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtklog.c	Tue Mar 07 05:48:54 2006 +0000
@@ -87,7 +87,6 @@
 {
 	const char *search_term = gtk_entry_get_text(GTK_ENTRY(lv->entry));
 	GList *logs;
-	GdkCursor *cursor;
 
 	if (lv->search != NULL)
 		g_free(lv->search);
@@ -103,11 +102,7 @@
 
 	lv->search = g_strdup(search_term);
 
-	cursor = gdk_cursor_new(GDK_WATCH);
-	gdk_window_set_cursor(lv->window->window, cursor);
-	gdk_cursor_unref(cursor);
-	while (gtk_events_pending())
-		gtk_main_iteration();
+	gaim_gtk_set_cursor(lv->window, GDK_WATCH);
 
 	for (logs = lv->logs; logs != NULL; logs = logs->next) {
 		char *read = gaim_log_read((GaimLog*)logs->data, NULL);
@@ -123,7 +118,7 @@
 		g_free(read);
 	}
 
-	gdk_window_set_cursor(lv->window->window, NULL);
+	gaim_gtk_clear_cursor(lv->window);
 }
 
 static gboolean destroy_cb(GtkWidget *w, gint resp, struct log_viewer_hash_t *ht) {
@@ -171,7 +166,6 @@
 	GValue val;
 	GtkTreeModel *model = GTK_TREE_MODEL(viewer->treestore);
 	GaimLog *log = NULL;
-	GdkCursor *cursor;
 	GaimLogReadFlags flags;
 	char *read = NULL;
 
@@ -186,15 +180,7 @@
 	if (log == NULL)
 		return;
 
-	/* When we set the initial log, this gets called and the window is still NULL. */
-	if (viewer->window->window != NULL)
-	{
-		cursor = gdk_cursor_new(GDK_WATCH);
-		gdk_window_set_cursor(viewer->window->window, cursor);
-		gdk_cursor_unref(cursor);
-		while (gtk_events_pending())
-			gtk_main_iteration();
-	}
+	gaim_gtk_set_cursor(viewer->window, GDK_WATCH);
 
 	if (log->type != GAIM_LOG_SYSTEM) {
 		char *title;
@@ -232,9 +218,7 @@
 		gtk_imhtml_search_find(GTK_IMHTML(viewer->imhtml), viewer->search);
 	}
 
-	/* When we set the initial log, this gets called and the window is still NULL. */
-	if (viewer->window->window != NULL)
-		gdk_window_set_cursor(viewer->window->window, NULL);
+	gaim_gtk_clear_cursor(viewer->window);
 }
 
 /* I want to make this smarter, but haven't come up with a cool algorithm to do so, yet.
--- a/src/gtkplugin.c	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtkplugin.c	Tue Mar 07 05:48:54 2006 +0000
@@ -255,14 +255,12 @@
 
 	if (!gaim_plugin_is_loaded(plug))
 	{
-		GdkCursor *wait = gdk_cursor_new (GDK_WATCH);
-		gdk_window_set_cursor(plugin_dialog->window, wait);
-		gdk_cursor_unref(wait);
+		gaim_gtk_set_cursor(plugin_dialog, GDK_WATCH);
 
 		gaim_plugin_load(plug);
 		plugin_toggled_stage_two(plug, model, iter, FALSE);
 
-		gdk_window_set_cursor(plugin_dialog->window, NULL);
+		gaim_gtk_clear_cursor(plugin_dialog);
 	}
 	else
 	{
@@ -309,13 +307,11 @@
 
 	if (unload)
 	{
-		GdkCursor *wait = gdk_cursor_new (GDK_WATCH);
-		gdk_window_set_cursor(plugin_dialog->window, wait);
-		gdk_cursor_unref(wait);
+		gaim_gtk_set_cursor(plugin_dialog, GDK_WATCH);
 
 		gaim_plugin_unload(plug);
 
-		gdk_window_set_cursor(plugin_dialog->window, NULL);
+		gaim_gtk_clear_cursor(plugin_dialog);
 	}
 
 	gtk_widget_set_sensitive(pref_button,
--- a/src/gtkrequest.c	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtkrequest.c	Tue Mar 07 05:48:54 2006 +0000
@@ -81,16 +81,12 @@
 static void
 generic_response_start(GaimGtkRequestData *data)
 {
-	GdkWindow *window = GTK_WIDGET(data->dialog)->window;
 	GdkCursor *cursor;
 
+	g_return_if_fail(data != NULL);
+
 	/* Tell the user we're doing something. */
-	cursor = gdk_cursor_new(GDK_WATCH);
-	gdk_window_set_cursor(window, cursor);
-	gdk_cursor_unref(cursor);
-	while (gtk_events_pending())
-		gtk_main_iteration();
-
+	gaim_gtk_set_cursor(GTK_WIDGET(data->dialog), GDK_WATCH);
 }
 
 static void
@@ -1396,7 +1392,7 @@
 			((GaimRequestFileCb)data->cbs[1])(data->user_data, data->u.file.name);
 		gaim_request_close(data->type, data);
 	} else {
-		gdk_window_set_cursor(GTK_WIDGET(data->dialog)->window, NULL);
+		gaim_gtk_clear_cursor(GTK_WIDGET(data->dialog));
 	}
 }
 
--- a/src/gtkutils.c	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtkutils.c	Tue Mar 07 05:48:54 2006 +0000
@@ -2180,3 +2180,29 @@
 	g_signal_connect(G_OBJECT(entry), "destroy", G_CALLBACK(screenname_autocomplete_destroyed_cb), NULL);
 }
 
+void gaim_gtk_set_cursor(GtkWidget *widget, GdkCursorType cursor_type)
+{
+	GdkCursor *cursor;
+
+	if (widget == NULL)
+		return;
+
+	cursor = gdk_cursor_new(GDK_WATCH);
+	gdk_window_set_cursor(widget->window, cursor);
+	gdk_cursor_unref(cursor);
+
+#if GTK_CHECK_VERSION(2,4,0)
+	gdk_display_flush(gdk_drawable_get_display(GDK_DRAWABLE(widget->window)));
+#else
+	gdk_flush();
+#endif
+}
+
+void gaim_gtk_clear_cursor(GtkWidget *widget)
+{
+	if (widget == NULL)
+		return;
+
+	gdk_window_set_cursor(widget->window, NULL);
+}
+
--- a/src/gtkutils.h	Tue Mar 07 05:09:51 2006 +0000
+++ b/src/gtkutils.h	Tue Mar 07 05:48:54 2006 +0000
@@ -438,4 +438,28 @@
 void gaim_gtk_append_menu_action(GtkWidget *menu, GaimMenuAction *act,
                                  gpointer gobject);
 
+/**
+ * Sets the mouse pointer for a GtkWidget.
+ *
+ * After setting the cursor, the display is flushed, so the change will
+ * take effect immediately.
+ *
+ * If @a widget is @c NULL, this function simply returns.
+ *
+ * @param widget      The widget for which to set the mouse pointer
+ * @param cursor_type The type of cursor to set
+ */
+void gaim_gtk_set_cursor(GtkWidget *widget, GdkCursorType cursor_type);
+
+/**
+ * Sets the mouse point for a GtkWidget back to that of its parent window.
+ *
+ * If @a widget is @c NULL, this function simply returns.
+ *
+ * @param widget The widget for which to clear the cursor
+ *
+ * @note The display is not flushed from this function.
+ */
+void gaim_gtk_clear_cursor(GtkWidget *widget);
+
 #endif /* _GAIM_GTKUTILS_H_ */