GNOME Bugzilla – Bug 561771
Setting layout sometimes fails silently
Last modified: 2010-06-22 20:05:03 UTC
This one is kind of quirky. If you: 1) Go to login, 2) Select a user, 3) Change the keyboard layout (let's say to "Norwegian"), 4) Cancel or fail the password check, 5) Select a user again, 6) Change the keyboard layout again, to the same item as in 3), the option menu will reflect your choice, but the keyboard layout will not be applied. So if "USA" was selected by default, and you changed away from that, the actual keyboard layout in use while entering the password will still be "USA" and not "Norwegian" like the option menu would have you believe. This produces hilarity when users have characters in their password that are produced by different key combinations in different keymaps (think [-/*=+] etc). This is due to a subtle logic error in gdm-option-widget.c:on_changed (): If the default item is NULL when the change signal arrives, no action is taken, which means the internal active_row reference won't be updated. This is not a problem on the first login attempt, because it's not possible to select anything until the default item is set. However, between the first and second login attempt, the widget's default item is set to NULL again, and then the selected item is set programmatically. This item will be shown in the option menu widget, but since the default item is NULL at the time, the "changed" signal is ignored, and active_row will not reflect the change. When the user selects the "Norwegian" keymap for the second time, that keymap is already (erroneously) pointed to by active_row, so the GdmOptionWidget thinks it's already the active choice, so no "activated" signal is emitted and the keymap is not applied.
Created attachment 123150 [details] [review] gdm-always-reflect-keyboard-layout.patch Tentative patch. Just remove the default_item_id check in on_changed (). I couldn't find a good reason why the check is being performed there - maybe to avoid problems when the widget is being populated? Seems to work fine without the check, though.
So, I don't remember why that check is there, but svn blame has: 2008-02-25 Ray Strode <rstrode@redhat.com> + * gui/simple-greeter/gdm-option-widget.[ch]: + (activate_from_item_id): allow NULL input + to deselect combo box + (gdm_option_widget_get_default_item): + (gdm_option_widget_set_default_item): + (gdm_option_widget_set_property): + (gdm_option_widget_get_property): + Add new concept of a default item, to fall + back to if the user hasn't picked on yet + (on_changed): If no default item is set + don't activate whatever invalid item is + selected + (gdm_option_widget_init): + (on_default_item_changed): set combo box + to insensitive if there is no default item + (name_cell_data_func): show the default item + in italics + (gdm_option_widget_remove_item): don't let the + default item get removed + IIRC, the default item is the item sent up from the daemon saying "This is what we'll use if you don't pick anything". It's also shown in italics so the user gets some indication what the default is if they choose something that's not the default. I guess between login attempts the defaults are reset. From the changelog entry above it says "set combo box to insensitive if there is no default item", so during that interval the combo boxes should be insensitive. I think what should be happening is sometime near the beginning of the second login attempt the daemon should be sending up a DefaultLayoutNameChanged signal, which should tell the greeter to set a new default and select it. I guess that's not happening? Or it's selecting it but not setting the default? I think the core bug might be there, if that's the case. Really we shouldn't ever be showing the user an option widget without a default item because Keyboard, Language, and Session all have defaults, and the user should get to know about those.
I think the problem is that the "changed" signal is being ignored, leaving active_row pointing to a row that's no longer the active one.
Between some changes yippi did a while ago and some changes I did today, I think this should be "fixed" now.