summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Jon McCann <jmccann@redhat.com>2008-08-19 22:41:54 +0000
committerWilliam Jon McCann <mccann@src.gnome.org>2008-08-19 22:41:54 +0000
commita9edde71ff24c6ac5b37d690c8adc8079ab6e78d (patch)
tree167914d4062a5ed00cb6981ae65cc3e46cb393e7
parent6c5ff01e72255a8ae77a989d066cabb12d137648 (diff)
downloadgdm-a9edde71ff24c6ac5b37d690c8adc8079ab6e78d.tar.gz
Make activation of single item work a bit more reliably.
2008-08-19 William Jon McCann <jmccann@redhat.com> * gui/simple-greeter/gdm-chooser-widget.c (translate_view_path_to_list_path), (translate_list_path_to_view_path), (activate_from_item_id), (get_path_to_active_row), (on_shrink_animation_complete), (clear_selection), (activate_from_row), (get_selected_path), (gdm_chooser_widget_activate_selected_item), (gdm_chooser_widget_class_init), (on_row_activated), (on_selection_changed), (gdm_chooser_widget_init), (gdm_chooser_widget_add_item), (gdm_chooser_widget_remove_item), (gdm_chooser_widget_activate_if_one_item), (gdm_chooser_widget_loaded): * gui/simple-greeter/gdm-chooser-widget.h: * gui/simple-greeter/gdm-greeter-login-window.c (on_users_loaded), (on_user_chosen), (load_theme): * gui/simple-greeter/gdm-user-chooser-widget.c (on_users_loaded), (load_users), (gdm_user_chooser_widget_constructor), (gdm_user_chooser_widget_dispose): Make activation of single item work a bit more reliably. svn path=/trunk/; revision=6393
-rw-r--r--ChangeLog21
-rw-r--r--gui/simple-greeter/gdm-chooser-widget.c206
-rw-r--r--gui/simple-greeter/gdm-chooser-widget.h7
-rw-r--r--gui/simple-greeter/gdm-greeter-login-window.c18
-rw-r--r--gui/simple-greeter/gdm-user-chooser-widget.c53
5 files changed, 214 insertions, 91 deletions
diff --git a/ChangeLog b/ChangeLog
index e40e7ec6..d742885c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
2008-08-19 William Jon McCann <jmccann@redhat.com>
+ * gui/simple-greeter/gdm-chooser-widget.c
+ (translate_view_path_to_list_path),
+ (translate_list_path_to_view_path), (activate_from_item_id),
+ (get_path_to_active_row), (on_shrink_animation_complete),
+ (clear_selection), (activate_from_row), (get_selected_path),
+ (gdm_chooser_widget_activate_selected_item),
+ (gdm_chooser_widget_class_init), (on_row_activated),
+ (on_selection_changed), (gdm_chooser_widget_init),
+ (gdm_chooser_widget_add_item), (gdm_chooser_widget_remove_item),
+ (gdm_chooser_widget_activate_if_one_item),
+ (gdm_chooser_widget_loaded):
+ * gui/simple-greeter/gdm-chooser-widget.h:
+ * gui/simple-greeter/gdm-greeter-login-window.c (on_users_loaded),
+ (on_user_chosen), (load_theme):
+ * gui/simple-greeter/gdm-user-chooser-widget.c (on_users_loaded),
+ (load_users), (gdm_user_chooser_widget_constructor),
+ (gdm_user_chooser_widget_dispose):
+ Make activation of single item work a bit more reliably.
+
+2008-08-19 William Jon McCann <jmccann@redhat.com>
+
* gui/simple-greeter/gdm-chooser-widget.c (activate_if_one_item),
(gdm_chooser_widget_set_active_item),
(gdm_chooser_widget_set_activate_on_one_item):
diff --git a/gui/simple-greeter/gdm-chooser-widget.c b/gui/simple-greeter/gdm-chooser-widget.c
index 4c4ec334..ea6a0a9c 100644
--- a/gui/simple-greeter/gdm-chooser-widget.c
+++ b/gui/simple-greeter/gdm-chooser-widget.c
@@ -91,7 +91,6 @@ struct GdmChooserWidgetPrivate
guint32 should_hide_inactive_items : 1;
guint32 emit_activated_after_resize_animation : 1;
guint32 was_fully_grown : 1;
- guint32 activate_on_one_item : 1;
GdmChooserWidgetPosition separator_position;
GdmChooserWidgetState state;
@@ -109,6 +108,7 @@ enum {
enum {
ACTIVATED = 0,
DEACTIVATED,
+ LOADED,
NUMBER_OF_SIGNALS
};
@@ -123,6 +123,7 @@ static void update_timer_from_time (GdmChooserWidget *widget,
double now);
G_DEFINE_TYPE (GdmChooserWidget, gdm_chooser_widget, GTK_TYPE_ALIGNMENT)
+
enum {
CHOOSER_IMAGE_COLUMN = 0,
CHOOSER_NAME_COLUMN,
@@ -287,25 +288,69 @@ gdm_chooser_widget_get_active_item (GdmChooserWidget *widget)
}
static void
+translate_view_path_to_list_path (GdmChooserWidget *widget,
+ GtkTreePath **path)
+{
+ GtkTreePath *filtered_path;
+ GtkTreePath *sorted_path;
+
+ /* the child model is the source for the filter */
+ filtered_path = gtk_tree_model_filter_convert_path_to_child_path (widget->priv->model_filter,
+ *path);
+ sorted_path = gtk_tree_model_sort_convert_child_path_to_path (widget->priv->model_sorter,
+ filtered_path);
+ gtk_tree_path_free (filtered_path);
+
+ gtk_tree_path_free (*path);
+ *path = sorted_path;
+}
+
+static void
+translate_list_path_to_view_path (GdmChooserWidget *widget,
+ GtkTreePath **path)
+{
+ GtkTreePath *filtered_path;
+ GtkTreePath *sorted_path;
+
+ /* the child model is the source for the filter */
+ filtered_path = gtk_tree_model_filter_convert_child_path_to_path (widget->priv->model_filter,
+ *path);
+ sorted_path = gtk_tree_model_sort_convert_child_path_to_path (widget->priv->model_sorter,
+ filtered_path);
+ gtk_tree_path_free (filtered_path);
+
+ gtk_tree_path_free (*path);
+ *path = sorted_path;
+}
+
+static void
activate_from_item_id (GdmChooserWidget *widget,
const char *item_id)
{
GtkTreeModel *model;
GtkTreePath *path;
GtkTreeIter iter;
+ char *path_str;
model = GTK_TREE_MODEL (widget->priv->list_store);
path = NULL;
if (find_item (widget, item_id, &iter)) {
- GtkTreePath *child_path;
+ path = gtk_tree_model_get_path (model, &iter);
+
+ path_str = gtk_tree_path_to_string (path);
+ g_debug ("GdmChooserWidget: got path '%s'", path_str);
+ g_free (path_str);
- child_path = gtk_tree_model_get_path (model, &iter);
- path = gtk_tree_model_sort_convert_child_path_to_path (widget->priv->model_sorter, child_path);
- gtk_tree_path_free (child_path);
+ translate_list_path_to_view_path (widget, &path);
+
+ path_str = gtk_tree_path_to_string (path);
+ g_debug ("GdmChooserWidget: translated to path '%s'", path_str);
+ g_free (path_str);
}
if (path == NULL) {
+ g_debug ("GdmChooserWidget: unable to activate - path for item not found");
return;
}
@@ -359,23 +404,6 @@ set_frame_text (GdmChooserWidget *widget,
}
}
-static void
-translate_base_path_to_sorted_path (GdmChooserWidget *widget,
- GtkTreePath **path)
-{
- GtkTreePath *filtered_path;
- GtkTreePath *sorted_path;
-
- filtered_path =
- gtk_tree_model_filter_convert_child_path_to_path (widget->priv->model_filter, *path);
- sorted_path = gtk_tree_model_sort_convert_child_path_to_path (widget->priv->model_sorter,
- filtered_path);
- gtk_tree_path_free (filtered_path);
-
- gtk_tree_path_free (*path);
- *path = sorted_path;
-}
-
static GtkTreePath *
get_path_to_active_row (GdmChooserWidget *widget)
{
@@ -385,13 +413,13 @@ get_path_to_active_row (GdmChooserWidget *widget)
return NULL;
}
- path= gtk_tree_row_reference_get_path (widget->priv->active_row);
+ path = gtk_tree_row_reference_get_path (widget->priv->active_row);
if (path == NULL) {
return NULL;
}
- translate_base_path_to_sorted_path (widget, &path);
+ translate_list_path_to_view_path (widget, &path);
return path;
}
@@ -502,6 +530,8 @@ on_shrink_animation_complete (GdmScrollableWidget *scrollable_widget,
{
g_assert (widget->priv->state == GDM_CHOOSER_WIDGET_STATE_SHRINKING);
+ g_debug ("GdmChooserWidget: shrink complete");
+
widget->priv->active_row_normalized_position = 0.5;
set_inactive_items_visible (GDM_CHOOSER_WIDGET (widget), FALSE);
gtk_tree_view_set_enable_search (GTK_TREE_VIEW (widget->priv->items_view), FALSE);
@@ -796,6 +826,8 @@ clear_selection (GdmChooserWidget *widget)
GtkTreeSelection *selection;
GtkWidget *window;
+ g_debug ("GdmChooserWidget: clearing selection");
+
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->items_view));
gtk_tree_selection_unselect_all (selection);
@@ -848,9 +880,11 @@ activate_from_row (GdmChooserWidget *widget,
widget->priv->active_row = gtk_tree_row_reference_copy (row);
if (widget->priv->should_hide_inactive_items) {
+ g_debug ("GdmChooserWidget: will emit activated after resize");
widget->priv->emit_activated_after_resize_animation = TRUE;
gdm_chooser_widget_shrink (widget);
} else {
+ g_debug ("GdmChooserWidget: emitting activated");
g_signal_emit (widget, signals[ACTIVATED], 0);
}
}
@@ -880,54 +914,63 @@ deactivate (GdmChooserWidget *widget)
g_signal_emit (widget, signals[DEACTIVATED], 0);
}
-void
-gdm_chooser_widget_activate_selected_item (GdmChooserWidget *widget)
+static void
+get_selected_path (GdmChooserWidget *widget,
+ GtkTreePath **pathp)
{
- GtkTreeRowReference *row;
GtkTreeSelection *selection;
- GtkTreeModel *model;
GtkTreeModel *sort_model;
GtkTreeIter sorted_iter;
- gboolean is_already_active;
+ GtkTreePath *path;
- row = NULL;
- model = GTK_TREE_MODEL (widget->priv->list_store);
- is_already_active = FALSE;
+ path = NULL;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->items_view));
if (gtk_tree_selection_get_selected (selection, &sort_model, &sorted_iter)) {
- GtkTreePath *sorted_path;
- GtkTreePath *filtered_path;
- GtkTreePath *base_path;
g_assert (sort_model == GTK_TREE_MODEL (widget->priv->model_sorter));
- sorted_path = gtk_tree_model_get_path (sort_model, &sorted_iter);
- filtered_path =
- gtk_tree_model_sort_convert_path_to_child_path (widget->priv->model_sorter,
- sorted_path);
- gtk_tree_path_free (sorted_path);
- base_path =
- gtk_tree_model_filter_convert_path_to_child_path (widget->priv->model_filter,
- filtered_path);
+ path = gtk_tree_model_get_path (sort_model, &sorted_iter);
+ translate_view_path_to_list_path (widget, &path);
+ } else {
+ g_debug ("GdmChooserWidget: no rows selected");
+ }
- if (widget->priv->active_row != NULL) {
- GtkTreePath *active_path;
+ *pathp = path;
+}
- active_path = gtk_tree_row_reference_get_path (widget->priv->active_row);
+void
+gdm_chooser_widget_activate_selected_item (GdmChooserWidget *widget)
+{
+ GtkTreeRowReference *row;
+ gboolean is_already_active;
+ GtkTreePath *path;
+ GtkTreeModel *model;
- if (gtk_tree_path_compare (base_path, active_path) == 0) {
- is_already_active = TRUE;
- }
- gtk_tree_path_free (active_path);
+ row = NULL;
+ model = GTK_TREE_MODEL (widget->priv->list_store);
+ is_already_active = FALSE;
+
+ get_selected_path (widget, &path);
+
+ if (widget->priv->active_row != NULL) {
+ GtkTreePath *active_path;
+
+ active_path = gtk_tree_row_reference_get_path (widget->priv->active_row);
+
+ if (gtk_tree_path_compare (path, active_path) == 0) {
+ is_already_active = TRUE;
}
- g_assert (base_path != NULL);
- row = gtk_tree_row_reference_new (model, base_path);
- gtk_tree_path_free (base_path);
+ gtk_tree_path_free (active_path);
}
+ g_assert (path != NULL);
+ row = gtk_tree_row_reference_new (model, path);
+ gtk_tree_path_free (path);
if (!is_already_active) {
activate_from_row (widget, row);
+ } else {
+ g_debug ("GdmChooserWidget: row is already active");
}
gtk_tree_row_reference_free (row);
}
@@ -1124,6 +1167,16 @@ gdm_chooser_widget_class_init (GdmChooserWidgetClass *klass)
widget_class->focus = gdm_chooser_widget_focus;
widget_class->focus_in_event = gdm_chooser_widget_focus_in_event;
+ signals [LOADED] = g_signal_new ("loaded",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GdmChooserWidgetClass, loaded),
+ NULL,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
signals [ACTIVATED] = g_signal_new ("activated",
G_TYPE_FROM_CLASS (object_class),
G_SIGNAL_RUN_LAST,
@@ -1172,6 +1225,11 @@ on_row_activated (GtkTreeView *tree_view,
GtkTreeViewColumn *tree_column,
GdmChooserWidget *widget)
{
+ char *path_str;
+
+ path_str = gtk_tree_path_to_string (tree_path);
+ g_debug ("GdmChooserWidget: row activated '%s'", path_str ? path_str : "(null)");
+ g_free (path_str);
gdm_chooser_widget_activate_selected_item (widget);
}
@@ -1572,6 +1630,23 @@ search_equal_func (GtkTreeModel *model,
}
static void
+on_selection_changed (GtkTreeSelection *selection,
+ GdmChooserWidget *widget)
+{
+ GtkTreePath *path;
+
+ get_selected_path (widget, &path);
+ if (path != NULL) {
+ char *path_str;
+ path_str = gtk_tree_path_to_string (path);
+ g_debug ("GdmChooserWidget: selection change to path '%s'", path_str);
+ g_free (path_str);
+ } else {
+ g_debug ("GdmChooserWidget: selection cleared");
+ }
+}
+
+static void
gdm_chooser_widget_init (GdmChooserWidget *widget)
{
GtkTreeViewColumn *column;
@@ -1625,6 +1700,8 @@ gdm_chooser_widget_init (GdmChooserWidget *widget)
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (widget->priv->items_view));
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+ g_signal_connect (selection, "changed", G_CALLBACK (on_selection_changed), widget);
+
g_assert (NUMBER_OF_CHOOSER_COLUMNS == 11);
widget->priv->list_store = gtk_list_store_new (NUMBER_OF_CHOOSER_COLUMNS,
GDK_TYPE_PIXBUF,
@@ -1881,10 +1958,6 @@ gdm_chooser_widget_add_item (GdmChooserWidget *widget,
-1);
move_cursor_to_top (widget);
-
- if (widget->priv->activate_on_one_item) {
- activate_if_one_item (widget);
- }
}
void
@@ -1933,10 +2006,6 @@ gdm_chooser_widget_remove_item (GdmChooserWidget *widget,
gtk_list_store_remove (widget->priv->list_store, &iter);
move_cursor_to_top (widget);
-
- if (widget->priv->activate_on_one_item) {
- activate_if_one_item (widget);
- }
}
gboolean
@@ -2304,14 +2373,9 @@ gdm_chooser_widget_get_number_of_items (GdmChooserWidget *widget)
}
void
-gdm_chooser_widget_set_activate_on_one_item (GdmChooserWidget *widget,
- gboolean should_activate)
+gdm_chooser_widget_activate_if_one_item (GdmChooserWidget *widget)
{
- widget->priv->activate_on_one_item = should_activate;
-
- if (widget->priv->activate_on_one_item) {
- activate_if_one_item (widget);
- }
+ activate_if_one_item (widget);
}
void
@@ -2323,3 +2387,9 @@ gdm_chooser_widget_propagate_pending_key_events (GdmChooserWidget *widget)
gdm_scrollable_widget_replay_queued_key_events (GDM_SCROLLABLE_WIDGET (widget->priv->scrollable_widget));
}
+
+void
+gdm_chooser_widget_loaded (GdmChooserWidget *widget)
+{
+ g_signal_emit (widget, signals[LOADED], 0);
+}
diff --git a/gui/simple-greeter/gdm-chooser-widget.h b/gui/simple-greeter/gdm-chooser-widget.h
index 83a0dfa2..a8ce4946 100644
--- a/gui/simple-greeter/gdm-chooser-widget.h
+++ b/gui/simple-greeter/gdm-chooser-widget.h
@@ -46,6 +46,8 @@ typedef struct
{
GtkAlignmentClass parent_class;
+ void (* loaded) (GdmChooserWidget *widget);
+
void (* activated) (GdmChooserWidget *widget);
void (* deactivated) (GdmChooserWidget *widget);
} GdmChooserWidgetClass;
@@ -127,10 +129,11 @@ void gdm_chooser_widget_set_hide_inactive_items (GdmChooserWidge
void gdm_chooser_widget_activate_selected_item (GdmChooserWidget *widget);
int gdm_chooser_widget_get_number_of_items (GdmChooserWidget *widget);
-void gdm_chooser_widget_set_activate_on_one_item (GdmChooserWidget *widget,
- gboolean should_activate);
+void gdm_chooser_widget_activate_if_one_item (GdmChooserWidget *widget);
void gdm_chooser_widget_propagate_pending_key_events (GdmChooserWidget *widget);
+void gdm_chooser_widget_loaded (GdmChooserWidget *widget);
+
G_END_DECLS
#endif /* __GDM_CHOOSER_WIDGET_H */
diff --git a/gui/simple-greeter/gdm-greeter-login-window.c b/gui/simple-greeter/gdm-greeter-login-window.c
index 0de76375..001301c9 100644
--- a/gui/simple-greeter/gdm-greeter-login-window.c
+++ b/gui/simple-greeter/gdm-greeter-login-window.c
@@ -1362,12 +1362,21 @@ shutdown_button_clicked (GtkButton *button,
}
static void
+on_users_loaded (GdmUserChooserWidget *user_chooser,
+ GdmGreeterLoginWindow *login_window)
+{
+ gdm_chooser_widget_activate_if_one_item (GDM_CHOOSER_WIDGET (login_window->priv->user_chooser));
+}
+
+static void
on_user_chosen (GdmUserChooserWidget *user_chooser,
GdmGreeterLoginWindow *login_window)
{
char *user_name;
user_name = gdm_user_chooser_widget_get_chosen_user_name (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser));
+ g_debug ("GdmGreeterLoginWindow: user chosen '%s'", user_name);
+
if (user_name == NULL) {
return;
}
@@ -1606,9 +1615,8 @@ load_theme (GdmGreeterLoginWindow *login_window)
box = glade_xml_get_widget (login_window->priv->xml, "window-box");
gtk_container_add (GTK_CONTAINER (login_window), box);
- login_window->priv->user_chooser =
- glade_xml_get_widget (login_window->priv->xml, "user-chooser");
-
+ login_window->priv->user_chooser = glade_xml_get_widget (login_window->priv->xml,
+ "user-chooser");
if (login_window->priv->user_chooser == NULL) {
g_critical ("Userlist box not found");
}
@@ -1616,6 +1624,10 @@ load_theme (GdmGreeterLoginWindow *login_window)
gdm_user_chooser_widget_set_show_only_chosen (GDM_USER_CHOOSER_WIDGET (login_window->priv->user_chooser), TRUE);
g_signal_connect (login_window->priv->user_chooser,
+ "loaded",
+ G_CALLBACK (on_users_loaded),
+ login_window);
+ g_signal_connect (login_window->priv->user_chooser,
"activated",
G_CALLBACK (on_user_chosen),
login_window);
diff --git a/gui/simple-greeter/gdm-user-chooser-widget.c b/gui/simple-greeter/gdm-user-chooser-widget.c
index f4b96188..4212ff04 100644
--- a/gui/simple-greeter/gdm-user-chooser-widget.c
+++ b/gui/simple-greeter/gdm-user-chooser-widget.c
@@ -66,6 +66,8 @@ struct GdmUserChooserWidgetPrivate
guint show_guest_user : 1;
guint show_auto_user : 1;
guint show_normal_users : 1;
+
+ guint load_idle_id;
};
enum {
@@ -383,22 +385,18 @@ on_users_loaded (GdmUserManager *manager,
}
gtk_widget_grab_focus (GTK_WIDGET (widget));
- gdm_chooser_widget_set_activate_on_one_item (GDM_CHOOSER_WIDGET (widget),
- TRUE);
+
+ gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET (widget));
}
-static GObject *
-gdm_user_chooser_widget_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam *construct_properties)
+static gboolean
+load_users (GdmUserChooserWidget *widget)
{
- GdmUserChooserWidget *widget;
-
- widget = GDM_USER_CHOOSER_WIDGET (G_OBJECT_CLASS (gdm_user_chooser_widget_parent_class)->constructor (type,
- n_construct_properties,
- construct_properties));
- widget->priv->show_normal_users = !is_user_list_disabled (widget);
+ /* FIXME: make these construct properties */
+ gdm_user_chooser_widget_set_show_guest_user (widget, FALSE);
+ gdm_user_chooser_widget_set_show_auto_user (widget, FALSE);
+ gdm_user_chooser_widget_set_show_other_user (widget, TRUE);
if (widget->priv->show_normal_users) {
widget->priv->manager = gdm_user_manager_ref_default ();
@@ -423,14 +421,28 @@ gdm_user_chooser_widget_constructor (GType type,
G_CALLBACK (on_user_login_frequency_changed),
widget);
} else {
- gdm_chooser_widget_set_activate_on_one_item (GDM_CHOOSER_WIDGET (widget),
- TRUE);
+ gdm_chooser_widget_loaded (GDM_CHOOSER_WIDGET (widget));
}
- /* FIXME: make these construct properties */
- gdm_user_chooser_widget_set_show_guest_user (widget, FALSE);
- gdm_user_chooser_widget_set_show_auto_user (widget, FALSE);
- gdm_user_chooser_widget_set_show_other_user (widget, TRUE);
+ widget->priv->load_idle_id = 0;
+
+ return FALSE;
+}
+
+static GObject *
+gdm_user_chooser_widget_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam *construct_properties)
+{
+ GdmUserChooserWidget *widget;
+
+ widget = GDM_USER_CHOOSER_WIDGET (G_OBJECT_CLASS (gdm_user_chooser_widget_parent_class)->constructor (type,
+ n_construct_properties,
+ construct_properties));
+
+ widget->priv->show_normal_users = !is_user_list_disabled (widget);
+
+ widget->priv->load_idle_id = g_idle_add ((GSourceFunc)load_users, widget);
return G_OBJECT (widget);
}
@@ -444,6 +456,11 @@ gdm_user_chooser_widget_dispose (GObject *object)
G_OBJECT_CLASS (gdm_user_chooser_widget_parent_class)->dispose (object);
+ if (widget->priv->load_idle_id > 0) {
+ g_source_remove (widget->priv->load_idle_id);
+ widget->priv->load_idle_id = 0;
+ }
+
if (widget->priv->logged_in_pixbuf != NULL) {
g_object_unref (widget->priv->logged_in_pixbuf);
widget->priv->logged_in_pixbuf = NULL;