Index: src/gs-grab-x11.c =================================================================== RCS file: /cvs/gnome/gnome-screensaver/src/gs-grab-x11.c,v retrieving revision 1.11 diff -p -u -r1.11 gs-grab-x11.c --- src/gs-grab-x11.c 19 Feb 2006 04:07:04 -0000 1.11 +++ src/gs-grab-x11.c 2 Jun 2006 20:07:30 -0000 @@ -1,6 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * - * Copyright (C) 2004-2005 William Jon McCann + * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef HAVE_XF86MISCSETGRABKEYSSTATE # include @@ -36,11 +37,26 @@ #include "gs-grab.h" #include "gs-debug.h" -gboolean mouse_hide_cursor = FALSE; -GdkWindow *mouse_grab_window = NULL; -GdkWindow *keyboard_grab_window = NULL; -GdkScreen *mouse_grab_screen = NULL; -GdkScreen *keyboard_grab_screen = NULL; +static void gs_grab_class_init (GSGrabClass *klass); +static void gs_grab_init (GSGrab *grab); +static void gs_grab_finalize (GObject *object); + +#define GS_GRAB_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GS_TYPE_GRAB, GSGrabPrivate)) + +G_DEFINE_TYPE (GSGrab, gs_grab, G_TYPE_OBJECT) + +static gpointer grab_object = NULL; + +struct GSGrabPrivate +{ + gboolean mouse_hide_cursor; + GdkWindow *mouse_grab_window; + GdkWindow *keyboard_grab_window; + GdkScreen *mouse_grab_screen; + GdkScreen *keyboard_grab_screen; + + GtkWidget *invisible; +}; static GdkCursor * get_cursor (void) @@ -99,7 +115,8 @@ grab_string (int status) Ctrl-Alt-F1) but I wish it did. Maybe it will someday. */ static void -xorg_lock_smasher_set_active (gboolean active) +xorg_lock_smasher_set_active (GSGrab *grab, + gboolean active) { int status; @@ -129,33 +146,15 @@ xorg_lock_smasher_set_active (gboolean a } #else static void -xorg_lock_smasher_set_active (gboolean active) +xorg_lock_smasher_set_active (GSGrab *grab, + gboolean active) { } #endif /* HAVE_XF86MISCSETGRABKEYSSTATE */ -void -gs_grab_window (GdkWindow *window, - GdkScreen *screen, - gboolean hide_cursor) -{ - gboolean result = FALSE; - - xorg_lock_smasher_set_active (FALSE); - - do { - result = gs_grab_move_keyboard (window, screen); - gdk_flush (); - } while (!result); - - do { - result = gs_grab_move_mouse (window, screen, hide_cursor); - gdk_flush (); - } while (!result); -} - static int -gs_grab_get_keyboard (GdkWindow *window, +gs_grab_get_keyboard (GSGrab *grab, + GdkWindow *window, GdkScreen *screen) { GdkGrabStatus status; @@ -167,8 +166,8 @@ gs_grab_get_keyboard (GdkWindow *window, status = gdk_keyboard_grab (window, FALSE, GDK_CURRENT_TIME); if (status == GDK_GRAB_SUCCESS) { - keyboard_grab_window = window; - keyboard_grab_screen = screen; + grab->priv->keyboard_grab_window = window; + grab->priv->keyboard_grab_screen = screen; } if (status != GDK_GRAB_SUCCESS) { @@ -179,7 +178,8 @@ gs_grab_get_keyboard (GdkWindow *window, } static int -gs_grab_get_mouse (GdkWindow *window, +gs_grab_get_mouse (GSGrab *grab, + GdkWindow *window, GdkScreen *screen, gboolean hide_cursor) { @@ -195,9 +195,9 @@ gs_grab_get_mouse (GdkWindow *window, GDK_CURRENT_TIME); if (status == GDK_GRAB_SUCCESS) { - mouse_grab_window = window; - mouse_grab_screen = screen; - mouse_hide_cursor = hide_cursor; + grab->priv->mouse_grab_window = window; + grab->priv->mouse_grab_screen = screen; + grab->priv->mouse_hide_cursor = hide_cursor; } gdk_cursor_unref (cursor); @@ -206,43 +206,44 @@ gs_grab_get_mouse (GdkWindow *window, } void -gs_grab_keyboard_reset (void) +gs_grab_keyboard_reset (GSGrab *grab) { - keyboard_grab_window = NULL; - keyboard_grab_screen = NULL; + grab->priv->keyboard_grab_window = NULL; + grab->priv->keyboard_grab_screen = NULL; } static gboolean -gs_grab_release_keyboard (void) +gs_grab_release_keyboard (GSGrab *grab) { gs_debug ("Ungrabbing keyboard"); gdk_keyboard_ungrab (GDK_CURRENT_TIME); - gs_grab_keyboard_reset (); + gs_grab_keyboard_reset (grab); return TRUE; } void -gs_grab_mouse_reset (void) +gs_grab_mouse_reset (GSGrab *grab) { - mouse_grab_window = NULL; - mouse_grab_screen = NULL; + grab->priv->mouse_grab_window = NULL; + grab->priv->mouse_grab_screen = NULL; } gboolean -gs_grab_release_mouse (void) +gs_grab_release_mouse (GSGrab *grab) { gs_debug ("Ungrabbing pointer"); gdk_pointer_ungrab (GDK_CURRENT_TIME); - gs_grab_mouse_reset (); + gs_grab_mouse_reset (grab); return TRUE; } -gboolean -gs_grab_move_mouse (GdkWindow *window, +static gboolean +gs_grab_move_mouse (GSGrab *grab, + GdkWindow *window, GdkScreen *screen, gboolean hide_cursor) { @@ -254,12 +255,12 @@ gs_grab_move_mouse (GdkWindow *window, /* if the pointer is not grabbed and we have a mouse_grab_window defined then we lost the grab */ if (! gdk_pointer_is_grabbed ()) { - gs_grab_mouse_reset (); + gs_grab_mouse_reset (grab); } - if (mouse_grab_window == window) { + if (grab->priv->mouse_grab_window == window) { gs_debug ("Window %X is already grabbed, skipping", - (guint32) GDK_WINDOW_XID (mouse_grab_window)); + (guint32) GDK_WINDOW_XID (grab->priv->mouse_grab_window)); return TRUE; } @@ -268,9 +269,9 @@ gs_grab_move_mouse (GdkWindow *window, /* FIXME: GTK doesn't like having the pointer grabbed */ return TRUE; #else - if (mouse_grab_window) { + if (grab->priv->mouse_grab_window) { gs_debug ("Moving pointer grab from %X to %X", - (guint32) GDK_WINDOW_XID (mouse_grab_window), + (guint32) GDK_WINDOW_XID (grab->priv->mouse_grab_window), (guint32) GDK_WINDOW_XID (window)); } else { gs_debug ("Getting pointer grab on %X", @@ -281,24 +282,24 @@ gs_grab_move_mouse (GdkWindow *window, gs_debug ("*** doing X server grab"); gdk_x11_grab_server (); - old_window = mouse_grab_window; - old_screen = mouse_grab_screen; - old_hide_cursor = mouse_hide_cursor; + old_window = grab->priv->mouse_grab_window; + old_screen = grab->priv->mouse_grab_screen; + old_hide_cursor = grab->priv->mouse_hide_cursor; if (old_window) { - gs_grab_release_mouse (); + gs_grab_release_mouse (grab); } - result = gs_grab_get_mouse (window, screen, hide_cursor); + result = gs_grab_get_mouse (grab, window, screen, hide_cursor); if (result != GDK_GRAB_SUCCESS) { sleep (1); - result = gs_grab_get_mouse (window, screen, hide_cursor); + result = gs_grab_get_mouse (grab, window, screen, hide_cursor); } if ((result != GDK_GRAB_SUCCESS) && old_window) { g_warning ("Could not grab mouse for new window. Resuming previous grab."); - gs_grab_get_mouse (old_window, old_screen, old_hide_cursor); + gs_grab_get_mouse (grab, old_window, old_screen, old_hide_cursor); } gs_debug ("*** releasing X server grab"); @@ -308,23 +309,24 @@ gs_grab_move_mouse (GdkWindow *window, return (result == GDK_GRAB_SUCCESS); } -gboolean -gs_grab_move_keyboard (GdkWindow *window, +static gboolean +gs_grab_move_keyboard (GSGrab *grab, + GdkWindow *window, GdkScreen *screen) { gboolean result; GdkWindow *old_window; GdkScreen *old_screen; - if (keyboard_grab_window == window) { + if (grab->priv->keyboard_grab_window == window) { gs_debug ("Window %X is already grabbed, skipping", - (guint32) GDK_WINDOW_XID (keyboard_grab_window)); + (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window)); return TRUE; } - if (keyboard_grab_window) { + if (grab->priv->keyboard_grab_window != NULL) { gs_debug ("Moving keyboard grab from %X to %X", - (guint32) GDK_WINDOW_XID (keyboard_grab_window), + (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window), (guint32) GDK_WINDOW_XID (window)); } else { gs_debug ("Getting keyboard grab on %X", @@ -335,23 +337,23 @@ gs_grab_move_keyboard (GdkWindow *window gs_debug ("*** doing X server grab"); gdk_x11_grab_server (); - old_window = keyboard_grab_window; - old_screen = keyboard_grab_screen; + old_window = grab->priv->keyboard_grab_window; + old_screen = grab->priv->keyboard_grab_screen; if (old_window) { - gs_grab_release_keyboard (); + gs_grab_release_keyboard (grab); } - result = gs_grab_get_keyboard (window, screen); + result = gs_grab_get_keyboard (grab, window, screen); if (result != GDK_GRAB_SUCCESS) { sleep (1); - result = gs_grab_get_keyboard (window, screen); + result = gs_grab_get_keyboard (grab, window, screen); } if ((result != GDK_GRAB_SUCCESS) && old_window) { g_warning ("Could not grab keyboard for new window. Resuming previous grab."); - gs_grab_get_keyboard (old_window, old_screen); + gs_grab_get_keyboard (grab, old_window, old_screen); } gs_debug ("*** releasing X server grab"); @@ -379,20 +381,22 @@ gs_grab_nuke_focus (void) } void -gs_grab_release_keyboard_and_mouse (void) +gs_grab_release (GSGrab *grab) { gs_debug ("Releasing all grabs"); - gs_grab_release_mouse (); - gs_grab_release_keyboard (); + gs_grab_release_mouse (grab); + gs_grab_release_keyboard (grab); /* FIXME: is it right to enable this ? */ - xorg_lock_smasher_set_active (TRUE); + xorg_lock_smasher_set_active (grab, TRUE); } gboolean -gs_grab_get_keyboard_and_mouse (GdkWindow *window, - GdkScreen *screen) +gs_grab_grab_window (GSGrab *grab, + GdkWindow *window, + GdkScreen *screen, + gboolean hide_cursor) { gboolean mstatus = FALSE; gboolean kstatus = FALSE; @@ -403,7 +407,7 @@ gs_grab_get_keyboard_and_mouse (GdkWindo AGAIN: for (i = 0; i < retries; i++) { - kstatus = gs_grab_get_keyboard (window, screen); + kstatus = gs_grab_get_keyboard (grab, window, screen); if (kstatus == GDK_GRAB_SUCCESS) { break; } @@ -421,7 +425,7 @@ gs_grab_get_keyboard_and_mouse (GdkWindo } for (i = 0; i < retries; i++) { - mstatus = gs_grab_get_mouse (window, screen, FALSE); + mstatus = gs_grab_get_mouse (grab, window, screen, hide_cursor); if (mstatus == GDK_GRAB_SUCCESS) { break; } @@ -437,7 +441,7 @@ gs_grab_get_keyboard_and_mouse (GdkWindo #if 0 /* FIXME: release the pointer grab so GTK will work */ - gs_grab_release_mouse (); + gs_grab_release_mouse (grab); #endif /* When should we allow blanking to proceed? The current theory @@ -459,3 +463,114 @@ gs_grab_get_keyboard_and_mouse (GdkWindo return TRUE; /* Grab is good, go ahead and blank. */ } +/* this is used to grab the keyboard and mouse to the root */ +gboolean +gs_grab_grab_root (GSGrab *grab, + gboolean hide_cursor) +{ + GdkDisplay *display; + GdkWindow *root; + GdkScreen *screen; + gboolean res; + + gs_debug ("Grabbing the root window"); + + display = gdk_display_get_default (); + gdk_display_get_pointer (display, &screen, NULL, NULL, NULL); + root = gdk_screen_get_root_window (screen); + + res = gs_grab_grab_window (grab, root, screen, hide_cursor); + + return res; +} + +/* this is used to grab the keyboard and mouse to an offscreen window */ +gboolean +gs_grab_grab_offscreen (GSGrab *grab, + gboolean hide_cursor) +{ + GdkScreen *screen; + gboolean res; + + gs_debug ("Grabbing an offscreen window"); + + screen = gtk_invisible_get_screen (GTK_INVISIBLE (grab->priv->invisible)); + res = gs_grab_grab_window (grab, grab->priv->invisible->window, screen, hide_cursor); + + return res; +} + +/* This is similar to gs_grab_grab_window but doesn't fail */ +void +gs_grab_move_to_window (GSGrab *grab, + GdkWindow *window, + GdkScreen *screen, + gboolean hide_cursor) +{ + gboolean result = FALSE; + + g_return_if_fail (GS_IS_GRAB (grab)); + + xorg_lock_smasher_set_active (grab, FALSE); + + do { + result = gs_grab_move_keyboard (grab, window, screen); + gdk_flush (); + } while (!result); + + do { + result = gs_grab_move_mouse (grab, window, screen, hide_cursor); + gdk_flush (); + } while (!result); +} + +static void +gs_grab_class_init (GSGrabClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gs_grab_finalize; + + g_type_class_add_private (klass, sizeof (GSGrabPrivate)); +} + +static void +gs_grab_init (GSGrab *grab) +{ + grab->priv = GS_GRAB_GET_PRIVATE (grab); + + grab->priv->mouse_hide_cursor = FALSE; + grab->priv->invisible = gtk_invisible_new (); + gtk_widget_show (grab->priv->invisible); +} + +static void +gs_grab_finalize (GObject *object) +{ + GSGrab *grab; + + g_return_if_fail (object != NULL); + g_return_if_fail (GS_IS_GRAB (object)); + + grab = GS_GRAB (object); + + g_return_if_fail (grab->priv != NULL); + + gtk_widget_destroy (grab->priv->invisible); + + G_OBJECT_CLASS (gs_grab_parent_class)->finalize (object); +} + +GSGrab * +gs_grab_new (void) +{ + if (grab_object) { + g_object_ref (grab_object); + } else { + grab_object = g_object_new (GS_TYPE_GRAB, NULL); + g_object_add_weak_pointer (grab_object, + (gpointer *) &grab_object); + } + + return GS_GRAB (grab_object); +} Index: src/gs-grab.h =================================================================== RCS file: /cvs/gnome/gnome-screensaver/src/gs-grab.h,v retrieving revision 1.3 diff -p -u -r1.3 gs-grab.h --- src/gs-grab.h 13 Feb 2006 20:21:53 -0000 1.3 +++ src/gs-grab.h 2 Jun 2006 20:07:30 -0000 @@ -1,6 +1,6 @@ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- * - * Copyright (C) 2004-2005 William Jon McCann + * Copyright (C) 2004-2006 William Jon McCann * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,22 +23,56 @@ #ifndef __GS_GRAB_H #define __GS_GRAB_H +#include +#include + G_BEGIN_DECLS -void gs_grab_release_keyboard_and_mouse (void); -void gs_grab_mouse_reset (void); -void gs_grab_keyboard_reset (void); -gboolean gs_grab_release_mouse (void); -gboolean gs_grab_get_keyboard_and_mouse (GdkWindow *window, - GdkScreen *screen); -void gs_grab_window (GdkWindow *window, - GdkScreen *screen, - gboolean hide_cursor); -gboolean gs_grab_move_mouse (GdkWindow *window, - GdkScreen *screen, - gboolean hide_cursor); -gboolean gs_grab_move_keyboard (GdkWindow *window, - GdkScreen *screen); +#define GS_TYPE_GRAB (gs_grab_get_type ()) +#define GS_GRAB(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GS_TYPE_GRAB, GSGrab)) +#define GS_GRAB_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GS_TYPE_GRAB, GSGrabClass)) +#define GS_IS_GRAB(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GS_TYPE_GRAB)) +#define GS_IS_GRAB_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GS_TYPE_GRAB)) +#define GS_GRAB_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GS_TYPE_GRAB, GSGrabClass)) + +typedef struct GSGrabPrivate GSGrabPrivate; + +typedef struct +{ + GObject parent; + GSGrabPrivate *priv; +} GSGrab; + +typedef struct +{ + GObjectClass parent_class; + +} GSGrabClass; + +GType gs_grab_get_type (void); + +GSGrab * gs_grab_new (void); + +void gs_grab_release (GSGrab *grab); +gboolean gs_grab_release_mouse (GSGrab *grab); + +gboolean gs_grab_grab_window (GSGrab *grab, + GdkWindow *window, + GdkScreen *screen, + gboolean hide_cursor); + +gboolean gs_grab_grab_root (GSGrab *grab, + gboolean hide_cursor); +gboolean gs_grab_grab_offscreen (GSGrab *grab, + gboolean hide_cursor); + +void gs_grab_move_to_window (GSGrab *grab, + GdkWindow *window, + GdkScreen *screen, + gboolean hide_cursor); + +void gs_grab_mouse_reset (GSGrab *grab); +void gs_grab_keyboard_reset (GSGrab *grab); G_END_DECLS Index: src/gs-manager.c =================================================================== RCS file: /cvs/gnome/gnome-screensaver/src/gs-manager.c,v retrieving revision 1.41.2.6 diff -p -u -r1.41.2.6 gs-manager.c --- src/gs-manager.c 2 Jun 2006 00:17:10 -0000 1.41.2.6 +++ src/gs-manager.c 2 Jun 2006 20:07:30 -0000 @@ -71,6 +71,7 @@ struct GSManagerPrivate GSList *themes; GSSaverMode saver_mode; + GSGrab *grab; GSFade *fade; guint unfade_idle_id; }; @@ -716,6 +717,7 @@ gs_manager_init (GSManager *manager) manager->priv = GS_MANAGER_GET_PRIVATE (manager); manager->priv->fade = gs_fade_new (); + manager->priv->grab = gs_grab_new (); } static void @@ -742,7 +744,7 @@ gs_manager_finalize (GObject *object) remove_timers (manager); - gs_grab_release_keyboard_and_mouse (); + gs_grab_release (manager->priv->grab); manager_stop_jobs (manager); @@ -757,6 +759,7 @@ gs_manager_finalize (GObject *object) manager->priv->lock_enabled = FALSE; g_object_unref (manager->priv->fade); + g_object_unref (manager->priv->grab); G_OBJECT_CLASS (parent_class)->finalize (object); } @@ -798,13 +801,14 @@ window_dialog_up_cb (GSWindow *window, manager->priv->dialog_up = TRUE; /* Move keyboard and mouse grabs so dialog can be used */ - gs_grab_window (gs_window_get_gdk_window (window), - gs_window_get_screen (window), - FALSE); + 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 (); + gs_grab_release_mouse (manager->priv->grab); /* Make all other windows insensitive so we don't get events */ for (l = manager->priv->windows; l; l = l->next) { @@ -830,9 +834,10 @@ window_dialog_down_cb (GSWindow *window g_return_if_fail (GS_IS_MANAGER (manager)); /* Regrab the mouse */ - gs_grab_window (gs_window_get_gdk_window (window), - gs_window_get_screen (window), - FALSE); + 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) { @@ -891,9 +896,10 @@ manager_maybe_grab_window (GSManager *ma grabbed = FALSE; if (gs_window_get_screen (window) == screen && gs_window_get_monitor (window) == monitor) { - gs_grab_window (gs_window_get_gdk_window (window), - gs_window_get_screen (window), - FALSE); + gs_grab_move_to_window (manager->priv->grab, + gs_window_get_gdk_window (window), + gs_window_get_screen (window), + FALSE); grabbed = TRUE; } @@ -907,9 +913,9 @@ window_grab_broken_cb (GSWindow { gs_debug ("GRAB BROKEN!"); if (event->keyboard) { - gs_grab_keyboard_reset (); + gs_grab_keyboard_reset (manager->priv->grab); } else { - gs_grab_mouse_reset (); + gs_grab_mouse_reset (manager->priv->grab); } } @@ -1159,10 +1165,8 @@ fade_done_cb (GSFade *fade, static gboolean gs_manager_activate (GSManager *manager) { - GdkDisplay *display; - GdkScreen *screen; - GdkWindow *root; gboolean do_fade; + gboolean res; g_return_val_if_fail (manager != NULL, FALSE); g_return_val_if_fail (GS_IS_MANAGER (manager), FALSE); @@ -1172,11 +1176,8 @@ gs_manager_activate (GSManager *manager) return FALSE; } - display = gdk_display_get_default (); - gdk_display_get_pointer (display, &screen, NULL, NULL, NULL); - root = gdk_screen_get_root_window (screen); - - if (! gs_grab_get_keyboard_and_mouse (root, screen)) { + res = gs_grab_grab_root (manager->priv->grab, FALSE); + if (! res) { return FALSE; } @@ -1226,7 +1227,7 @@ gs_manager_deactivate (GSManager *manage remove_timers (manager); - gs_grab_release_keyboard_and_mouse (); + gs_grab_release (manager->priv->grab); manager_stop_jobs (manager); Index: src/gs-monitor.c =================================================================== RCS file: /cvs/gnome/gnome-screensaver/src/gs-monitor.c,v retrieving revision 1.45.2.2 diff -p -u -r1.45.2.2 gs-monitor.c --- src/gs-monitor.c 1 Jun 2006 14:54:03 -0000 1.45.2.2 +++ src/gs-monitor.c 2 Jun 2006 20:07:30 -0000 @@ -37,6 +37,7 @@ #include "gs-manager.h" #include "gs-watcher.h" #include "gs-fade.h" +#include "gs-grab.h" #ifdef USE_LEGACY_DPMS_SUPPORT #include "gs-power.h" @@ -63,6 +64,9 @@ struct GSMonitorPrivate #endif GSPrefs *prefs; GSFade *fade; + GSGrab *grab; + + guint release_grab_id; }; enum { @@ -115,6 +119,20 @@ watcher_idle_cb (GSWatcher *watcher, } static gboolean +release_grab_timeout (GSMonitor *monitor) +{ + gboolean manager_active; + + manager_active = gs_manager_get_active (monitor->priv->manager); + if (! manager_active) { + gs_grab_release (monitor->priv->grab); + } + + monitor->priv->release_grab_id = 0; + return FALSE; +} + +static gboolean watcher_idle_notice_cb (GSWatcher *watcher, gboolean in_effect, GSMonitor *monitor) @@ -133,7 +151,12 @@ watcher_idle_notice_cb (GSWatcher *watch if (in_effect) { if (activation_enabled && ! inhibited) { /* start slow fade */ - gs_fade_async (monitor->priv->fade, FADE_TIMEOUT, NULL, NULL); + if (gs_grab_grab_offscreen (monitor->priv->grab, FALSE)) { + gs_fade_async (monitor->priv->fade, FADE_TIMEOUT, NULL, NULL); + } else { + gs_debug ("Could not grab the keyboard so not performing idle warning fade-out"); + } + handled = TRUE; } } else { @@ -144,6 +167,12 @@ watcher_idle_notice_cb (GSWatcher *watch if (! manager_active) { gs_debug ("manager not active, performing fade cancellation"); gs_fade_reset (monitor->priv->fade); + + /* don't release the grab immediately to prevent typing passwords into windows */ + if (monitor->priv->release_grab_id != 0) { + g_source_remove (monitor->priv->release_grab_id); + } + monitor->priv->release_grab_id = g_timeout_add (1000, (GSourceFunc)release_grab_timeout, monitor); } else { gs_debug ("manager active, skipping fade cancellation"); } @@ -432,6 +461,8 @@ gs_monitor_init (GSMonitor *monitor) connect_listener_signals (monitor); monitor->priv->fade = gs_fade_new (); + monitor->priv->grab = gs_grab_new (); + monitor->priv->watcher = gs_watcher_new (monitor->priv->prefs->timeout); connect_watcher_signals (monitor); @@ -467,6 +498,7 @@ gs_monitor_finalize (GObject *object) disconnect_prefs_signals (monitor); g_object_unref (monitor->priv->fade); + g_object_unref (monitor->priv->grab); g_object_unref (monitor->priv->watcher); g_object_unref (monitor->priv->listener); g_object_unref (monitor->priv->manager); Index: src/test-window.c =================================================================== RCS file: /cvs/gnome/gnome-screensaver/src/test-window.c,v retrieving revision 1.4 diff -p -u -r1.4 test-window.c --- src/test-window.c 11 Jan 2006 16:46:13 -0000 1.4 +++ src/test-window.c 2 Jun 2006 20:07:30 -0000 @@ -32,6 +32,8 @@ #include "gs-grab.h" #include "gs-debug.h" +static GSGrab *grab = NULL; + static void window_deactivated_cb (GSWindow *window, gpointer data) @@ -56,9 +58,10 @@ window_show_cb (GSWindow *window, gpointer data) { /* Grab keyboard so dialog can be used */ - gs_grab_window (gs_window_get_gdk_window (window), - gs_window_get_screen (window), - FALSE); + gs_grab_move_to_window (grab, + gs_window_get_gdk_window (window), + gs_window_get_screen (window), + FALSE); } @@ -79,7 +82,7 @@ window_destroyed_cb (GtkWindow *window, gpointer data) { disconnect_window_signals (GS_WINDOW (window)); - gs_grab_release_keyboard_and_mouse (); + gs_grab_release (grab); gtk_main_quit (); } @@ -147,9 +150,13 @@ main (int argc, gs_debug_init (TRUE, FALSE); + grab = gs_grab_new (); + test_window (); gtk_main (); + + g_object_unref (grab); gs_debug_shutdown ();