manpagez: man pages & more
html files: gtk2
Home | html | info | man

Migrating to client-side windows

In version 2.18, GDK has been changed to use client-side windows. This means that there is no longer a 1-1 correspondence between GdkWindows and windows in the underlying window system. In particular, it is no longer correct to assume that each window has an associated XID. Code that makes this assumption can sometimes be fixed by calling gdk_window_ensure_native() on the windows in question. Calling gdk_x11_drawable_get_xid() (or GDK_WINDOW_XID()) from the X11-specific API on a non-native window will explicitly call gdk_window_ensure_native(), so old code using this will continue to work. A small gotcha is that the GDK_WINDOW_XID() call is no longer a trivial accessor for the XID of the window, and thus must not be called from another thread without taking locking precautions.

GDK looks for the GDK_NATIVE_WINDOWS environment variable and makes all windows native if it is set. It also tries to be more compatible with the way prior versions worked in some other ways.

Some applications assume that they can just operate on the X windows corresponding to their GDK windows without ever telling GDK. One example that we've seen is changing the child window stacking order using XRestackWindows(). Fixing this properly requires to fix the code to use GDK functions to achieve whatever it is trying to achieve. To make this easier in the case of stacking order changes, we've added a gdk_window_restack() function.

One change that can cause problems for some applications is that GDK is more aggressive about optimizing away expose events. Code that does more than just repainting exposed areas in response to expose events may be affected by this.

Problems can also occur when using cairo for drawing. One thing that can go wrong is clip handling. If you ever need to reset the clip region on a cairo_t (i.e. use cairo_reset_clip()), you have to to use gdk_cairo_reset_clip() instead. The reason for this is that the cairo_reset_clip() call will remove the initial clip region that limits your drawing to the client-side window at hand, so you will end up drawing over stuff outside the window. You also need to use gdk_cairo_reset_clip() if you use a cairo_t that was not allocated in a double-buffered expose handler and keep it in use after window hierarchy changes (resizing, moving, stacking order changes). The easiest fix for this kind of problem is to simply create a new cairo context for each expose event.

Due to a weird API in XClearArea the gdk_window_clear_area() call handled a specified width or height of zero to mean "to end of window" for non-double-buffered drawing. This has been changed to be consistent with the docs and what happens in the double-buffered case. All code in GTK+ that relied on this has been fixed, but it is possible (although unlikely) that third party applications rely on this. If you need to do this, just implement it yourself using gdk_drawable_get_size().

© 2000-2024
Individual documents may contain additional copyright information.