static gboolean gs_grab_move_keyboard (GSGrab *grab, GdkWindow *window, GdkScreen *screen) { gboolean result; GdkWindow *old_window; GdkScreen *old_screen; if (grab->priv->keyboard_grab_window == window) { gs_debug ("Window %X is already grabbed, skipping", (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window)); return TRUE; } if (grab->priv->keyboard_grab_window != NULL) { gs_debug ("Moving keyboard grab from %X to %X", (guint32) GDK_WINDOW_XID (grab->priv->keyboard_grab_window), (guint32) GDK_WINDOW_XID (window)); } else { gs_debug ("Getting keyboard grab on %X", (guint32) GDK_WINDOW_XID (window)); } gs_debug ("*** doing X server grab"); gdk_x11_grab_server (); old_window = grab->priv->keyboard_grab_window; old_screen = grab->priv->keyboard_grab_screen; if (old_window) { gs_grab_release_keyboard (grab); } result = gs_grab_get_keyboard (grab, window, screen); if (result != GDK_GRAB_SUCCESS) { sleep (1); result = gs_grab_get_keyboard (grab, window, screen); } if ((result != GDK_GRAB_SUCCESS) && old_window) { gs_debug ("Could not grab keyboard for new window. Resuming previous grab."); gs_grab_get_keyboard (grab, old_window, old_screen); } gs_debug ("*** releasing X server grab"); gdk_x11_ungrab_server (); gdk_flush (); return (result == GDK_GRAB_SUCCESS); }
gboolean gs_grab_grab_window (GSGrab *grab, GdkWindow *window, GdkScreen *screen, gboolean hide_cursor) { gboolean mstatus = FALSE; gboolean kstatus = FALSE; int i; int retries = 4; gboolean focus_fuckus = FALSE; /* First, have stuff we control in GNOME un-grab */ request_shell_exit_overview (grab); AGAIN: for (i = 0; i < retries; i++) { kstatus = gs_grab_get_keyboard (grab, window, screen); if (kstatus == GDK_GRAB_SUCCESS) { break; } /* else, wait a second and try to grab again. */ sleep (1); } if (kstatus != GDK_GRAB_SUCCESS) { if (!focus_fuckus) { focus_fuckus = TRUE; gs_grab_nuke_focus (); goto AGAIN; } } for (i = 0; i < retries; i++) { mstatus = gs_grab_get_mouse (grab, window, screen, hide_cursor); if (mstatus == GDK_GRAB_SUCCESS) { break; } /* else, wait a second and try to grab again. */ sleep (1); } if (mstatus != GDK_GRAB_SUCCESS) { gs_debug ("Couldn't grab pointer! (%s)", grab_string (mstatus)); } #if 0 /* FIXME: release the pointer grab so GTK will work */ gs_grab_release_mouse (grab); #endif /* When should we allow blanking to proceed? The current theory is that both a keyboard grab and a mouse grab are mandatory - If we don't have a keyboard grab, then we won't be able to read a password to unlock, so the kbd grab is manditory. - If we don't have a mouse grab, then we might not see mouse clicks as a signal to unblank, on-screen widgets won't work ideally, and gs_grab_move_to_window() will spin forever when it gets called. */ if (kstatus != GDK_GRAB_SUCCESS || mstatus != GDK_GRAB_SUCCESS) { /* Do not blank without a keyboard and mouse grabs. */ /* Release keyboard or mouse which was grabbed. */ if (kstatus == GDK_GRAB_SUCCESS) { gs_grab_release_keyboard (grab); } if (mstatus == GDK_GRAB_SUCCESS) { gs_grab_release_mouse (grab); } return FALSE; } /* Grab is good, go ahead and blank. */ return TRUE; }