File gnome-screensaver-xvkbd-on-lock.patch of Package gnome-screensaver
Index: gnome-screensaver-2.91.2/src/gnome-screensaver-dialog.c
===================================================================
--- gnome-screensaver-2.91.2.orig/src/gnome-screensaver-dialog.c
+++ gnome-screensaver-2.91.2/src/gnome-screensaver-dialog.c
@@ -119,10 +119,19 @@ response_ok (void)
fflush (stdout);
}
+static GPid xvkbd_pid;
+static gboolean xvkbd_running = FALSE;
+
static gboolean
quit_response_ok (void)
{
response_ok ();
+
+ if (xvkbd_running) {
+ xvkbd_running = FALSE;
+ kill (xvkbd_pid, 9);
+ }
+
gtk_main_quit ();
return FALSE;
}
@@ -131,6 +140,12 @@ static gboolean
quit_response_cancel (void)
{
response_cancel ();
+
+ if (xvkbd_running) {
+ xvkbd_running = FALSE;
+ kill (xvkbd_pid, 9);
+ }
+
gtk_main_quit ();
return FALSE;
}
@@ -422,6 +437,14 @@ popup_dialog_idle (void)
return FALSE;
}
+static void
+handle_sigterm (int sig)
+{
+ if (xvkbd_running)
+ kill (xvkbd_pid, 9);
+
+ exit (0);
+}
/*
* Copyright (c) 1991-2004 Jamie Zawinski <jwz@jwz.org>
@@ -582,6 +605,8 @@ main (int argc,
exit (1);
}
+ signal (SIGTERM, handle_sigterm);
+
if (show_version) {
g_print ("%s %s\n", argv [0], VERSION);
exit (1);
@@ -598,10 +623,27 @@ main (int argc,
gs_debug_init (verbose, FALSE);
+ int status = system ("hal-find-by-property --key system.formfactor.subtype --string tabletpc");
+ if (WIFEXITED (status) && WEXITSTATUS (status) == 0) {
+ gchar **arguments[] = { "/usr/bin/xvkbd", "-always-on-top", "-compact", "-geometry", "-0-0", NULL };
+ error = NULL;
+
+ if (g_spawn_async (g_get_home_dir (), arguments, NULL, 0, NULL, NULL,
+ &xvkbd_pid, &error))
+ xvkbd_running = TRUE;
+ else {
+ g_warning ("Could not spawn xvkbd: %s\n", error->message);
+ g_error_free (error);
+
+ }
+ }
g_idle_add ((GSourceFunc)popup_dialog_idle, NULL);
gtk_main ();
+ if (xvkbd_running)
+ kill (xvkbd_pid, 9);
+
gs_profile_end (NULL);
gs_debug_shutdown ();
Index: gnome-screensaver-2.91.2/src/gs-window-x11.c
===================================================================
--- gnome-screensaver-2.91.2.orig/src/gs-window-x11.c
+++ gnome-screensaver-2.91.2/src/gs-window-x11.c
@@ -633,6 +633,49 @@ x11_window_is_ours (Window window)
return ret;
}
+#define GET_DISPLAY gdk_x11_display_get_xdisplay (gdk_display_get_default ())
+
+GdkWindow *xvkbd_window = NULL;
+
+static gboolean
+is_xvkbd_window (Window window)
+{
+ gboolean ret = FALSE;
+ XClassHint class_hint = { NULL, NULL };
+
+ gdk_error_trap_push ();
+ if (XGetClassHint (GET_DISPLAY, window, &class_hint)) {
+ if (g_strstr_len (class_hint.res_name,
+ strlen (class_hint.res_name),
+ "xvkbd"))
+ ret = TRUE;
+ }
+
+ if (G_UNLIKELY (gdk_error_trap_pop () == BadWindow)) ;
+
+ return ret;
+}
+
+static void
+setup_xvkbd_window (GSWindow *gswindow, Window window)
+{
+ gs_debug ("Setting up xvkbd_window from window %d", (int) window);
+
+ xvkbd_window = gdk_x11_window_foreign_new_for_display (gtk_widget_get_display (widget), window);
+ gdk_window_hide (xvkbd_window);
+ gdk_window_set_override_redirect (xvkbd_window, TRUE);
+ gdk_window_set_events (xvkbd_window, gdk_window_get_events (xvkbd_window) | GDK_STRUCTURE_MASK);
+
+ int display_width, display_height, width, height;
+ GdkWindow *root = gdk_screen_get_root_window (gdk_window_get_screen (xvkbd_window));
+
+ gdk_window_get_geometry (xvkbd_window, NULL, NULL, &width, &height);
+ gdk_window_get_geometry (root, NULL, NULL, &display_width, &display_height);
+ gdk_window_reparent (xvkbd_window, NULL, display_width - width, display_height - height);
+ gdk_window_set_transient_for (xvkbd_window, gtk_widget_get_window (GTK_WIDGET (gswindow)));
+ gdk_window_show (xvkbd_window);
+}
+
#ifdef HAVE_SHAPE_EXT
static void
unshape_window (GSWindow *window)
@@ -655,6 +698,16 @@ gs_window_xevent (GSWindow *window,
/* MapNotify is used to tell us when new windows are mapped.
ConfigureNofify is used to tell us when windows are raised. */
switch (ev->xany.type) {
+ case CreateNotify :
+ {
+ XCreateWindowEvent *create_event;
+
+ create_event = &ev->xcreatewindow;
+ if (!x11_window_is_ours (create_event->window) && is_xvkbd_window (create_event->window))
+ setup_xvkbd_window (window, create_event->window);
+
+ break;
+ }
case MapNotify:
{
XMapEvent *xme = &ev->xmap;
@@ -672,7 +725,7 @@ gs_window_xevent (GSWindow *window,
XConfigureEvent *xce = &ev->xconfigure;
if (! x11_window_is_ours (xce->window)) {
- gs_window_raise (window);
+ gs_window_raise (window);
} else {
gs_debug ("not raising our windows");
}