# HG changeset patch # User Richard Laager # Date 1141710534 0 # Node ID ffd724befbf8509ea5a27700d4b15ef9bd8394c9 # Parent 7ef6a2d0d9dac766dd36bcaccad71c985ea93301 [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 diff -r 7ef6a2d0d9da -r ffd724befbf8 plugins/ChangeLog.API --- 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. diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtkblist.c --- 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); } } diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtkconv.c --- 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); diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtkdialogs.c --- 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); diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtklog.c --- 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. diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtkplugin.c --- 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, diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtkrequest.c --- 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)); } } diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtkutils.c --- 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); +} + diff -r 7ef6a2d0d9da -r ffd724befbf8 src/gtkutils.h --- 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_ */