Merge lp:~kalgasnik/lightdm-gtk-greeter/lp-1445420-greeter-show-manual-login-fixed into lp:lightdm-gtk-greeter
- lp-1445420-greeter-show-manual-login-fixed
- Merge into trunk
Proposed by
Andrew P.
on 2015-07-04
| Status: | Needs review |
|---|---|
| Proposed branch: | lp:~kalgasnik/lightdm-gtk-greeter/lp-1445420-greeter-show-manual-login-fixed |
| Merge into: | lp:lightdm-gtk-greeter |
| Diff against target: |
799 lines (+355/-237) 3 files modified
src/greeterbackground.c (+3/-8) src/lightdm-gtk-greeter.c (+343/-222) src/lightdm-gtk-greeter.glade (+9/-7) |
| To merge this branch: | bzr merge lp:~kalgasnik/lightdm-gtk-greeter/lp-1445420-greeter-show-manual-login-fixed |
| Related bugs: |
| Reviewer | Review Type | Date Requested | Status |
|---|---|---|---|
| Sean Davis | 2015-07-04 | Needs Fixing on 2015-09-26 | |
|
Review via email:
|
|||
Commit Message
Description of the Change
1. Support of "greeter-
2. "Other" item is displayed dynamically.
3. Replacing literals with named constants (other, guest, model columns).
4. New column in users model - type. Will be used later for #1379710.
To post a comment you must log in.
| Sean Davis (bluesabre) wrote : | # |
From a quick overview, this looks like a reasonable patch. If it works for you, I'd say go ahead and merge it.
review:
Approve
| Sean Davis (bluesabre) wrote : | # |
Just tested this. When I lock my session, there are no available options and I cannot unlock.
review:
Needs Fixing
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
| 1 | === modified file 'src/greeterbackground.c' |
| 2 | --- src/greeterbackground.c 2015-06-26 06:00:10 +0000 |
| 3 | +++ src/greeterbackground.c 2015-07-04 17:20:19 +0000 |
| 4 | @@ -299,7 +299,7 @@ |
| 5 | |
| 6 | /* Implemented in lightdm-gtk-greeter.c */ |
| 7 | gpointer greeter_save_focus(GtkWidget* widget); |
| 8 | -void greeter_restore_focus(const gpointer saved_data); |
| 9 | +void greeter_restore_focus(gpointer* saved_data); |
| 10 | |
| 11 | static const MonitorConfig DEFAULT_MONITOR_CONFIG = |
| 12 | { |
| 13 | @@ -650,11 +650,7 @@ |
| 14 | if(!priv->active_monitor) |
| 15 | greeter_background_set_active_monitor(background, NULL); |
| 16 | |
| 17 | - if(saved_focus) |
| 18 | - { |
| 19 | - greeter_restore_focus(saved_focus); |
| 20 | - g_free(saved_focus); |
| 21 | - } |
| 22 | + greeter_restore_focus(&saved_focus); |
| 23 | |
| 24 | priv->screen_monitors_changed_handler_id = g_signal_connect(G_OBJECT(screen), "monitors-changed", |
| 25 | G_CALLBACK(greeter_background_monitors_changed_cb), |
| 26 | @@ -802,8 +798,7 @@ |
| 27 | gtk_container_add(GTK_CONTAINER(active->window), priv->child); |
| 28 | |
| 29 | gtk_window_present(active->window); |
| 30 | - greeter_restore_focus(focus); |
| 31 | - g_free(focus); |
| 32 | + greeter_restore_focus(&focus); |
| 33 | } |
| 34 | else |
| 35 | g_warning("[Background] Child widget is destroyed or not defined"); |
| 36 | |
| 37 | === modified file 'src/lightdm-gtk-greeter.c' |
| 38 | --- src/lightdm-gtk-greeter.c 2015-05-18 03:25:42 +0000 |
| 39 | +++ src/lightdm-gtk-greeter.c 2015-07-04 17:20:19 +0000 |
| 40 | @@ -214,6 +214,27 @@ |
| 41 | static void process_prompts (LightDMGreeter *greeter); |
| 42 | static void show_prompt_cb (LightDMGreeter *greeter, const gchar *text, LightDMPromptType type); |
| 43 | |
| 44 | +/* Users list */ |
| 45 | + |
| 46 | +typedef enum |
| 47 | +{ |
| 48 | + USERS_MODEL_TYPE, |
| 49 | + USERS_MODEL_NAME, |
| 50 | + USERS_MODEL_DISPLAY_NAME, |
| 51 | + USERS_MODEL_FONT_WEIGHT |
| 52 | +} UsersModelColumn; |
| 53 | + |
| 54 | +typedef enum |
| 55 | +{ |
| 56 | + USER_TYPE_REGULAR, |
| 57 | + USER_TYPE_GUEST, |
| 58 | + USER_TYPE_OTHER, |
| 59 | + USER_TYPE_INVALID |
| 60 | +} UserType; |
| 61 | + |
| 62 | +static const gchar *OTHER_USER_NAME = "*other"; |
| 63 | +static const gchar *GUEST_USER_NAME = "*guest"; |
| 64 | + |
| 65 | /* Panel and indicators */ |
| 66 | |
| 67 | typedef enum |
| 68 | @@ -290,14 +311,28 @@ |
| 69 | |
| 70 | static void read_monitor_configuration (const gchar *group, const gchar *name); |
| 71 | |
| 72 | -struct SavedFocusData |
| 73 | +static gboolean get_iter_by_str (GtkTreeModel *model, GtkTreeIter *iter, gint column, const gchar *value); |
| 74 | +static gint get_iter_by_intr (GtkTreeModel *model, GtkTreeIter *iter, gint column, gint value, gint search_length); |
| 75 | + |
| 76 | +typedef struct |
| 77 | { |
| 78 | GtkWidget *widget; |
| 79 | gint editable_pos; |
| 80 | -}; |
| 81 | - |
| 82 | -gpointer greeter_save_focus(GtkWidget* widget); |
| 83 | -void greeter_restore_focus(const gpointer saved_data); |
| 84 | +} SavedFocusData; |
| 85 | + |
| 86 | +SavedFocusData* greeter_save_focus (GtkWidget* widget); |
| 87 | +/* Restore focus, "focus" will be freed */ |
| 88 | +void greeter_restore_focus (SavedFocusData** focus); |
| 89 | + |
| 90 | +typedef struct |
| 91 | +{ |
| 92 | + GtkTreePath *path; |
| 93 | + UserType type; |
| 94 | +} SavedUserSelectionData; |
| 95 | + |
| 96 | +static SavedUserSelectionData* save_user_selection (void); |
| 97 | +/* Restore saved user selection, saved_data will be freed */ |
| 98 | +static void restore_user_selection (SavedUserSelectionData** saved_data, gboolean override_current); |
| 99 | |
| 100 | |
| 101 | static void |
| 102 | @@ -318,31 +353,127 @@ |
| 103 | g_free (background); |
| 104 | } |
| 105 | |
| 106 | -gpointer |
| 107 | -greeter_save_focus(GtkWidget* widget) |
| 108 | -{ |
| 109 | - GtkWidget *window = gtk_widget_get_toplevel(widget); |
| 110 | - if (!GTK_IS_WINDOW (window)) |
| 111 | + |
| 112 | +static gboolean |
| 113 | +get_iter_by_str (GtkTreeModel *model, GtkTreeIter *iter, gint column, const gchar *value) |
| 114 | +{ |
| 115 | + if (gtk_tree_model_get_iter_first (model, iter)) |
| 116 | + do |
| 117 | + { |
| 118 | + gchar *iter_value; |
| 119 | + gboolean matched; |
| 120 | + |
| 121 | + gtk_tree_model_get (model, iter, column, &iter_value, -1); |
| 122 | + matched = g_strcmp0 (iter_value, value) == 0; |
| 123 | + g_free (iter_value); |
| 124 | + if (matched) |
| 125 | + return TRUE; |
| 126 | + } while (gtk_tree_model_iter_next (model, iter)); |
| 127 | + |
| 128 | + return FALSE; |
| 129 | +} |
| 130 | + |
| 131 | +static gint |
| 132 | +get_iter_by_intr (GtkTreeModel *model, GtkTreeIter *iter, gint column, gint value, gint search_length) |
| 133 | +{ |
| 134 | + gint length = gtk_tree_model_iter_n_children (model, NULL); |
| 135 | + GtkTreePath *path = length ? gtk_tree_path_new_from_indices (length - 1, -1) : NULL; |
| 136 | + gboolean found = FALSE; |
| 137 | + gint iter_value; |
| 138 | + |
| 139 | + if (path && gtk_tree_model_get_iter (model, iter, path)) |
| 140 | + { |
| 141 | + do |
| 142 | + { |
| 143 | + gtk_tree_model_get (model, iter, column, &iter_value, -1); |
| 144 | + found = iter_value == value; |
| 145 | + } while (!found && --search_length != 0 && gtk_tree_model_iter_previous (model, iter)); |
| 146 | + } |
| 147 | + |
| 148 | + if (path) |
| 149 | + gtk_tree_path_free (path); |
| 150 | + return found; |
| 151 | +} |
| 152 | + |
| 153 | +SavedFocusData* |
| 154 | +greeter_save_focus (GtkWidget *widget) |
| 155 | +{ |
| 156 | + GtkWidget *window = gtk_widget_get_toplevel (widget); |
| 157 | + if(!GTK_IS_WINDOW (window)) |
| 158 | return NULL; |
| 159 | - |
| 160 | - struct SavedFocusData *data = g_new0 (struct SavedFocusData, 1); |
| 161 | - data->widget = gtk_window_get_focus (GTK_WINDOW (window)); |
| 162 | - data->editable_pos = GTK_IS_EDITABLE(data->widget) ? gtk_editable_get_position (GTK_EDITABLE (data->widget)) : -1; |
| 163 | + SavedFocusData* focus = g_new0 (SavedFocusData, 1); |
| 164 | + focus->widget = gtk_window_get_focus (GTK_WINDOW (window)); |
| 165 | + focus->editable_pos = GTK_IS_EDITABLE (focus->widget) ? gtk_editable_get_position (GTK_EDITABLE (focus->widget)) : -1; |
| 166 | + return focus; |
| 167 | +} |
| 168 | + |
| 169 | +void |
| 170 | +greeter_restore_focus (SavedFocusData** pfocus) |
| 171 | +{ |
| 172 | + g_return_if_fail (pfocus != NULL); |
| 173 | + |
| 174 | + SavedFocusData *focus = *pfocus; |
| 175 | + if(focus && GTK_IS_WIDGET (focus->widget)) |
| 176 | + { |
| 177 | + gtk_widget_grab_focus (focus->widget); |
| 178 | + if (GTK_IS_EDITABLE (focus->widget) && focus->editable_pos > -1) |
| 179 | + gtk_editable_set_position (GTK_EDITABLE (focus->widget), focus->editable_pos); |
| 180 | + } |
| 181 | + g_free (focus); |
| 182 | + *pfocus = NULL; |
| 183 | +} |
| 184 | + |
| 185 | +static SavedUserSelectionData* |
| 186 | +save_user_selection (void) |
| 187 | +{ |
| 188 | + SavedUserSelectionData *data = g_new0 (SavedUserSelectionData, 1); |
| 189 | + |
| 190 | + GtkTreeIter active_iter; |
| 191 | + if (gtk_combo_box_get_active_iter (user_combo, &active_iter)) |
| 192 | + { |
| 193 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 194 | + data->path = gtk_tree_model_get_path (model, &active_iter); |
| 195 | + gtk_tree_model_get (model, &active_iter, USERS_MODEL_TYPE, &data->type, -1); |
| 196 | + } |
| 197 | |
| 198 | return data; |
| 199 | } |
| 200 | |
| 201 | -void |
| 202 | -greeter_restore_focus(const gpointer saved_data) |
| 203 | +static void |
| 204 | +restore_user_selection (SavedUserSelectionData** pdata, gboolean override_current) |
| 205 | { |
| 206 | - struct SavedFocusData *data = saved_data; |
| 207 | - |
| 208 | - if (!saved_data || !GTK_IS_WIDGET (data->widget)) |
| 209 | - return; |
| 210 | - |
| 211 | - gtk_widget_grab_focus (data->widget); |
| 212 | - if (GTK_IS_EDITABLE(data->widget) && data->editable_pos > -1) |
| 213 | - gtk_editable_set_position(GTK_EDITABLE(data->widget), data->editable_pos); |
| 214 | + g_return_if_fail(pdata != NULL); |
| 215 | + |
| 216 | + SavedUserSelectionData* data = *pdata; |
| 217 | + GtkTreeIter active_iter; |
| 218 | + |
| 219 | + if (override_current || !gtk_combo_box_get_active_iter (user_combo, &active_iter)) |
| 220 | + { |
| 221 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 222 | + UserType new_active_type; |
| 223 | + gboolean iter_is_valid = FALSE; |
| 224 | + |
| 225 | + if (data->path) |
| 226 | + { |
| 227 | + iter_is_valid = gtk_tree_model_get_iter (model, &active_iter, data->path); |
| 228 | + if (iter_is_valid) |
| 229 | + gtk_tree_model_get (model, &active_iter, USERS_MODEL_TYPE, &new_active_type, -1); |
| 230 | + |
| 231 | + GtkTreeIter iter; |
| 232 | + if ((!iter_is_valid || data->type != new_active_type) && |
| 233 | + get_iter_by_intr (model, &iter, USERS_MODEL_TYPE, data->type, 2)) |
| 234 | + { |
| 235 | + iter_is_valid = TRUE; |
| 236 | + active_iter = iter; |
| 237 | + } |
| 238 | + } |
| 239 | + |
| 240 | + if (iter_is_valid || gtk_tree_model_get_iter_first (model, &active_iter)) |
| 241 | + gtk_combo_box_set_active_iter (user_combo, &active_iter); |
| 242 | + } |
| 243 | + |
| 244 | + gtk_tree_path_free (data->path); |
| 245 | + g_clear_pointer (pdata, g_free); |
| 246 | } |
| 247 | |
| 248 | static void |
| 249 | @@ -1856,24 +1987,6 @@ |
| 250 | lightdm_shutdown (NULL); |
| 251 | } |
| 252 | |
| 253 | -static void |
| 254 | -set_login_button_label (LightDMGreeter *greeter, const gchar *username) |
| 255 | -{ |
| 256 | - LightDMUser *user; |
| 257 | - gboolean logged_in = FALSE; |
| 258 | - |
| 259 | - user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username); |
| 260 | - if (user) |
| 261 | - logged_in = lightdm_user_get_logged_in (user); |
| 262 | - if (logged_in) |
| 263 | - gtk_button_set_label (login_button, _("Unlock")); |
| 264 | - else |
| 265 | - gtk_button_set_label (login_button, _("Log In")); |
| 266 | - /* and disable the session and language widgets */ |
| 267 | - gtk_widget_set_sensitive (GTK_WIDGET (session_menuitem), !logged_in); |
| 268 | - gtk_widget_set_sensitive (GTK_WIDGET (language_menuitem), !logged_in); |
| 269 | -} |
| 270 | - |
| 271 | static guint set_user_background_delayed_id = 0; |
| 272 | |
| 273 | static gboolean |
| 274 | @@ -1928,13 +2041,13 @@ |
| 275 | |
| 276 | config_set_string (STATE_SECTION_GREETER, STATE_KEY_LAST_USER, username); |
| 277 | |
| 278 | - if (g_strcmp0 (username, "*other") == 0) |
| 279 | + if (g_strcmp0 (username, OTHER_USER_NAME) == 0) |
| 280 | { |
| 281 | gtk_widget_show (GTK_WIDGET (username_entry)); |
| 282 | gtk_widget_show (GTK_WIDGET (cancel_button)); |
| 283 | lightdm_greeter_authenticate (greeter, NULL); |
| 284 | } |
| 285 | - else if (g_strcmp0 (username, "*guest") == 0) |
| 286 | + else if (g_strcmp0 (username, GUEST_USER_NAME) == 0) |
| 287 | { |
| 288 | lightdm_greeter_authenticate_as_guest (greeter); |
| 289 | } |
| 290 | @@ -1963,10 +2076,6 @@ |
| 291 | static void |
| 292 | cancel_authentication (void) |
| 293 | { |
| 294 | - GtkTreeModel *model; |
| 295 | - GtkTreeIter iter; |
| 296 | - gboolean other = FALSE; |
| 297 | - |
| 298 | if (pending_questions) |
| 299 | { |
| 300 | g_slist_free_full (pending_questions, (GDestroyNotify) pam_message_finalize); |
| 301 | @@ -1974,10 +2083,9 @@ |
| 302 | } |
| 303 | |
| 304 | /* If in authentication then stop that first */ |
| 305 | - cancelling = FALSE; |
| 306 | - if (lightdm_greeter_get_in_authentication (greeter)) |
| 307 | + cancelling = lightdm_greeter_get_in_authentication (greeter); |
| 308 | + if (cancelling) |
| 309 | { |
| 310 | - cancelling = TRUE; |
| 311 | lightdm_greeter_cancel_authentication (greeter); |
| 312 | set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, NULL); |
| 313 | } |
| 314 | @@ -1985,22 +2093,19 @@ |
| 315 | /* Make sure password entry is back to normal */ |
| 316 | gtk_entry_set_visibility (password_entry, FALSE); |
| 317 | |
| 318 | - /* Force refreshing the prompt_box for "Other" */ |
| 319 | - model = gtk_combo_box_get_model (user_combo); |
| 320 | - |
| 321 | - if (gtk_combo_box_get_active_iter (user_combo, &iter)) |
| 322 | + UserType user_type = gtk_widget_get_visible (GTK_WIDGET (user_combo)) ? USER_TYPE_INVALID : USER_TYPE_OTHER; |
| 323 | + if (user_type == USER_TYPE_INVALID) |
| 324 | { |
| 325 | - gchar *user; |
| 326 | - |
| 327 | - gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &user, -1); |
| 328 | - other = (g_strcmp0 (user, "*other") == 0); |
| 329 | - g_free (user); |
| 330 | + GtkTreeIter iter; |
| 331 | + if (gtk_combo_box_get_active_iter (user_combo, &iter)) |
| 332 | + gtk_tree_model_get (gtk_combo_box_get_model (user_combo), &iter, USERS_MODEL_TYPE, &user_type, -1); |
| 333 | } |
| 334 | |
| 335 | - /* Start a new login or return to the user list */ |
| 336 | - if (other || lightdm_greeter_get_hide_users_hint (greeter)) |
| 337 | - start_authentication ("*other"); |
| 338 | + if (user_type == USER_TYPE_OTHER) |
| 339 | + /* Force refreshing the prompt_box for "Other" */ |
| 340 | + start_authentication (OTHER_USER_NAME); |
| 341 | else |
| 342 | + /* Return to the user list */ |
| 343 | gtk_widget_grab_focus (GTK_WIDGET (user_combo)); |
| 344 | } |
| 345 | |
| 346 | @@ -2145,51 +2250,51 @@ |
| 347 | } |
| 348 | |
| 349 | static void |
| 350 | -set_displayed_user (LightDMGreeter *greeter, const gchar *username) |
| 351 | +set_displayed_user (LightDMGreeter *greeter, const gchar *user_name) |
| 352 | { |
| 353 | - gchar *user_tooltip; |
| 354 | - LightDMUser *user; |
| 355 | - |
| 356 | - if (g_strcmp0 (username, "*other") == 0) |
| 357 | - { |
| 358 | - gtk_widget_show (GTK_WIDGET (username_entry)); |
| 359 | - gtk_widget_show (GTK_WIDGET (cancel_button)); |
| 360 | - user_tooltip = g_strdup (_("Other")); |
| 361 | - } |
| 362 | - else |
| 363 | - { |
| 364 | - gtk_widget_hide (GTK_WIDGET (username_entry)); |
| 365 | - gtk_widget_hide (GTK_WIDGET (cancel_button)); |
| 366 | - user_tooltip = g_strdup (username); |
| 367 | - } |
| 368 | - |
| 369 | - /* At this moment we do not have information about possible prompts |
| 370 | - * for current user (except *guest). So, password_entry.visible changed in: |
| 371 | - * auth_complete_cb |
| 372 | - * process_prompts |
| 373 | - * and here - for *guest */ |
| 374 | - |
| 375 | - if (g_strcmp0 (username, "*guest") == 0) |
| 376 | - { |
| 377 | - user_tooltip = g_strdup (_("Guest Session")); |
| 378 | + UserType user_type = g_strcmp0 (user_name, OTHER_USER_NAME) == 0 ? USER_TYPE_OTHER : |
| 379 | + g_strcmp0 (user_name, GUEST_USER_NAME) == 0 ? USER_TYPE_GUEST : USER_TYPE_REGULAR; |
| 380 | + LightDMUser *user = NULL; |
| 381 | + const gchar *user_tooltip = user_name; |
| 382 | + gboolean logged_in = FALSE; |
| 383 | + |
| 384 | + gtk_widget_set_visible (GTK_WIDGET (username_entry), user_type == USER_TYPE_OTHER); |
| 385 | + gtk_widget_set_visible (GTK_WIDGET (cancel_button), user_type == USER_TYPE_OTHER); |
| 386 | + |
| 387 | + if (user_type == USER_TYPE_REGULAR) |
| 388 | + user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), user_name); |
| 389 | + else if (user_type == USER_TYPE_OTHER) |
| 390 | + user_tooltip = _("Other"); |
| 391 | + else if (user_type == USER_TYPE_GUEST) |
| 392 | + { |
| 393 | + user_tooltip = _("Guest Session"); |
| 394 | + /* At this moment we do not have information about possible prompts |
| 395 | + * for current user (except *guest). So, password_entry.visible changed in: |
| 396 | + * auth_complete_cb |
| 397 | + * process_prompts |
| 398 | + * and here - for *guest */ |
| 399 | gtk_widget_hide (GTK_WIDGET (password_entry)); |
| 400 | gtk_widget_grab_focus (GTK_WIDGET (user_combo)); |
| 401 | } |
| 402 | |
| 403 | - set_login_button_label (greeter, username); |
| 404 | - set_user_background (username); |
| 405 | - set_user_image (username); |
| 406 | - user = lightdm_user_list_get_user_by_name (lightdm_user_list_get_instance (), username); |
| 407 | if (user) |
| 408 | { |
| 409 | + logged_in = lightdm_user_get_logged_in (user); |
| 410 | set_language (lightdm_user_get_language (user)); |
| 411 | set_session (lightdm_user_get_session (user)); |
| 412 | } |
| 413 | else |
| 414 | set_language (lightdm_language_get_code (lightdm_get_language ())); |
| 415 | + |
| 416 | gtk_widget_set_tooltip_text (GTK_WIDGET (user_combo), user_tooltip); |
| 417 | - start_authentication (username); |
| 418 | - g_free (user_tooltip); |
| 419 | + gtk_widget_set_sensitive (GTK_WIDGET (session_menuitem), !logged_in); |
| 420 | + gtk_widget_set_sensitive (GTK_WIDGET (language_menuitem), !logged_in); |
| 421 | + gtk_button_set_label (login_button, logged_in ? _("Unlock") : _("Log In")); |
| 422 | + |
| 423 | + set_user_background (user_name); |
| 424 | + set_user_image (user_name); |
| 425 | + |
| 426 | + start_authentication (user_name); |
| 427 | } |
| 428 | |
| 429 | void user_combobox_active_changed_cb (GtkComboBox *widget, LightDMGreeter *greeter); |
| 430 | @@ -2197,19 +2302,14 @@ |
| 431 | void |
| 432 | user_combobox_active_changed_cb (GtkComboBox *widget, LightDMGreeter *greeter) |
| 433 | { |
| 434 | - GtkTreeModel *model; |
| 435 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 436 | GtkTreeIter iter; |
| 437 | |
| 438 | - model = gtk_combo_box_get_model (user_combo); |
| 439 | - |
| 440 | if (gtk_combo_box_get_active_iter (user_combo, &iter)) |
| 441 | { |
| 442 | gchar *user; |
| 443 | - |
| 444 | - gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &user, -1); |
| 445 | - |
| 446 | + gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, USERS_MODEL_NAME, &user, -1); |
| 447 | set_displayed_user (greeter, user); |
| 448 | - |
| 449 | g_free (user); |
| 450 | } |
| 451 | set_message_label (LIGHTDM_MESSAGE_TYPE_INFO, NULL); |
| 452 | @@ -2380,164 +2480,185 @@ |
| 453 | } |
| 454 | } |
| 455 | |
| 456 | -static void |
| 457 | -user_added_cb (LightDMUserList *user_list, LightDMUser *user, LightDMGreeter *greeter) |
| 458 | -{ |
| 459 | - GtkTreeModel *model; |
| 460 | - GtkTreeIter iter; |
| 461 | - gboolean logged_in = FALSE; |
| 462 | - |
| 463 | - model = gtk_combo_box_get_model (user_combo); |
| 464 | - |
| 465 | - logged_in = lightdm_user_get_logged_in (user); |
| 466 | - |
| 467 | - gtk_list_store_append (GTK_LIST_STORE (model), &iter); |
| 468 | +/* Controls visibility of "other" user. |
| 469 | + Must be called after any change of users list. */ |
| 470 | +static void |
| 471 | +update_manual_login_item (void) |
| 472 | +{ |
| 473 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 474 | + GtkTreeIter other_iter; |
| 475 | + /* "other" user must be the last, no need to check more than one */ |
| 476 | + gboolean other_iter_is_valid = get_iter_by_intr (model, &other_iter, USERS_MODEL_TYPE, USER_TYPE_OTHER, 1); |
| 477 | + |
| 478 | + gboolean show_manual_login = lightdm_greeter_get_show_manual_login_hint (greeter); |
| 479 | + if (!show_manual_login) |
| 480 | + { |
| 481 | + GtkTreeIter iter = other_iter; |
| 482 | + if (other_iter_is_valid) |
| 483 | + /* Force to show if "Other" is the only entry we have */ |
| 484 | + show_manual_login = !gtk_tree_model_iter_previous (model, &iter); |
| 485 | + else |
| 486 | + /* Or there are no other entries */ |
| 487 | + show_manual_login = !gtk_tree_model_get_iter_first (model, &iter); |
| 488 | + } |
| 489 | + |
| 490 | + if (show_manual_login && !other_iter_is_valid) |
| 491 | + { |
| 492 | + gtk_list_store_append (GTK_LIST_STORE (model), &other_iter); |
| 493 | + gtk_list_store_set (GTK_LIST_STORE (model), &other_iter, |
| 494 | + USERS_MODEL_TYPE, USER_TYPE_OTHER, |
| 495 | + USERS_MODEL_NAME, OTHER_USER_NAME, |
| 496 | + USERS_MODEL_DISPLAY_NAME, _("Other..."), |
| 497 | + USERS_MODEL_FONT_WEIGHT, PANGO_WEIGHT_NORMAL, |
| 498 | + -1); |
| 499 | + } |
| 500 | + else if (!show_manual_login && other_iter_is_valid) |
| 501 | + { |
| 502 | + gtk_list_store_remove (GTK_LIST_STORE (model), &other_iter); |
| 503 | + } |
| 504 | +} |
| 505 | + |
| 506 | +static void |
| 507 | +user_added_cb (LightDMUserList *user_list, LightDMUser *user) |
| 508 | +{ |
| 509 | + if (!gtk_widget_get_visible (GTK_WIDGET (user_combo))) |
| 510 | + return; |
| 511 | + |
| 512 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 513 | + GtkTreeIter iter, last_user_iter; |
| 514 | + gboolean logged_in = lightdm_user_get_logged_in (user); |
| 515 | + |
| 516 | + /* Insert item before "guest" and "other" accounts */ |
| 517 | + if (get_iter_by_intr (model, &last_user_iter, USERS_MODEL_TYPE, USER_TYPE_REGULAR, -1)) |
| 518 | + gtk_list_store_insert_after (GTK_LIST_STORE (model), &iter, &last_user_iter); |
| 519 | + else |
| 520 | + gtk_list_store_insert_after (GTK_LIST_STORE (model), &iter, NULL); |
| 521 | + |
| 522 | + SavedUserSelectionData* user_selection = save_user_selection (); |
| 523 | gtk_list_store_set (GTK_LIST_STORE (model), &iter, |
| 524 | - 0, lightdm_user_get_name (user), |
| 525 | - 1, lightdm_user_get_display_name (user), |
| 526 | - 2, logged_in ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
| 527 | + USERS_MODEL_TYPE, USER_TYPE_REGULAR, |
| 528 | + USERS_MODEL_NAME, lightdm_user_get_name (user), |
| 529 | + USERS_MODEL_DISPLAY_NAME, lightdm_user_get_display_name (user), |
| 530 | + USERS_MODEL_FONT_WEIGHT, logged_in ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
| 531 | -1); |
| 532 | -} |
| 533 | - |
| 534 | -static gboolean |
| 535 | -get_user_iter (const gchar *username, GtkTreeIter *iter) |
| 536 | -{ |
| 537 | - GtkTreeModel *model; |
| 538 | - |
| 539 | - model = gtk_combo_box_get_model (user_combo); |
| 540 | - |
| 541 | - if (!gtk_tree_model_get_iter_first (model, iter)) |
| 542 | - return FALSE; |
| 543 | - do |
| 544 | - { |
| 545 | - gchar *name; |
| 546 | - gboolean matched; |
| 547 | - |
| 548 | - gtk_tree_model_get (model, iter, 0, &name, -1); |
| 549 | - matched = g_strcmp0 (name, username) == 0; |
| 550 | - g_free (name); |
| 551 | - if (matched) |
| 552 | - return TRUE; |
| 553 | - } while (gtk_tree_model_iter_next (model, iter)); |
| 554 | - |
| 555 | - return FALSE; |
| 556 | + update_manual_login_item (); |
| 557 | + restore_user_selection (&user_selection, TRUE); |
| 558 | } |
| 559 | |
| 560 | static void |
| 561 | -user_changed_cb (LightDMUserList *user_list, LightDMUser *user, LightDMGreeter *greeter) |
| 562 | +user_changed_cb (LightDMUserList *user_list, LightDMUser *user) |
| 563 | { |
| 564 | - GtkTreeModel *model; |
| 565 | + if (!gtk_widget_get_visible (GTK_WIDGET (user_combo))) |
| 566 | + return; |
| 567 | + |
| 568 | + const gchar *name = lightdm_user_get_name (user); |
| 569 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 570 | GtkTreeIter iter; |
| 571 | - gboolean logged_in = FALSE; |
| 572 | |
| 573 | - if (!get_user_iter (lightdm_user_get_name (user), &iter)) |
| 574 | + if (!get_iter_by_str (model, &iter, USERS_MODEL_NAME, name)) |
| 575 | + { |
| 576 | + g_warning ("%s: model doesn't contain user '%s'", G_STRFUNC, name); |
| 577 | return; |
| 578 | - logged_in = lightdm_user_get_logged_in (user); |
| 579 | - |
| 580 | - model = gtk_combo_box_get_model (user_combo); |
| 581 | - |
| 582 | + } |
| 583 | + |
| 584 | + gboolean logged_in = lightdm_user_get_logged_in (user); |
| 585 | gtk_list_store_set (GTK_LIST_STORE (model), &iter, |
| 586 | - 0, lightdm_user_get_name (user), |
| 587 | - 1, lightdm_user_get_display_name (user), |
| 588 | - 2, logged_in ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
| 589 | + USERS_MODEL_DISPLAY_NAME, lightdm_user_get_display_name (user), |
| 590 | + USERS_MODEL_FONT_WEIGHT, logged_in ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
| 591 | -1); |
| 592 | } |
| 593 | |
| 594 | static void |
| 595 | user_removed_cb (LightDMUserList *user_list, LightDMUser *user) |
| 596 | { |
| 597 | - GtkTreeModel *model; |
| 598 | + if (!gtk_widget_get_visible (GTK_WIDGET (user_combo))) |
| 599 | + return; |
| 600 | + |
| 601 | + const gchar *name = lightdm_user_get_name (user); |
| 602 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 603 | GtkTreeIter iter; |
| 604 | |
| 605 | - if (!get_user_iter (lightdm_user_get_name (user), &iter)) |
| 606 | + if (!get_iter_by_str (model, &iter, USERS_MODEL_NAME, name)) |
| 607 | + { |
| 608 | + g_warning ("%s: model doesn't contain user '%s'", G_STRFUNC, name); |
| 609 | return; |
| 610 | + } |
| 611 | |
| 612 | - model = gtk_combo_box_get_model (user_combo); |
| 613 | + SavedUserSelectionData* user_selection = save_user_selection (); |
| 614 | gtk_list_store_remove (GTK_LIST_STORE (model), &iter); |
| 615 | + update_manual_login_item (); |
| 616 | + restore_user_selection (&user_selection, TRUE); |
| 617 | } |
| 618 | |
| 619 | static void |
| 620 | load_user_list (void) |
| 621 | { |
| 622 | - const GList *items, *item; |
| 623 | - GtkTreeModel *model; |
| 624 | - GtkTreeIter iter; |
| 625 | + LightDMUserList *lightdm_users = lightdm_user_list_get_instance (); |
| 626 | + |
| 627 | + g_signal_connect (lightdm_users, "user-added", G_CALLBACK (user_added_cb), NULL); |
| 628 | + g_signal_connect (lightdm_users, "user-changed", G_CALLBACK (user_changed_cb), NULL); |
| 629 | + g_signal_connect (lightdm_users, "user-removed", G_CALLBACK (user_removed_cb), NULL); |
| 630 | + |
| 631 | + if (!gtk_widget_get_visible (GTK_WIDGET (user_combo))) |
| 632 | + return; |
| 633 | + |
| 634 | + const GList *users = lightdm_user_list_get_users (lightdm_users); |
| 635 | + const GList *users_iter; |
| 636 | + GtkTreeModel *model = gtk_combo_box_get_model (user_combo); |
| 637 | + GtkTreeIter model_iter; |
| 638 | + |
| 639 | + for (users_iter = users; users_iter; users_iter = users_iter->next) |
| 640 | + { |
| 641 | + LightDMUser *user = users_iter->data; |
| 642 | + gboolean logged_in = lightdm_user_get_logged_in (user); |
| 643 | + |
| 644 | + gtk_list_store_append (GTK_LIST_STORE (model), &model_iter); |
| 645 | + gtk_list_store_set (GTK_LIST_STORE (model), &model_iter, |
| 646 | + USERS_MODEL_TYPE, USER_TYPE_REGULAR, |
| 647 | + USERS_MODEL_NAME, lightdm_user_get_name (user), |
| 648 | + USERS_MODEL_DISPLAY_NAME, lightdm_user_get_display_name (user), |
| 649 | + USERS_MODEL_FONT_WEIGHT, logged_in ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
| 650 | + -1); |
| 651 | + } |
| 652 | + |
| 653 | + if (lightdm_greeter_get_has_guest_account_hint (greeter)) |
| 654 | + { |
| 655 | + gtk_list_store_append (GTK_LIST_STORE (model), &model_iter); |
| 656 | + gtk_list_store_set (GTK_LIST_STORE (model), &model_iter, |
| 657 | + USERS_MODEL_TYPE, USER_TYPE_GUEST, |
| 658 | + USERS_MODEL_NAME, GUEST_USER_NAME, |
| 659 | + USERS_MODEL_DISPLAY_NAME, _("Guest Session"), |
| 660 | + USERS_MODEL_FONT_WEIGHT, PANGO_WEIGHT_NORMAL, |
| 661 | + -1); |
| 662 | + } |
| 663 | + |
| 664 | + update_manual_login_item (); |
| 665 | + |
| 666 | + /* Initial user selection */ |
| 667 | const gchar *selected_user; |
| 668 | - gboolean logged_in = FALSE; |
| 669 | - |
| 670 | - g_signal_connect (lightdm_user_list_get_instance (), "user-added", G_CALLBACK (user_added_cb), greeter); |
| 671 | - g_signal_connect (lightdm_user_list_get_instance (), "user-changed", G_CALLBACK (user_changed_cb), greeter); |
| 672 | - g_signal_connect (lightdm_user_list_get_instance (), "user-removed", G_CALLBACK (user_removed_cb), NULL); |
| 673 | - model = gtk_combo_box_get_model (user_combo); |
| 674 | - items = lightdm_user_list_get_users (lightdm_user_list_get_instance ()); |
| 675 | - for (item = items; item; item = item->next) |
| 676 | - { |
| 677 | - LightDMUser *user = item->data; |
| 678 | - logged_in = lightdm_user_get_logged_in (user); |
| 679 | - |
| 680 | - gtk_list_store_append (GTK_LIST_STORE (model), &iter); |
| 681 | - gtk_list_store_set (GTK_LIST_STORE (model), &iter, |
| 682 | - 0, lightdm_user_get_name (user), |
| 683 | - 1, lightdm_user_get_display_name (user), |
| 684 | - 2, logged_in ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, |
| 685 | - -1); |
| 686 | - } |
| 687 | - if (lightdm_greeter_get_has_guest_account_hint (greeter)) |
| 688 | - { |
| 689 | - gtk_list_store_append (GTK_LIST_STORE (model), &iter); |
| 690 | - gtk_list_store_set (GTK_LIST_STORE (model), &iter, |
| 691 | - 0, "*guest", |
| 692 | - 1, _("Guest Session"), |
| 693 | - 2, PANGO_WEIGHT_NORMAL, |
| 694 | - -1); |
| 695 | - } |
| 696 | - |
| 697 | - gtk_list_store_append (GTK_LIST_STORE (model), &iter); |
| 698 | - gtk_list_store_set (GTK_LIST_STORE (model), &iter, |
| 699 | - 0, "*other", |
| 700 | - 1, _("Other..."), |
| 701 | - 2, PANGO_WEIGHT_NORMAL, |
| 702 | - -1); |
| 703 | - |
| 704 | gchar *last_user = config_get_string (STATE_SECTION_GREETER, STATE_KEY_LAST_USER, NULL); |
| 705 | |
| 706 | if (lightdm_greeter_get_select_user_hint (greeter)) |
| 707 | selected_user = lightdm_greeter_get_select_user_hint (greeter); |
| 708 | else if (lightdm_greeter_get_select_guest_hint (greeter)) |
| 709 | - selected_user = "*guest"; |
| 710 | + selected_user = GUEST_USER_NAME; |
| 711 | else if (last_user) |
| 712 | selected_user = last_user; |
| 713 | else |
| 714 | selected_user = NULL; |
| 715 | |
| 716 | - if (gtk_tree_model_get_iter_first (model, &iter)) |
| 717 | + if (selected_user && get_iter_by_str (model, &model_iter, USERS_MODEL_NAME, selected_user)) |
| 718 | + { |
| 719 | + gtk_combo_box_set_active_iter (user_combo, &model_iter); |
| 720 | + set_displayed_user (greeter, selected_user); |
| 721 | + } |
| 722 | + else if (gtk_tree_model_get_iter_first (model, &model_iter)) |
| 723 | { |
| 724 | gchar *name; |
| 725 | - gboolean matched = FALSE; |
| 726 | - |
| 727 | - if (selected_user) |
| 728 | - { |
| 729 | - do |
| 730 | - { |
| 731 | - gtk_tree_model_get (model, &iter, 0, &name, -1); |
| 732 | - matched = g_strcmp0 (name, selected_user) == 0; |
| 733 | - g_free (name); |
| 734 | - if (matched) |
| 735 | - { |
| 736 | - gtk_combo_box_set_active_iter (user_combo, &iter); |
| 737 | - set_displayed_user (greeter, selected_user); |
| 738 | - break; |
| 739 | - } |
| 740 | - } while (gtk_tree_model_iter_next (model, &iter)); |
| 741 | - } |
| 742 | - if (!matched) |
| 743 | - { |
| 744 | - gtk_tree_model_get_iter_first (model, &iter); |
| 745 | - gtk_tree_model_get (model, &iter, 0, &name, -1); |
| 746 | - gtk_combo_box_set_active_iter (user_combo, &iter); |
| 747 | - set_displayed_user (greeter, name); |
| 748 | - g_free (name); |
| 749 | - } |
| 750 | + gtk_tree_model_get (model, &model_iter, USERS_MODEL_NAME, &name, -1); |
| 751 | + gtk_combo_box_set_active_iter (user_combo, &model_iter); |
| 752 | + set_displayed_user (greeter, name); |
| 753 | + g_free (name); |
| 754 | } |
| 755 | |
| 756 | g_free (last_user); |
| 757 | @@ -3059,7 +3180,7 @@ |
| 758 | if (lightdm_greeter_get_hide_users_hint (greeter)) |
| 759 | { |
| 760 | set_user_image (NULL); |
| 761 | - start_authentication ("*other"); |
| 762 | + start_authentication (OTHER_USER_NAME); |
| 763 | } |
| 764 | else |
| 765 | { |
| 766 | |
| 767 | === modified file 'src/lightdm-gtk-greeter.glade' |
| 768 | --- src/lightdm-gtk-greeter.glade 2015-06-29 15:11:04 +0000 |
| 769 | +++ src/lightdm-gtk-greeter.glade 2015-07-04 17:20:19 +0000 |
| 770 | @@ -343,11 +343,13 @@ |
| 771 | </object> |
| 772 | <object class="GtkListStore" id="user_liststore"> |
| 773 | <columns> |
| 774 | - <!-- column-name username --> |
| 775 | - <column type="gchararray"/> |
| 776 | - <!-- column-name label --> |
| 777 | - <column type="gchararray"/> |
| 778 | - <!-- column-name weight --> |
| 779 | + <!-- column-name type --> |
| 780 | + <column type="gint"/> |
| 781 | + <!-- column-name name --> |
| 782 | + <column type="gchararray"/> |
| 783 | + <!-- column-name display-name --> |
| 784 | + <column type="gchararray"/> |
| 785 | + <!-- column-name font-weight --> |
| 786 | <column type="gint"/> |
| 787 | </columns> |
| 788 | </object> |
| 789 | @@ -418,8 +420,8 @@ |
| 790 | <child> |
| 791 | <object class="GtkCellRendererText" id="cellrenderertext1"/> |
| 792 | <attributes> |
| 793 | - <attribute name="text">1</attribute> |
| 794 | - <attribute name="weight">2</attribute> |
| 795 | + <attribute name="text">2</attribute> |
| 796 | + <attribute name="weight">3</attribute> |
| 797 | </attributes> |
| 798 | </child> |
| 799 | </object> |
