[gnome-screensaver/gnome-2-28] Work around x errors by asking dialog to die on cancel
- From: William Jon McCann <mccann src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-screensaver/gnome-2-28] Work around x errors by asking dialog to die on cancel
- Date: Fri, 29 Jan 2010 02:31:43 +0000 (UTC)
commit 98f8a22412cf388217fd5b88915eadd274d68520
Author: Chris Coulson <chriscoulson googlemail com>
Date: Thu Jan 28 21:29:17 2010 -0500
Work around x errors by asking dialog to die on cancel
Basically, what is happening is that gnome-screensaver-dialog exits after the
5th failed attempt at unlocking the screen, but before the shake animation
finishes. If the timing is slightly unlucky, this results in gnome-screensaver
accessing X resources that have already been destroyed (I ran it through
xtrace, and that showed this happening)
My patch fixes this by making gnome-screensaver-dialog request to
gnome-screensaver that it be terminated after the 5th failed attempt (rather
than exitting straight away, although there is a fallback timeout too).
gnome-screensaver then terminates the dialog after it is finished with the
shake animation, to avoid the race condition that is currently making it crash.
src/gnome-screensaver-dialog.c | 22 +++++++++++++++++++++-
src/gs-window-x11.c | 24 ++++++++++++++++++++++++
2 files changed, 45 insertions(+), 1 deletions(-)
---
diff --git a/src/gnome-screensaver-dialog.c b/src/gnome-screensaver-dialog.c
index 88d14a0..9d72fcb 100644
--- a/src/gnome-screensaver-dialog.c
+++ b/src/gnome-screensaver-dialog.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
+#include <signal.h>
#include <glib/gi18n.h>
#include <gdk/gdkx.h>
@@ -326,6 +327,21 @@ response_cb (GSLockPlug *plug,
}
static gboolean
+response_request_quit (void)
+{
+ printf ("REQUEST QUIT\n");
+ fflush (stdout);
+ return FALSE;
+}
+
+static gboolean
+quit_timeout_cb (gpointer data)
+{
+ gtk_main_quit ();
+ return FALSE;
+}
+
+static gboolean
auth_check_idle (GSLockPlug *plug)
{
gboolean res;
@@ -347,7 +363,11 @@ auth_check_idle (GSLockPlug *plug)
} else {
gs_debug ("Authentication failed, quitting (max failures)");
again = FALSE;
- gtk_main_quit ();
+ /* Don't quit immediately, but rather request that gnome-screensaver
+ * terminates us after it has finished the dialog shake. Time out
+ * after 5 seconds and quit anyway if this doesn't happen though */
+ g_idle_add ((GSourceFunc)response_request_quit, NULL);
+ g_timeout_add (5000, (GSourceFunc)quit_timeout_cb, NULL);
}
}
diff --git a/src/gs-window-x11.c b/src/gs-window-x11.c
index 2a74e10..ea6c1cd 100644
--- a/src/gs-window-x11.c
+++ b/src/gs-window-x11.c
@@ -91,6 +91,8 @@ struct GSWindowPrivate
gint lock_pid;
gint lock_watch_id;
gint dialog_response;
+ gboolean dialog_quit_requested;
+ gboolean dialog_shake_in_progress;
gint keyboard_pid;
gint keyboard_watch_id;
@@ -1383,6 +1385,16 @@ gs_window_dialog_finish (GSWindow *window)
remove_key_events (window);
}
+static void
+maybe_kill_dialog (GSWindow *window)
+{
+ if (!window->priv->dialog_shake_in_progress
+ && window->priv->dialog_quit_requested
+ && window->priv->lock_pid > 0) {
+ kill (window->priv->lock_pid, SIGTERM);
+ }
+}
+
/* very rudimentary animation for indicating an auth failure */
static void
shake_dialog (GSWindow *window)
@@ -1391,6 +1403,8 @@ shake_dialog (GSWindow *window)
guint left;
guint right;
+ window->priv->dialog_shake_in_progress = TRUE;
+
for (i = 0; i < 9; i++) {
if (i % 2 == 0) {
left = 30;
@@ -1415,6 +1429,9 @@ shake_dialog (GSWindow *window)
g_usleep (10000);
}
+
+ window->priv->dialog_shake_in_progress = FALSE;
+ maybe_kill_dialog (window);
}
static gboolean
@@ -1457,6 +1474,10 @@ lock_command_watch (GIOChannel *source,
window->priv->dialog_response = DIALOG_RESPONSE_CANCEL;
}
finished = TRUE;
+ } else if (strstr (line, "REQUEST QUIT") != NULL) {
+ gs_debug ("Got request for quit");
+ window->priv->dialog_quit_requested = TRUE;
+ maybe_kill_dialog (window);
}
break;
case G_IO_STATUS_EOF:
@@ -1570,6 +1591,9 @@ popup_dialog_idle (GSWindow *window)
set_invisible_cursor (GTK_WIDGET (window)->window, FALSE);
+ window->priv->dialog_quit_requested = FALSE;
+ window->priv->dialog_shake_in_progress = FALSE;
+
result = spawn_on_window (window,
command->str,
&window->priv->lock_pid,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]