[gnome-screensaver] Properly handle monitor configuration changes
- From: William Jon McCann <mccann src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-screensaver] Properly handle monitor configuration changes
- Date: Mon, 21 Jun 2010 18:44:25 +0000 (UTC)
commit 3616731382c69c148054c001c4625f5047a9630f
Author: William Jon McCann <jmccann redhat com>
Date: Mon Jun 21 14:42:31 2010 -0400
Properly handle monitor configuration changes
The issue comes down to a few things.
* When a monitor reconfiguration event occurs between the time we spawn a
dialog process and the time a dialog window is mapped and its window id is
communicated to the daemon we don't properly cancel the current unlock request.
* The present unlock request cancellation code is not symmetric/consistent
with the unlock request code. In other words we aren't properly resetting
state.
https://bugzilla.gnome.org/show_bug.cgi?id=619773
src/gs-manager.c | 163 +++++++++++++++++++++++++++-----------------------
src/gs-window-x11.c | 122 +++++++++++++++++++++-----------------
src/gs-window.h | 1 +
3 files changed, 157 insertions(+), 129 deletions(-)
---
diff --git a/src/gs-manager.c b/src/gs-manager.c
index aea72f3..34ff403 100644
--- a/src/gs-manager.c
+++ b/src/gs-manager.c
@@ -1069,75 +1069,6 @@ window_deactivated_cb (GSWindow *window,
g_idle_add ((GSourceFunc)window_deactivated_idle, manager);
}
-static void
-window_dialog_up_cb (GSWindow *window,
- GSManager *manager)
-{
- GSList *l;
-
- g_return_if_fail (manager != NULL);
- g_return_if_fail (GS_IS_MANAGER (manager));
-
- gs_debug ("Handling dialog up");
-
- g_signal_emit (manager, signals [AUTH_REQUEST_BEGIN], 0);
-
- manager->priv->dialog_up = TRUE;
- /* Make all other windows insensitive so we don't get events */
- for (l = manager->priv->windows; l; l = l->next) {
- if (l->data != window) {
- gtk_widget_set_sensitive (GTK_WIDGET (l->data), FALSE);
- }
- }
-
- /* Move keyboard and mouse grabs so dialog can be used */
- gs_grab_move_to_window (manager->priv->grab,
- gs_window_get_gdk_window (window),
- gs_window_get_screen (window),
- FALSE);
-
- /* Release the pointer grab while dialog is up so that
- the dialog can be used. We'll regrab it when the dialog goes down. */
- gs_grab_release_mouse (manager->priv->grab);
-
- if (! manager->priv->throttled) {
- gs_debug ("Suspending jobs");
-
- manager_suspend_jobs (manager);
- }
-}
-
-static void
-window_dialog_down_cb (GSWindow *window,
- GSManager *manager)
-{
- GSList *l;
-
- g_return_if_fail (manager != NULL);
- g_return_if_fail (GS_IS_MANAGER (manager));
-
- gs_debug ("Handling dialog down");
-
- /* Regrab the mouse */
- gs_grab_move_to_window (manager->priv->grab,
- gs_window_get_gdk_window (window),
- gs_window_get_screen (window),
- FALSE);
-
- /* Make all windows sensitive so we get events */
- for (l = manager->priv->windows; l; l = l->next) {
- gtk_widget_set_sensitive (GTK_WIDGET (l->data), TRUE);
- }
-
- manager->priv->dialog_up = FALSE;
-
- if (! manager->priv->throttled) {
- manager_resume_jobs (manager);
- }
-
- g_signal_emit (manager, signals [AUTH_REQUEST_END], 0);
-}
-
static GSWindow *
find_window_at_pointer (GSManager *manager)
{
@@ -1380,6 +1311,91 @@ window_obscured_cb (GSWindow *window,
}
}
+static void
+handle_window_dialog_up (GSManager *manager,
+ GSWindow *window)
+{
+ GSList *l;
+
+ g_return_if_fail (manager != NULL);
+ g_return_if_fail (GS_IS_MANAGER (manager));
+
+ gs_debug ("Handling dialog up");
+
+ g_signal_emit (manager, signals [AUTH_REQUEST_BEGIN], 0);
+
+ manager->priv->dialog_up = TRUE;
+ /* Make all other windows insensitive so we don't get events */
+ for (l = manager->priv->windows; l; l = l->next) {
+ if (l->data != window) {
+ gtk_widget_set_sensitive (GTK_WIDGET (l->data), FALSE);
+ }
+ }
+
+ /* Move keyboard and mouse grabs so dialog can be used */
+ gs_grab_move_to_window (manager->priv->grab,
+ gs_window_get_gdk_window (window),
+ gs_window_get_screen (window),
+ FALSE);
+
+ /* Release the pointer grab while dialog is up so that
+ the dialog can be used. We'll regrab it when the dialog goes down. */
+ gs_grab_release_mouse (manager->priv->grab);
+
+ if (! manager->priv->throttled) {
+ gs_debug ("Suspending jobs");
+
+ manager_suspend_jobs (manager);
+ }
+}
+
+static void
+handle_window_dialog_down (GSManager *manager,
+ GSWindow *window)
+{
+ GSList *l;
+
+ g_return_if_fail (manager != NULL);
+ g_return_if_fail (GS_IS_MANAGER (manager));
+
+ gs_debug ("Handling dialog down");
+
+ /* Regrab the mouse */
+ gs_grab_move_to_window (manager->priv->grab,
+ gs_window_get_gdk_window (window),
+ gs_window_get_screen (window),
+ FALSE);
+
+ /* Make all windows sensitive so we get events */
+ for (l = manager->priv->windows; l; l = l->next) {
+ gtk_widget_set_sensitive (GTK_WIDGET (l->data), TRUE);
+ }
+
+ manager->priv->dialog_up = FALSE;
+
+ if (! manager->priv->throttled) {
+ manager_resume_jobs (manager);
+ }
+
+ g_signal_emit (manager, signals [AUTH_REQUEST_END], 0);
+}
+
+static void
+window_dialog_up_changed_cb (GSWindow *window,
+ GParamSpec *pspec,
+ GSManager *manager)
+{
+ gboolean up;
+
+ up = gs_window_is_dialog_up (window);
+ gs_debug ("Handling window dialog up changed: %s", up ? "up" : "down");
+ if (up) {
+ handle_window_dialog_up (manager, window);
+ } else {
+ handle_window_dialog_down (manager, window);
+ }
+}
+
static gboolean
window_activity_cb (GSWindow *window,
GSManager *manager)
@@ -1397,12 +1413,11 @@ disconnect_window_signals (GSManager *manager,
{
g_signal_handlers_disconnect_by_func (window, window_deactivated_cb, manager);
g_signal_handlers_disconnect_by_func (window, window_activity_cb, manager);
- g_signal_handlers_disconnect_by_func (window, window_dialog_up_cb, manager);
- g_signal_handlers_disconnect_by_func (window, window_dialog_down_cb, manager);
g_signal_handlers_disconnect_by_func (window, window_show_cb, manager);
g_signal_handlers_disconnect_by_func (window, window_map_cb, manager);
g_signal_handlers_disconnect_by_func (window, window_map_event_cb, manager);
g_signal_handlers_disconnect_by_func (window, window_obscured_cb, manager);
+ g_signal_handlers_disconnect_by_func (window, window_dialog_up_changed_cb, manager);
g_signal_handlers_disconnect_by_func (window, window_unmap_cb, manager);
g_signal_handlers_disconnect_by_func (window, window_grab_broken_cb, manager);
}
@@ -1424,10 +1439,6 @@ connect_window_signals (GSManager *manager,
G_CALLBACK (window_activity_cb), manager, 0);
g_signal_connect_object (window, "deactivated",
G_CALLBACK (window_deactivated_cb), manager, 0);
- g_signal_connect_object (window, "dialog-up",
- G_CALLBACK (window_dialog_up_cb), manager, 0);
- g_signal_connect_object (window, "dialog-down",
- G_CALLBACK (window_dialog_down_cb), manager, 0);
g_signal_connect_object (window, "show",
G_CALLBACK (window_show_cb), manager, G_CONNECT_AFTER);
g_signal_connect_object (window, "map",
@@ -1436,6 +1447,8 @@ connect_window_signals (GSManager *manager,
G_CALLBACK (window_map_event_cb), manager, G_CONNECT_AFTER);
g_signal_connect_object (window, "notify::obscured",
G_CALLBACK (window_obscured_cb), manager, G_CONNECT_AFTER);
+ g_signal_connect_object (window, "notify::dialog-up",
+ G_CALLBACK (window_dialog_up_changed_cb), manager, 0);
g_signal_connect_object (window, "unmap",
G_CALLBACK (window_unmap_cb), manager, G_CONNECT_AFTER);
g_signal_connect_object (window, "grab_broken_event",
diff --git a/src/gs-window-x11.c b/src/gs-window-x11.c
index 53f59be..4216ea4 100644
--- a/src/gs-window-x11.c
+++ b/src/gs-window-x11.c
@@ -64,6 +64,7 @@ struct GSWindowPrivate
GdkRectangle geometry;
guint obscured : 1;
+ guint dialog_up : 1;
guint lock_enabled : 1;
guint user_switch_enabled : 1;
@@ -118,14 +119,13 @@ struct GSWindowPrivate
enum {
ACTIVITY,
DEACTIVATED,
- DIALOG_UP,
- DIALOG_DOWN,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_OBSCURED,
+ PROP_DIALOG_UP,
PROP_LOCK_ENABLED,
PROP_LOGOUT_ENABLED,
PROP_KEYBOARD_ENABLED,
@@ -1532,6 +1532,43 @@ shake_dialog (GSWindow *window)
maybe_kill_dialog (window);
}
+static void
+window_set_dialog_up (GSWindow *window,
+ gboolean dialog_up)
+{
+ if (window->priv->dialog_up == dialog_up) {
+ return;
+ }
+
+ window->priv->dialog_up = dialog_up;
+ g_object_notify (G_OBJECT (window), "dialog-up");
+}
+
+static void
+popdown_dialog (GSWindow *window)
+{
+ gs_window_dialog_finish (window);
+
+ gtk_widget_show (window->priv->drawing_area);
+
+ gs_window_clear (window);
+ set_invisible_cursor (GTK_WIDGET (window)->window, TRUE);
+
+ window_set_dialog_up (window, FALSE);
+
+ /* reset the pointer positions */
+ window->priv->last_x = -1;
+ window->priv->last_y = -1;
+
+ if (window->priv->lock_box != NULL) {
+ gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box));
+ window->priv->lock_box = NULL;
+ }
+
+ remove_popup_dialog_idle (window);
+ remove_command_watches (window);
+}
+
static gboolean
lock_command_watch (GIOChannel *source,
GIOCondition condition,
@@ -1597,22 +1634,12 @@ lock_command_watch (GIOChannel *source,
}
if (finished) {
- gs_window_dialog_finish (window);
+ popdown_dialog (window);
if (window->priv->dialog_response == DIALOG_RESPONSE_OK) {
add_emit_deactivated_idle (window);
}
- gtk_widget_show (window->priv->drawing_area);
-
- gs_window_clear (window);
- set_invisible_cursor (GTK_WIDGET (window)->window, TRUE);
- g_signal_emit (window, signals [DIALOG_DOWN], 0);
-
- /* reset the pointer positions */
- window->priv->last_x = -1;
- window->priv->last_y = -1;
-
window->priv->lock_watch_id = 0;
return FALSE;
@@ -1649,8 +1676,8 @@ is_user_switch_enabled (GSWindow *window)
return window->priv->user_switch_enabled;
}
-static gboolean
-popup_dialog_idle (GSWindow *window)
+static void
+popup_dialog (GSWindow *window)
{
gboolean result;
char *tmp;
@@ -1703,6 +1730,12 @@ popup_dialog_idle (GSWindow *window)
}
g_string_free (command, TRUE);
+}
+
+static gboolean
+popup_dialog_idle (GSWindow *window)
+{
+ popup_dialog (window);
window->priv->popup_dialog_idle_id = 0;
@@ -1735,7 +1768,7 @@ gs_window_request_unlock (GSWindow *window)
add_popup_dialog_idle (window);
}
- g_signal_emit (window, signals [DIALOG_UP], 0);
+ window_set_dialog_up (window, TRUE);
}
void
@@ -1747,24 +1780,7 @@ gs_window_cancel_unlock_request (GSWindow *window)
*/
g_return_if_fail (GS_IS_WINDOW (window));
- if (window->priv->lock_socket == NULL) {
- return;
- }
-
- if (window->priv->lock_pid > 0) {
- gs_window_dialog_finish (window);
- }
-
- remove_popup_dialog_idle (window);
- remove_command_watches (window);
- remove_watchdog_timer (window);
-
- if (window->priv->lock_box != NULL) {
- gtk_container_remove (GTK_CONTAINER (window->priv->vbox), GTK_WIDGET (window->priv->lock_box));
- window->priv->lock_box = NULL;
-
- g_signal_emit (window, signals [DIALOG_DOWN], 0);
- }
+ popdown_dialog (window);
}
void
@@ -1984,6 +2000,9 @@ gs_window_get_property (GObject *object,
case PROP_OBSCURED:
g_value_set_boolean (value, self->priv->obscured);
break;
+ case PROP_DIALOG_UP:
+ g_value_set_boolean (value, self->priv->dialog_up);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -2182,6 +2201,14 @@ gs_window_is_obscured (GSWindow *window)
return window->priv->obscured;
}
+gboolean
+gs_window_is_dialog_up (GSWindow *window)
+{
+ g_return_val_if_fail (GS_IS_WINDOW (window), FALSE);
+
+ return window->priv->dialog_up;
+}
+
static void
window_set_obscured (GSWindow *window,
gboolean obscured)
@@ -2258,26 +2285,6 @@ gs_window_class_init (GSWindowClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE,
0);
- signals [DIALOG_UP] =
- g_signal_new ("dialog-up",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GSWindowClass, dialog_up),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
- signals [DIALOG_DOWN] =
- g_signal_new ("dialog-down",
- G_TYPE_FROM_CLASS (object_class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GSWindowClass, dialog_down),
- NULL,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
g_object_class_install_property (object_class,
PROP_OBSCURED,
@@ -2287,6 +2294,13 @@ gs_window_class_init (GSWindowClass *klass)
FALSE,
G_PARAM_READABLE));
g_object_class_install_property (object_class,
+ PROP_DIALOG_UP,
+ g_param_spec_boolean ("dialog-up",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READABLE));
+ g_object_class_install_property (object_class,
PROP_LOCK_ENABLED,
g_param_spec_boolean ("lock-enabled",
NULL,
diff --git a/src/gs-window.h b/src/gs-window.h
index fc2287e..db76d72 100644
--- a/src/gs-window.h
+++ b/src/gs-window.h
@@ -57,6 +57,7 @@ typedef struct
GType gs_window_get_type (void);
gboolean gs_window_is_obscured (GSWindow *window);
+gboolean gs_window_is_dialog_up (GSWindow *window);
void gs_window_set_screen (GSWindow *window,
GdkScreen *screen);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]