diff --git a/8-improve-animation.patch b/8-improve-animation.patch new file mode 100644 index 0000000..73d3a05 --- /dev/null +++ b/8-improve-animation.patch @@ -0,0 +1,210 @@ +--- gdm/gui/simple-greeter/gdm-greeter-login-window.c (revision 5571) ++++ gdm/gui/simple-greeter/gdm-greeter-login-window.c (revision 5573) +@@ -780,10 +780,6 @@ custom_widget_constructor (GladeXML + widget = gdm_session_chooser_widget_new (); + } + +- if (widget != NULL) { +- gtk_widget_show (widget); +- } +- + return widget; + } + +@@ -827,6 +823,8 @@ load_theme (GdmGreeterLoginWindow *login + G_CALLBACK (on_user_unchosen), + login_window); + ++ gtk_widget_show (login_window->priv->user_chooser); ++ + login_window->priv->session_chooser = + glade_xml_get_widget (login_window->priv->xml, "session-chooser"); + +--- gdm/gui/simple-greeter/gdm-chooser-widget.c (revision 5571) ++++ gdm/gui/simple-greeter/gdm-chooser-widget.c (revision 5573) +@@ -84,6 +84,7 @@ struct GdmChooserWidgetPrivate + guint animation_timeout_id; + + guint32 should_hide_inactive_items : 1; ++ guint32 emit_activated_after_animation : 1; + + GdmChooserWidgetPosition separator_position; + GdmChooserWidgetState state; +@@ -335,10 +336,16 @@ shrink_edge_toward_active_row (GdmChoose + } + + static gboolean +-iterate_animation (GdmChooserWidget *widget) ++run_animation (GdmChooserWidget *widget, ++ int number_of_iterations) + { + gboolean is_done; + ++ /* FIXME: this function could be done a lot more efficiently ++ * If we know we need to iterate more than once before the next redraw ++ * we should be able to avoid a lot of intermediate work ++ */ ++ + is_done = FALSE; + + if (widget->priv->state == GDM_CHOOSER_WIDGET_STATE_SHRINKING) { +@@ -357,6 +364,8 @@ iterate_animation (GdmChooserWidget *wid + GtkTreeIter iter; + gboolean is_visible; + ++ g_assert (widget->priv->state == GDM_CHOOSER_WIDGET_STATE_GROWING); ++ + path = gtk_tree_path_new_first (); + + do { +@@ -382,24 +391,70 @@ iterate_animation (GdmChooserWidget *wid + gtk_tree_path_free (path); + } + +- return is_done != TRUE; ++ number_of_iterations--; ++ ++ if (number_of_iterations == 0) { ++ return is_done; ++ } ++ ++ return run_animation (widget, number_of_iterations); ++} ++ ++static gboolean ++on_animation_timeout (GdmChooserWidget *widget) ++{ ++ return run_animation (widget, 1) != TRUE; + } + + static void +-stop_animation (GdmChooserWidget *widget) ++on_animation_done (GdmChooserWidget *widget) + { + if (widget->priv->animation_timeout_id == 0) { + return; + } + +- gtk_tree_row_reference_free (widget->priv->top_edge_row); +- widget->priv->top_edge_row = NULL; ++ if (widget->priv->top_edge_row != NULL) { ++ gtk_tree_row_reference_free (widget->priv->top_edge_row); ++ widget->priv->top_edge_row = NULL; ++ } + +- gtk_tree_row_reference_free (widget->priv->bottom_edge_row); +- widget->priv->bottom_edge_row = NULL; ++ if (widget->priv->bottom_edge_row != NULL) { ++ gtk_tree_row_reference_free (widget->priv->bottom_edge_row); ++ widget->priv->bottom_edge_row = NULL; ++ } + + widget->priv->animation_timeout_id = 0; + gtk_widget_set_sensitive (GTK_WIDGET (widget), TRUE); ++ ++ if (widget->priv->emit_activated_after_animation) { ++ g_signal_emit (widget, signals[ACTIVATED], 0); ++ widget->priv->emit_activated_after_animation = FALSE; ++ } ++} ++ ++static int ++get_number_of_on_screen_rows (GdmChooserWidget *widget) ++{ ++ GtkTreePath *start_path; ++ GtkTreePath *end_path; ++ int *start_index; ++ int *end_index; ++ int number_of_rows; ++ ++ if (!gtk_tree_view_get_visible_range (GTK_TREE_VIEW (widget->priv->items_view), ++ &start_path, &end_path)) { ++ return 0; ++ } ++ ++ start_index = gtk_tree_path_get_indices (start_path); ++ end_index = gtk_tree_path_get_indices (end_path); ++ ++ number_of_rows = *end_index - *start_index; ++ ++ gtk_tree_path_free (start_path); ++ gtk_tree_path_free (end_path); ++ ++ return number_of_rows; + } + + static void +@@ -417,8 +472,12 @@ start_animation (GdmChooserWidget *widge + number_of_rows = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (widget->priv->list_store), NULL); + + if (widget->priv->state == GDM_CHOOSER_WIDGET_STATE_SHRINKING) { ++ int number_of_on_screen_rows; ++ int number_of_iterations; ++ + if (number_of_visible_rows <= 1) { + widget->priv->state = GDM_CHOOSER_WIDGET_STATE_SHRUNK; ++ on_animation_done (widget); + return; + } + +@@ -434,11 +493,18 @@ start_animation (GdmChooserWidget *widge + gtk_tree_path_free (edge_path); + + g_assert (widget->priv->top_edge_row != NULL && widget->priv->bottom_edge_row != NULL); ++ ++ number_of_on_screen_rows = get_number_of_on_screen_rows (widget); ++ number_of_iterations = number_of_visible_rows - number_of_on_screen_rows; ++ number_of_iterations = MAX (0, number_of_iterations); ++ ++ run_animation (widget, number_of_iterations); + } + + if (widget->priv->state == GDM_CHOOSER_WIDGET_STATE_GROWING) { + if (number_of_visible_rows >= number_of_rows) { + widget->priv->state = GDM_CHOOSER_WIDGET_STATE_GROWN; ++ on_animation_done (widget); + return; + } + } +@@ -451,8 +517,8 @@ start_animation (GdmChooserWidget *widge + widget->priv->animation_timeout_id = + g_timeout_add_full (G_PRIORITY_DEFAULT_IDLE, + 1000 / (4 * number_of_rows), +- (GSourceFunc) iterate_animation, +- widget, (GDestroyNotify) stop_animation); ++ (GSourceFunc) on_animation_timeout, ++ widget, (GDestroyNotify) on_animation_done); + } + + static void +@@ -534,11 +600,14 @@ activate_from_row (GdmChooserWidget * + } + + widget->priv->active_row = gtk_tree_row_reference_copy (row); +- g_signal_emit (widget, signals[ACTIVATED], 0); + + if (widget->priv->should_hide_inactive_items) { ++ widget->priv->emit_activated_after_animation = TRUE; + gdm_chooser_widget_shrink (widget); ++ } else { ++ g_signal_emit (widget, signals[ACTIVATED], 0); + } ++ + } + + static void +@@ -551,11 +620,11 @@ deactivate (GdmChooserWidget *widget) + gtk_tree_row_reference_free (widget->priv->active_row); + widget->priv->active_row = NULL; + +- g_signal_emit (widget, signals[DEACTIVATED], 0, NULL, NULL); +- + if (widget->priv->state != GDM_CHOOSER_WIDGET_STATE_GROWN) { + gdm_chooser_widget_grow (widget); + } ++ ++ g_signal_emit (widget, signals[DEACTIVATED], 0); + } + + static void + diff --git a/gdm.spec b/gdm.spec index 0fb999d..cd19d88 100644 --- a/gdm.spec +++ b/gdm.spec @@ -16,7 +16,7 @@ Summary: The GNOME Display Manager Name: gdm Version: 2.21.2 -Release: 0.2007.11.20.6%{?dist} +Release: 0.2007.11.20.7%{?dist} Epoch: 1 License: GPLv2+ Group: User Interface/X @@ -88,7 +88,7 @@ Patch4: 4-switch-session-chooser-over.patch Patch5: 5-dont-shrink-in-test-program.patch Patch6: 6-session-chooser-in-login-window.patch Patch7: 7-login-window-animation.patch - +Patch8: 8-improve-animation.patch %description Gdm (the GNOME Display Manager) is a highly configurable @@ -106,6 +106,7 @@ several different X sessions on your local machine at the same time. %patch5 -p1 -b .dont-shrink-in-test-program %patch6 -p1 -b .session-chooser-in-login-window %patch7 -p1 -b .login-window-animation +%patch8 -p1 -b .improve-animation %build cp -f %{SOURCE1} data/gdm @@ -293,6 +294,9 @@ fi %attr(1770, root, gdm) %dir %{_localstatedir}/lib/gdm %changelog +* Wed Dec 19 2007 Ray Strode - 1:2.21.2-0.2007.11.20.7 +- Improve animation to be less jumpy + * Fri Dec 14 2007 Ray Strode - 1:2.21.2-0.2007.11.20.6 - Fix an uninitialized variable that makes the session list stop growing before its finished sometimes