Commit message: Update which monitor the unlock dialog is on when layout changes

Before we were moving the grabs but not the unlock dialog.
Everything needs to be in lock step, otherwise:

1) The unlock dialog won't get focus and will fail to work generally
2) Assumptions in the code about the two being in lock-step will
prove incorrect leading to the grabs getting dropped entirely.

Part of fix for
https://bugzilla.gnome.org/show_bug.cgi?id=609789
CVE-2010-0422
CVE: CVE-2010-0422
CWE: NVD-CWE-Other
Vulnerability description: gnome-screensaver 2.28.x before 2.28.3 does not properly synchronize the state of screen locking and the unlock dialog in situations involving a change to the number of monitors, which allows physically proximate attackers to bypass screen locking and access an unattended workstation by connecting and disconnecting monitors multiple times, a related issue to CVE-2010-0414.

Project: gnome-screensaver

on_screen_monitors_changed (GdkScreen *screen,
                            GSManager *manager)
{
        GSList *l;
        int     n_monitors;
        int     n_windows;
        int     i;

        n_monitors = gdk_screen_get_n_monitors (screen);
        n_windows = g_slist_length (manager->priv->windows);

        gs_debug ("Monitors changed for screen %d: num=%d",
                  gdk_screen_get_number (screen),
                  n_monitors);

        if (n_monitors > n_windows) {

                /* Tear down unlock dialog in case we want to move it
                 * to a new monitor
                 */
                l = manager->priv->windows;
                while (l != NULL) {
                        gs_window_cancel_unlock_request (GS_WINDOW (l->data));
                        l = l->next;
                }

                /* add more windows */
                for (i = n_windows; i < n_monitors; i++) {
                        gs_manager_create_window_for_monitor (manager, screen, i);
                }

                /* And put unlock dialog up where ever it's supposed to be
                 */
                gs_manager_request_unlock (manager);
        } else {

                gdk_x11_grab_server ();

                /* remove the extra windows */
                l = manager->priv->windows;
                while (l != NULL) {
                        GdkScreen *this_screen;
                        int        this_monitor;
                        GSList    *next = l->next;

                        this_screen = gs_window_get_screen (GS_WINDOW (l->data));
                        this_monitor = gs_window_get_monitor (GS_WINDOW (l->data));
                        if (this_screen == screen && this_monitor >= n_monitors) {
                                manager_maybe_stop_job_for_window (manager, GS_WINDOW (l->data));
                                g_hash_table_remove (manager->priv->jobs, l->data);
                                gs_window_destroy (GS_WINDOW (l->data));
                                manager->priv->windows = g_slist_delete_link (manager->priv->windows, l);
                        }
                        l = next;
                }

                /* make sure there is a lock dialog on a connected monitor,
                 * and that the keyboard is still properly grabbed after all
                 * the windows above got destroyed*/
                if (n_windows > n_monitors) {
                        gs_manager_request_unlock (manager);
                }

                gdk_flush ();
                gdk_x11_ungrab_server ();
        }
}