works fine here on i386, tested gaim, gqview, gvim, and xnmap both
locally and remote through ssh -X
mozilla-firefox didn't work however, but there's probably more to it
than just fixing gtk+
ok david@
* steven mestdagh <[EMAIL PROTECTED]> [060610 08:38]:
> Brad [2006-06-10, 06:06:07]:
> > I noticed this from the Gtk+ 2.9.2 release notes..
> >
> > * Make GTK+ work as an untrused X client
>
> applies reasonably well to the in tree version. i did some very minimal
> testing on i386, it seems to work. obviously, more testing with this is
> appreciated...
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/x11/gtk+2/Makefile,v
> retrieving revision 1.38
> diff -u -r1.38 Makefile
> --- Makefile 2006/06/03 19:56:56 1.38
> +++ Makefile 2006/06/10 12:57:43
> @@ -7,7 +7,7 @@
>
> VERSION= 2.8.18
> DISTNAME= gtk+-${VERSION}
> -PKGNAME= gtk+2-${VERSION}p1
> +PKGNAME= gtk+2-${VERSION}p2
> PKGNAME-docs= gtk+2-docs-${VERSION}
> CATEGORIES= x11 devel
>
> Index: patches/patch-gdk_x11_gdkdisplay-x11_c
> ===================================================================
> RCS file: patch-gdk_x11_gdkdisplay-x11_c
> diff -N patch-gdk_x11_gdkdisplay-x11_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gdk_x11_gdkdisplay-x11_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,38 @@
> +$OpenBSD$
> +--- gdk/x11/gdkdisplay-x11.c.orig Thu Jun 30 05:35:30 2005
> ++++ gdk/x11/gdkdisplay-x11.c Sat Jun 10 14:32:57 2006
> +@@ -224,6 +224,24 @@ gdk_display_open (const gchar *display_n
> + #endif
> + display_x11->have_xfixes = FALSE;
> +
> ++ display_x11->trusted_client = TRUE;
> ++ {
> ++ Window root, child;
> ++ int rootx, rooty, winx, winy;
> ++ unsigned int xmask;
> ++
> ++ gdk_error_trap_push ();
> ++ XQueryPointer (display_x11->xdisplay,
> ++ GDK_SCREEN_X11 (display_x11->default_screen)->xroot_window,
> ++ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
> ++ gdk_flush ();
> ++ if (G_UNLIKELY (gdk_error_trap_pop () == BadWindow))
> ++ {
> ++ g_warning ("Connection to display %s appears to be untrusted. Pointer
> and keyboard grabs and inter-client communication may not work as expected.",
> gdk_display_get_name (display));
> ++ display_x11->trusted_client = FALSE;
> ++ }
> ++ }
> ++
> + if (_gdk_synchronize)
> + XSynchronize (display_x11->xdisplay, True);
> +
> +@@ -1043,6 +1061,9 @@ gdk_notify_startup_complete (void)
> + display_x11 = GDK_DISPLAY_X11 (display);
> +
> + if (display_x11->startup_notification_id == NULL)
> ++ return;
> ++
> ++ if (!G_LIKELY (display_x11->trusted_client))
> + return;
> +
> + escaped_id = escape_for_xmessage (display_x11->startup_notification_id);
> Index: patches/patch-gdk_x11_gdkdisplay-x11_h
> ===================================================================
> RCS file: patch-gdk_x11_gdkdisplay-x11_h
> diff -N patch-gdk_x11_gdkdisplay-x11_h
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gdk_x11_gdkdisplay-x11_h Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,15 @@
> +$OpenBSD$
> +--- gdk/x11/gdkdisplay-x11.h.orig Thu Jun 30 05:35:30 2005
> ++++ gdk/x11/gdkdisplay-x11.h Sat Jun 10 14:32:57 2006
> +@@ -81,6 +81,11 @@ struct _GdkDisplayX11
> + gboolean have_xfixes;
> + gint xfixes_event_base;
> +
> ++ /* If the SECURITY extension is in place, whether this client holds
> ++ * a trusted authorization and so is allowed to make various requests
> ++ * (grabs, properties etc.) Otherwise always TRUE. */
> ++ gboolean trusted_client;
> ++
> + /* Information about current pointer and keyboard grabs held by this
> + * client. If gdk_pointer_xgrab_window or gdk_keyboard_xgrab_window
> + * window is NULL, then the other associated fields are ignored
> Index: patches/patch-gdk_x11_gdkdnd-x11_c
> ===================================================================
> RCS file: patch-gdk_x11_gdkdnd-x11_c
> diff -N patch-gdk_x11_gdkdnd-x11_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gdk_x11_gdkdnd-x11_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,39 @@
> +$OpenBSD$
> +--- gdk/x11/gdkdnd-x11.c.orig Thu May 18 20:15:40 2006
> ++++ gdk/x11/gdkdnd-x11.c Sat Jun 10 14:32:57 2006
> +@@ -489,6 +489,25 @@ gdk_window_cache_new (GdkScreen *screen)
> +
> + XGetWindowAttributes (xdisplay, GDK_WINDOW_XWINDOW (root_window), &xwa);
> + result->old_event_mask = xwa.your_event_mask;
> ++
> ++ if (G_UNLIKELY (!GDK_DISPLAY_X11 (GDK_SCREEN_X11
> (screen)->display)->trusted_client))
> ++ {
> ++ GList *toplevel_windows, *list;
> ++ GdkWindow *window;
> ++ gint x, y, width, height;
> ++
> ++ toplevel_windows = gdk_screen_get_toplevel_windows (screen);
> ++ for (list = toplevel_windows; list; list = list->next) {
> ++ window = GDK_WINDOW (list->data);
> ++ gdk_window_get_geometry (window, &x, &y, &width, &height, NULL);
> ++ gdk_window_cache_add (result, GDK_WINDOW_XID (window),
> ++ x, y, width, height,
> ++ gdk_window_is_visible (window));
> ++ }
> ++ g_list_free (toplevel_windows);
> ++ return result;
> ++ }
> ++
> + XSelectInput (xdisplay, GDK_WINDOW_XWINDOW (root_window),
> + result->old_event_mask | SubstructureNotifyMask);
> + gdk_window_add_filter (root_window, gdk_window_cache_filter, result);
> +@@ -1315,6 +1334,9 @@ motif_send_enter (GdkDragContext *conte
> + GdkDragContextPrivateX11 *private = PRIVATE_DATA (context);
> + GdkDisplay *display = GDK_DRAWABLE_DISPLAY (context->source_window);
> + XEvent xev;
> ++
> ++ if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
> ++ return; /* Motif Dnd requires getting properties on the root window */
> +
> + xev.xclient.type = ClientMessage;
> + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display
> (display, "_MOTIF_DRAG_AND_DROP_MESSAGE");
> Index: patches/patch-gdk_x11_gdkevents-x11_c
> ===================================================================
> RCS file: patch-gdk_x11_gdkevents-x11_c
> diff -N patch-gdk_x11_gdkevents-x11_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gdk_x11_gdkevents-x11_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,32 @@
> +$OpenBSD$
> +--- gdk/x11/gdkevents-x11.c.orig Wed Jan 11 07:30:38 2006
> ++++ gdk/x11/gdkevents-x11.c Sat Jun 10 14:32:57 2006
> +@@ -2551,6 +2551,8 @@ fetch_net_wm_check_window (GdkScreen *sc
> +
> + screen_x11 = GDK_SCREEN_X11 (screen);
> + display = screen_x11->display;
> ++
> ++ g_return_if_fail (GDK_DISPLAY_X11 (display)->trusted_client);
> +
> + if (screen_x11->wmspec_check_window != None)
> + return; /* already have it */
> +@@ -2608,6 +2610,9 @@ gdk_x11_screen_get_window_manager_name (
> +
> + screen_x11 = GDK_SCREEN_X11 (screen);
> +
> ++ if (!G_LIKELY (GDK_DISPLAY_X11 (screen_x11->display)->trusted_client))
> ++ return screen_x11->window_manager_name;
> ++
> + fetch_net_wm_check_window (screen);
> +
> + if (screen_x11->need_refetch_wm_name)
> +@@ -2702,6 +2707,9 @@ gdk_x11_screen_supports_net_wm_hint (Gdk
> +
> + screen_x11 = GDK_SCREEN_X11 (screen);
> + display = screen_x11->display;
> ++
> ++ if (!G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
> ++ return FALSE;
> +
> + supported_atoms = g_object_get_data (G_OBJECT (screen),
> "gdk-net-wm-supported-atoms");
> + if (!supported_atoms)
> Index: patches/patch-gdk_x11_gdkmain-x11_c
> ===================================================================
> RCS file: patch-gdk_x11_gdkmain-x11_c
> diff -N patch-gdk_x11_gdkmain-x11_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gdk_x11_gdkmain-x11_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,70 @@
> +$OpenBSD$
> +--- gdk/x11/gdkmain-x11.c.orig Thu Jul 7 21:05:33 2005
> ++++ gdk/x11/gdkmain-x11.c Sat Jun 10 14:32:57 2006
> +@@ -191,6 +191,7 @@ gdk_pointer_grab (GdkWindow * window,
> + {
> + gint return_val;
> + GdkCursorPrivate *cursor_private;
> ++ GdkDisplayX11 *display_x11;
> + guint xevent_mask;
> + Window xwindow;
> + Window xconfine_to;
> +@@ -202,6 +203,8 @@ gdk_pointer_grab (GdkWindow * window,
> + g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
> + g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to),
> 0);
> +
> ++ display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
> ++
> + cursor_private = (GdkCursorPrivate*) cursor;
> +
> + xwindow = GDK_WINDOW_XID (window);
> +@@ -233,7 +236,8 @@ gdk_pointer_grab (GdkWindow * window,
> + confine_to,
> + time);
> +
> +- if (return_val == GrabSuccess)
> ++ if (return_val == GrabSuccess ||
> ++ G_UNLIKELY (!display_x11->trusted_client && return_val ==
> AlreadyGrabbed))
> + {
> + if (!GDK_WINDOW_DESTROYED (window))
> + {
> +@@ -257,7 +261,6 @@ gdk_pointer_grab (GdkWindow * window,
> +
> + if (return_val == GrabSuccess)
> + {
> +- GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY
> (window));
> + if (display_x11->pointer_xgrab_window != NULL &&
> + display_x11->pointer_xgrab_window != (GdkWindowObject *)window)
> + generate_grab_broken_event (GDK_WINDOW
> (display_x11->pointer_xgrab_window),
> +@@ -338,10 +341,13 @@ gdk_keyboard_grab (GdkWindow * window
> + {
> + gint return_val;
> + unsigned long serial;
> ++ GdkDisplayX11 *display_x11;
> +
> + g_return_val_if_fail (window != NULL, 0);
> + g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
> +
> ++ display_x11 = GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (window));
> ++
> + serial = NextRequest (GDK_WINDOW_XDISPLAY (window));
> +
> + if (!GDK_WINDOW_DESTROYED (window))
> +@@ -356,13 +362,16 @@ gdk_keyboard_grab (GdkWindow * window
> + owner_events,
> + GrabModeAsync, GrabModeAsync,
> + time);
> ++ if (G_UNLIKELY (!display_x11->trusted_client &&
> ++ return_val == AlreadyGrabbed))
> ++ /* we can't grab the keyboard, but we can do a GTK-local grab */
> ++ return_val = GrabSuccess;
> + }
> + else
> + return_val = AlreadyGrabbed;
> +
> + if (return_val == GrabSuccess)
> + {
> +- GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11
> (gdk_drawable_get_display (window));
> + if (display_x11->keyboard_xgrab_window != NULL &&
> + display_x11->keyboard_xgrab_window != (GdkWindowObject *)window)
> + generate_grab_broken_event (GDK_WINDOW
> (display_x11->keyboard_xgrab_window),
> Index: patches/patch-gdk_x11_gdkwindow-x11_c
> ===================================================================
> RCS file: patch-gdk_x11_gdkwindow-x11_c
> diff -N patch-gdk_x11_gdkwindow-x11_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gdk_x11_gdkwindow-x11_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,275 @@
> +$OpenBSD$
> +--- gdk/x11/gdkwindow-x11.c.orig Sun Apr 16 07:05:03 2006
> ++++ gdk/x11/gdkwindow-x11.c Sat Jun 10 14:37:24 2006
> +@@ -89,6 +89,7 @@ static void gdk_window_add_colormap_
> + static void set_wm_name (GdkDisplay *display,
> + Window xwindow,
> + const gchar *name);
> ++static void move_to_current_desktop (GdkWindow *window);
> +
> + static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable
> *drawable);
> + static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
> +@@ -761,6 +762,17 @@ gdk_window_new (GdkWindow *parent,
> + else
> + private->window_type = attributes->window_type;
> +
> ++ /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
> ++ * from an untrusted client:
> http://bugs.freedesktop.org/show_bug.cgi?id=6988
> ++ */
> ++ if (attributes->wclass == GDK_INPUT_ONLY &&
> ++ GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT &&
> ++ !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY
> (parent))->trusted_client))
> ++ {
> ++ g_warning ("Coercing GDK_INPUT_ONLY toplevel window to
> GDK_INPUT_OUTPUT to work around bug in Xorg server");
> ++ attributes->wclass = GDK_INPUT_OUTPUT;
> ++ }
> ++
> + _gdk_window_init_position (GDK_WINDOW (private));
> + if (impl->position_info.big)
> + private->guffaw_gravity = TRUE;
> +@@ -2040,7 +2052,13 @@ gdk_x11_window_move_to_current_desktop (
> +
> + if (toplevel->on_all_desktops)
> + return;
> ++
> ++ move_to_current_desktop (window);
> ++}
> +
> ++static void
> ++move_to_current_desktop (GdkWindow *window)
> ++{
> + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
> + gdk_atom_intern ("_NET_WM_DESKTOP",
> FALSE)))
> + {
> +@@ -3374,6 +3392,8 @@ _gdk_windowing_get_pointer (GdkDisplay
> + GdkModifierType *mask)
> + {
> + GdkScreen *default_screen;
> ++ Display *xdisplay;
> ++ Window xwindow;
> + Window root = None;
> + Window child;
> + int rootx, rooty;
> +@@ -3385,10 +3405,27 @@ _gdk_windowing_get_pointer (GdkDisplay
> + return;
> +
> + default_screen = gdk_display_get_default_screen (display);
> ++
> ++ xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
> ++ xwindow = GDK_SCREEN_XROOTWIN (default_screen);
> +
> +- XQueryPointer (GDK_SCREEN_XDISPLAY (default_screen),
> +- GDK_SCREEN_XROOTWIN (default_screen),
> +- &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
> ++ if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
> ++ {
> ++ XQueryPointer (xdisplay, xwindow,
> ++ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
> ++ }
> ++ else
> ++ {
> ++ XSetWindowAttributes attributes;
> ++ Window w;
> ++
> ++ w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
> ++ CopyFromParent, InputOnly, CopyFromParent,
> ++ 0, &attributes);
> ++ XQueryPointer (xdisplay, w,
> ++ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
> ++ XDestroyWindow (xdisplay, w);
> ++ }
> +
> + if (root != None)
> + {
> +@@ -3422,13 +3459,28 @@ _gdk_windowing_window_get_pointer (GdkDi
> + _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
> +
> + return_val = NULL;
> +- if (!GDK_WINDOW_DESTROYED (window) &&
> +- XQueryPointer (GDK_WINDOW_XDISPLAY (window),
> +- GDK_WINDOW_XID (window),
> +- &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
> ++ if (!GDK_WINDOW_DESTROYED (window))
> + {
> +- if (child)
> +- return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY
> (window), child);
> ++ if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
> ++ {
> ++ if (XQueryPointer (GDK_WINDOW_XDISPLAY (window),
> ++ GDK_WINDOW_XID (window),
> ++ &root, &child, &rootx, &rooty, &winx, &winy,
> &xmask))
> ++ {
> ++ if (child)
> ++ return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY
> (window), child);
> ++ }
> ++ }
> ++ else
> ++ {
> ++ GdkScreen *screen;
> ++ int originx, originy;
> ++ _gdk_windowing_get_pointer (gdk_drawable_get_display (window),
> &screen,
> ++ &rootx, &rooty, &xmask);
> ++ gdk_window_get_origin (window, &originx, &originy);
> ++ winx = rootx - originx;
> ++ winy = rooty - originy;
> ++ }
> + }
> +
> + *x = winx + xoffset;
> +@@ -3501,24 +3553,89 @@ _gdk_windowing_window_at_pointer (GdkDis
> + * and the result.
> + */
> + gdk_x11_display_grab (display);
> +- XQueryPointer (xdisplay, xwindow,
> +- &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
> +-
> +- if (root == xwindow)
> +- xwindow = child;
> +- else
> +- xwindow = root;
> +-
> +- while (xwindow)
> ++ if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
> + {
> +- xwindow_last = xwindow;
> + XQueryPointer (xdisplay, xwindow,
> +- &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
> ++ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
> ++ if (root == xwindow)
> ++ xwindow = child;
> ++ else
> ++ xwindow = root;
> ++
> ++ while (xwindow)
> ++ {
> ++ xwindow_last = xwindow;
> ++ XQueryPointer (xdisplay, xwindow,
> ++ &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
> ++ }
> ++ }
> ++ else
> ++ {
> ++ gint i, screens, width, height;
> ++ GList *toplevels, *list;
> ++ Window pointer_window;
> ++
> ++ pointer_window = None;
> ++ screens = gdk_display_get_n_screens (display);
> ++ for (i = 0; i < screens; ++i) {
> ++ screen = gdk_display_get_screen (display, i);
> ++ toplevels = gdk_screen_get_toplevel_windows (screen);
> ++ for (list = toplevels; list != NULL; list = g_list_next (list)) {
> ++ window = GDK_WINDOW (list->data);
> ++ xwindow = GDK_WINDOW_XWINDOW (window);
> ++ gdk_error_trap_push ();
> ++ XQueryPointer (xdisplay, xwindow,
> ++ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
> ++ gdk_flush ();
> ++ if (gdk_error_trap_pop ())
> ++ continue;
> ++ if (child != None)
> ++ {
> ++ pointer_window = child;
> ++ break;
> ++ }
> ++ gdk_window_get_geometry (window, NULL, NULL, &width, &height, NULL);
> ++ if (winx >= 0 && winy >= 0 && winx < width && winy < height)
> ++ {
> ++ /* A childless toplevel, or below another window? */
> ++ XSetWindowAttributes attributes;
> ++ Window w;
> ++
> ++ w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
> ++ CopyFromParent, InputOnly, CopyFromParent,
> ++ 0, &attributes);
> ++ XMapWindow (xdisplay, w);
> ++ XQueryPointer (xdisplay, xwindow,
> ++ &root, &child, &rootx, &rooty, &winx, &winy,
> &xmask);
> ++ XDestroyWindow (xdisplay, w);
> ++ if (child == w)
> ++ {
> ++ pointer_window = xwindow;
> ++ break;
> ++ }
> ++ }
> ++ }
> ++ g_list_free (toplevels);
> ++ if (pointer_window != None)
> ++ break;
> ++ }
> ++ xwindow = pointer_window;
> ++
> ++ while (xwindow)
> ++ {
> ++ xwindow_last = xwindow;
> ++ gdk_error_trap_push ();
> ++ XQueryPointer (xdisplay, xwindow,
> ++ &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
> ++ gdk_flush ();
> ++ if (gdk_error_trap_pop ())
> ++ break;
> ++ }
> + }
> ++
> + gdk_x11_display_ungrab (display);
> +
> +- window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen),
> +- xwindow_last);
> ++ window = gdk_window_lookup_for_display (display, xwindow_last);
> + *win_x = window ? winx : -1;
> + *win_y = window ? winy : -1;
> +
> +@@ -4353,52 +4470,12 @@ gdk_window_unstick (GdkWindow *window)
> +
> + if (GDK_WINDOW_IS_MAPPED (window))
> + {
> +- XEvent xev;
> +- Atom type;
> +- gint format;
> +- gulong nitems;
> +- gulong bytes_after;
> +- guchar *data;
> +- gulong *current_desktop;
> +- GdkDisplay *display = gdk_drawable_get_display (window);
> +-
> + /* Request unstick from viewport */
> + gdk_wmspec_change_state (FALSE, window,
> + gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
> + NULL);
> +
> +- /* Get current desktop, then set it; this is a race, but not
> +- * one that matters much in practice.
> +- */
> +- XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
> GDK_WINDOW_XROOTWIN (window),
> +- gdk_x11_get_xatom_by_name_for_display (display,
> "_NET_CURRENT_DESKTOP"),
> +- 0, G_MAXLONG,
> +- False, XA_CARDINAL, &type, &format, &nitems,
> +- &bytes_after, &data);
> +-
> +- if (type == XA_CARDINAL)
> +- {
> +- current_desktop = (gulong *)data;
> +-
> +- xev.xclient.type = ClientMessage;
> +- xev.xclient.serial = 0;
> +- xev.xclient.send_event = True;
> +- xev.xclient.window = GDK_WINDOW_XWINDOW (window);
> +- xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display
> (display, "_NET_WM_DESKTOP");
> +- xev.xclient.format = 32;
> +-
> +- xev.xclient.data.l[0] = *current_desktop;
> +- xev.xclient.data.l[1] = 0;
> +- xev.xclient.data.l[2] = 0;
> +- xev.xclient.data.l[3] = 0;
> +- xev.xclient.data.l[4] = 0;
> +-
> +- XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN
> (window), False,
> +- SubstructureRedirectMask | SubstructureNotifyMask,
> +- &xev);
> +-
> +- XFree (current_desktop);
> +- }
> ++ move_to_current_desktop (window);
> + }
> + else
> + {
> Index: patches/patch-gtk_gtkcolorsel_c
> ===================================================================
> RCS file: patch-gtk_gtkcolorsel_c
> diff -N patch-gtk_gtkcolorsel_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gtk_gtkcolorsel_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,35 @@
> +$OpenBSD$
> +--- gtk/gtkcolorsel.c.orig Sat Jun 25 09:09:58 2005
> ++++ gtk/gtkcolorsel.c Sat Jun 10 14:32:20 2006
> +@@ -1227,6 +1227,17 @@ grab_color_at_mouse (GdkScreen *screen,
> + priv = colorsel->private_data;
> +
> + image = gdk_drawable_get_image (root_window, x_root, y_root, 1, 1);
> ++ if (!image)
> ++ {
> ++ gint x, y;
> ++ GdkDisplay *display = gdk_screen_get_display (screen);
> ++ GdkWindow *window = gdk_display_get_window_at_pointer (display, &x,
> &y);
> ++ if (!window)
> ++ return;
> ++ image = gdk_drawable_get_image (window, x, y, 1, 1);
> ++ if (!image)
> ++ return;
> ++ }
> + pixel = gdk_image_get_pixel (image, 0, 0);
> + g_object_unref (image);
> +
> +@@ -1436,11 +1447,11 @@ get_screen_color (GtkWidget *button)
> + gtk_widget_add_events (priv->dropper_grab_widget,
> + GDK_BUTTON_RELEASE_MASK |
> GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
> +
> ++ gtk_widget_set_parent_window (priv->dropper_grab_widget,
> ++ GTK_WIDGET (colorsel)->window);
> + gtk_widget_show (priv->dropper_grab_widget);
> +
> + gdk_window_set_user_data (priv->dropper_grab_widget->window,
> colorsel);
> +- gdk_window_reparent (priv->dropper_grab_widget->window,
> +- GTK_WIDGET (colorsel)->window, 0, 0);
> + }
> +
> + if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
> Index: patches/patch-gtk_gtkinvisible_c
> ===================================================================
> RCS file: patch-gtk_gtkinvisible_c
> diff -N patch-gtk_gtkinvisible_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gtk_gtkinvisible_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,30 @@
> +$OpenBSD$
> +--- gtk/gtkinvisible.c.orig Tue Mar 22 03:14:55 2005
> ++++ gtk/gtkinvisible.c Sat Jun 10 14:32:20 2006
> +@@ -246,11 +246,16 @@ gtk_invisible_get_screen (GtkInvisible *
> + static void
> + gtk_invisible_realize (GtkWidget *widget)
> + {
> ++ GdkWindow *parent;
> + GdkWindowAttr attributes;
> + gint attributes_mask;
> +
> + GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
> +
> ++ parent = gtk_widget_get_parent_window (widget);
> ++ if (parent == NULL)
> ++ parent = gtk_widget_get_root_window (widget);
> ++
> + attributes.x = -100;
> + attributes.y = -100;
> + attributes.width = 10;
> +@@ -262,8 +267,7 @@ gtk_invisible_realize (GtkWidget *widget
> +
> + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
> +
> +- widget->window = gdk_window_new (gtk_widget_get_root_window (widget),
> +- &attributes, attributes_mask);
> ++ widget->window = gdk_window_new (parent, &attributes, attributes_mask);
> +
> + gdk_window_set_user_data (widget->window, widget);
> +
> Index: patches/patch-gtk_gtkwidget_c
> ===================================================================
> RCS file: patch-gtk_gtkwidget_c
> diff -N patch-gtk_gtkwidget_c
> --- /dev/null Sat Aug 30 18:16:59 1997
> +++ patches/patch-gtk_gtkwidget_c Sat Jun 10 12:57:43 2006
> @@ -0,0 +1,17 @@
> +$OpenBSD$
> +--- gtk/gtkwidget.c.orig Sat Apr 29 08:58:25 2006
> ++++ gtk/gtkwidget.c Sat Jun 10 14:32:20 2006
> +@@ -5616,11 +5616,11 @@ gtk_widget_get_parent_window (GtkWidge
> + GdkWindow *parent_window;
> +
> + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
> +- g_return_val_if_fail (widget->parent != NULL, NULL);
> +
> + parent_window = g_object_get_qdata (G_OBJECT (widget),
> quark_parent_window);
> +
> +- return (parent_window != NULL) ? parent_window : widget->parent->window;
> ++ return (parent_window != NULL) ? parent_window :
> ++ (widget->parent != NULL) ? widget->parent->window : NULL;
> + }
> +
> + /**
>
> Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm