1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3 * Josh MacDonald, Ryan Lortie
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include <cairo-gobject.h>
32 #include "gdkwindow.h"
34 #ifdef GDK_WINDOWING_X11
35 #include "x11/gdkx.h" /* For workaround */
38 #include "gdkrectangle.h"
39 #include "gdkinternals.h"
41 #include "gdkscreen.h"
42 #include "gdkdeviceprivate.h"
43 #include "gdkdrawable.h"
44 #include "gdkmarshalers.h"
45 #include "gdkscreen.h"
46 #include "gdkwindowimpl.h"
50 #undef DEBUG_WINDOW_PRINTING
55 * @Short_description: Onscreen display areas in the target window system
58 * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
59 * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
60 * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
61 * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
62 * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
65 * <refsect2 id="COMPOSITED-WINDOWS">
66 * <title>Composited Windows</title>
68 * Normally, the windowing system takes care of rendering the contents of a
69 * child window onto its parent window. This mechanism can be intercepted by
70 * calling gdk_window_set_composited() on the child window. For a
71 * <firstterm>composited</firstterm> window it is the responsibility of the
72 * application to render the window contents at the right spot.
74 * <example id="composited-window-example">
75 * <title>Composited windows</title>
77 * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../examples/gdk/composited-window-example.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include>
78 * </programlisting></example>
80 * In the example <xref linkend="composited-window-example"/>, a button is
81 * placed inside of an event box inside of a window. The event box is set as
82 * composited and therefore is no longer automatically drawn to the screen.
84 * When the contents of the event box change, an expose event is generated on
85 * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
86 * The expose handler for this widget is responsible for merging the changes
87 * back on the screen in the way that it wishes.
89 * In our case, we merge the contents with a 50% transparency. We also set the
90 * background colour of the window to red. The effect is that the background
91 * shows through the button.
94 * <refsect2 id="OFFSCREEN-WINDOWS">
95 * <title>Offscreen Windows</title>
97 * Offscreen windows are more general than composited windows, since they allow
98 * not only to modify the rendering of the child window onto its parent, but
99 * also to apply coordinate transformations.
101 * To integrate an offscreen window into a window hierarchy, one has to call
102 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
103 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
104 * select an offscreen child at given coordinates, and the
105 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
106 * offscreen window are used to translate coordinates between the embedder and
107 * the offscreen window.
109 * For rendering an offscreen window onto its embedder, the contents of the
110 * offscreen window are available as a surface, via
111 * gdk_offscreen_window_get_surface().
117 /* Historically a GdkWindow always matches a platform native window,
118 * be it a toplevel window or a child window. In this setup the
119 * GdkWindow (and other GdkDrawables) were platform independent classes,
120 * and the actual platform specific implementation was in a delegate
121 * object availible as "impl" in the window object.
123 * With the addition of client side windows and offscreen windows this
124 * changes a bit. The application-visible GdkWindow object behaves as
125 * it did before, but not all such windows now have a corresponding native
126 * window. Instead windows that are "client side" are emulated by the gdk
127 * code such that clipping, drawing, moving, events etc work as expected.
129 * For GdkWindows that have a native window the "impl" object is the
130 * same as before. However, for all client side windows the impl object
131 * is shared with its parent (i.e. all client windows descendants of one
132 * native window has the same impl.
134 * Additionally there is a new type of platform independent impl object,
135 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
136 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
137 * windows). Such windows work by allocating a #cairo_surface_t as the backing
138 * store for drawing operations, which is resized with the window.
140 * GdkWindows have a pointer to the "impl window" they are in, i.e.
141 * the topmost GdkWindow which have the same "impl" value. This is stored
142 * in impl_window, which is different from the window itself only for client
144 * All GdkWindows (native or not) track the position of the window in the parent
145 * (x, y), the size of the window (width, height), the position of the window
146 * with respect to the impl window (abs_x, abs_y). We also track the clip
147 * region of the window wrt parent windows and siblings, in window-relative
148 * coordinates with and without child windows included (clip_region,
149 * clip_region_with_children).
151 * All toplevel windows are native windows, but also child windows can be
152 * native (although not children of offscreens). We always listen to
153 * a basic set of events (see get_native_event_mask) for these windows
154 * so that we can emulate events for any client side children.
156 * For native windows we apply the calculated clip region as a window shape
157 * so that eg. client side siblings that overlap the native child properly
158 * draws over the native child window.
160 * In order to minimize flicker and for performance we use a couple of cacheing
161 * tricks. First of all, every time we do a window to window copy area, for instance
162 * when moving a client side window or when scrolling/moving a region in a window
163 * we store this in outstanding_moves instead of applying immediately. We then
164 * delay this move until we really need it (because something depends on being
165 * able to read it), or until we're handing a redraw from an expose/invalidation
166 * (actually we delay it past redraw, but before blitting the double buffer
167 * to the window). This gives us two advantages. First of all it minimizes the time
168 * from the window is moved to the exposes related to that move, secondly it allows
169 * us to be smart about how to do the copy. We combine multiple moves into one (when
170 * possible) and we don't actually do copies to anything that is or will be
171 * invalidated and exposed anyway.
173 * Secondly, we use something called a "implicit paint" during repaint handling.
174 * An implicit paint is similar to a regular paint for the paint stack, but it is
175 * not put on the stack. Instead, it is set on the impl window, and later when
176 * regular gdk_window_begin_paint_region() happen on a window of this impl window
177 * we reuse the surface from the implicit paint. During repaint we create and at the
178 * end flush an implicit paint, which means we can collect all the paints on
179 * multiple client side windows in the same backing store.
182 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
184 /* This adds a local value to the GdkVisibilityState enum */
185 #define GDK_VISIBILITY_NOT_VIEWABLE 3
188 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
202 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
206 struct _GdkWindowPaint
208 cairo_region_t *region;
209 cairo_surface_t *surface;
210 guint uses_implicit : 1;
216 cairo_region_t *dest_region; /* The destination region */
217 int dx, dy; /* The amount that the source was moved to reach dest_region */
218 } GdkWindowRegionMove;
222 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
223 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
226 static void gdk_window_drop_cairo_surface (GdkWindowObject *private);
227 static void gdk_window_set_cairo_clip (GdkDrawable *drawable,
230 static cairo_region_t* gdk_window_get_clip_region (GdkDrawable *drawable);
231 static cairo_region_t* gdk_window_get_visible_region (GdkDrawable *drawable);
233 static void gdk_window_free_paint_stack (GdkWindow *window);
235 static void gdk_window_init (GdkWindowObject *window);
236 static void gdk_window_class_init (GdkWindowObjectClass *klass);
237 static void gdk_window_finalize (GObject *object);
239 static void gdk_window_set_property (GObject *object,
243 static void gdk_window_get_property (GObject *object,
248 static void gdk_window_clear_backing_region (GdkWindow *window,
249 cairo_region_t *region);
251 static void recompute_visible_regions (GdkWindowObject *private,
252 gboolean recalculate_siblings,
253 gboolean recalculate_children);
254 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
255 static void gdk_window_flush_recursive (GdkWindowObject *window);
256 static void do_move_region_bits_on_impl (GdkWindowObject *private,
257 cairo_region_t *region, /* In impl window coords */
259 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
260 static void move_native_children (GdkWindowObject *private);
261 static void update_cursor (GdkDisplay *display,
263 static void impl_window_add_update_area (GdkWindowObject *impl_window,
264 cairo_region_t *region);
265 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
266 static void gdk_window_invalidate_region_full (GdkWindow *window,
267 const cairo_region_t *region,
268 gboolean invalidate_children,
270 static void gdk_window_invalidate_rect_full (GdkWindow *window,
271 const GdkRectangle *rect,
272 gboolean invalidate_children,
275 static guint signals[LAST_SIGNAL] = { 0 };
277 static gpointer parent_class = NULL;
279 static const cairo_user_data_key_t gdk_window_cairo_key;
282 new_region_tag (void)
284 static guint32 tag = 0;
290 gdk_window_object_get_type (void)
292 static GType object_type = 0;
295 object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
297 sizeof (GdkWindowObjectClass),
298 (GClassInitFunc) gdk_window_class_init,
299 sizeof (GdkWindowObject),
300 (GInstanceInitFunc) gdk_window_init,
307 _gdk_paintable_get_type (void)
309 static GType paintable_type = 0;
313 const GTypeInfo paintable_info =
315 sizeof (GdkPaintableIface), /* class_size */
316 NULL, /* base_init */
317 NULL, /* base_finalize */
320 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
321 g_intern_static_string ("GdkPaintable"),
324 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
327 return paintable_type;
331 gdk_window_init (GdkWindowObject *window)
333 /* 0-initialization is good for all other fields. */
335 window->window_type = GDK_WINDOW_CHILD;
337 window->state = GDK_WINDOW_STATE_WITHDRAWN;
340 window->toplevel_window_type = -1;
342 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
343 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
344 /* Default to unobscured since some backends don't send visibility events */
345 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
348 /* Stop and return on the first non-NULL parent */
350 accumulate_get_window (GSignalInvocationHint *ihint,
352 const GValue *handler_return,
355 g_value_copy (handler_return, return_accu);
356 /* Continue while returning NULL */
357 return g_value_get_object (handler_return) == NULL;
361 create_surface_accumulator (GSignalInvocationHint *ihint,
363 const GValue *handler_return,
366 g_value_copy (handler_return, return_accu);
368 /* Stop on the first non-NULL return value */
369 return g_value_get_boxed (handler_return) == NULL;
372 static GQuark quark_pointer_window = 0;
375 gdk_window_class_init (GdkWindowObjectClass *klass)
377 GObjectClass *object_class = G_OBJECT_CLASS (klass);
378 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
380 parent_class = g_type_class_peek_parent (klass);
382 object_class->finalize = gdk_window_finalize;
383 object_class->set_property = gdk_window_set_property;
384 object_class->get_property = gdk_window_get_property;
386 drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
387 drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
388 drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
389 drawable_class->get_clip_region = gdk_window_get_clip_region;
390 drawable_class->get_visible_region = gdk_window_get_visible_region;
392 klass->create_surface = _gdk_offscreen_window_create_surface;
394 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
402 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
403 * gdk_window_get_cursor() for details.
407 g_object_class_install_property (object_class,
409 g_param_spec_boxed ("cursor",
416 * GdkWindow::pick-embedded-child:
417 * @window: the window on which the signal is emitted
418 * @x: x coordinate in the window
419 * @y: y coordinate in the window
421 * The ::pick-embedded-child signal is emitted to find an embedded
422 * child at the given position.
424 * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
428 signals[PICK_EMBEDDED_CHILD] =
429 g_signal_new (g_intern_static_string ("pick-embedded-child"),
430 G_OBJECT_CLASS_TYPE (object_class),
432 G_STRUCT_OFFSET (GdkWindowObjectClass, pick_embedded_child),
433 accumulate_get_window, NULL,
434 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
441 * GdkWindow::to-embedder:
442 * @window: the offscreen window on which the signal is emitted
443 * @offscreen-x: x coordinate in the offscreen window
444 * @offscreen-y: y coordinate in the offscreen window
445 * @embedder-x: return location for the x coordinate in the embedder window
446 * @embedder-y: return location for the y coordinate in the embedder window
448 * The ::to-embedder signal is emitted to translate coordinates
449 * in an offscreen window to its embedder.
451 * See also #GtkWindow::from-embedder.
455 signals[TO_EMBEDDER] =
456 g_signal_new (g_intern_static_string ("to-embedder"),
457 G_OBJECT_CLASS_TYPE (object_class),
459 G_STRUCT_OFFSET (GdkWindowObjectClass, to_embedder),
461 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
470 * GdkWindow::from-embedder:
471 * @window: the offscreen window on which the signal is emitted
472 * @embedder-x: x coordinate in the embedder window
473 * @embedder-y: y coordinate in the embedder window
474 * @offscreen-x: return location for the x coordinate in the offscreen window
475 * @offscreen-y: return location for the y coordinate in the offscreen window
477 * The ::from-embedder signal is emitted to translate coordinates
478 * in the embedder of an offscreen window to the offscreen window.
480 * See also #GtkWindow::to-embedder.
484 signals[FROM_EMBEDDER] =
485 g_signal_new (g_intern_static_string ("from-embedder"),
486 G_OBJECT_CLASS_TYPE (object_class),
488 G_STRUCT_OFFSET (GdkWindowObjectClass, from_embedder),
490 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
499 * GdkWindow::create-surface:
500 * @window: the offscreen window on which the signal is emitted
501 * @width: the width of the offscreen surface to create
502 * @height: the height of the offscreen surface to create
504 * The ::create-surface signal is emitted when an offscreen window
505 * needs its surface (re)created, which happens either when the the
506 * window is first drawn to, or when the window is being
507 * resized. The first signal handler that returns a non-%NULL
508 * surface will stop any further signal emission, and its surface
511 * Note that it is not possible to access the window's previous
512 * surface from within any callback of this signal. Calling
513 * gdk_offscreen_window_get_surface() will lead to a crash.
515 * Returns: the newly created #cairo_surface_t for the offscreen window
519 signals[CREATE_SURFACE] =
520 g_signal_new (g_intern_static_string ("create-surface"),
521 G_OBJECT_CLASS_TYPE (object_class),
523 G_STRUCT_OFFSET (GdkWindowObjectClass, create_surface),
524 create_surface_accumulator, NULL,
525 _gdk_marshal_BOXED__INT_INT,
526 CAIRO_GOBJECT_TYPE_SURFACE,
533 device_removed_cb (GdkDeviceManager *device_manager,
537 GdkWindowObject *private;
539 private = (GdkWindowObject *) window;
541 private->devices_inside = g_list_remove (private->devices_inside, device);
542 g_hash_table_remove (private->device_cursor, device);
544 if (private->device_events)
545 g_hash_table_remove (private->device_events, device);
549 gdk_window_finalize (GObject *object)
551 GdkWindow *window = GDK_WINDOW (object);
552 GdkWindowObject *obj = (GdkWindowObject *) object;
553 GdkDeviceManager *device_manager;
555 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
556 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
558 if (!GDK_WINDOW_DESTROYED (window))
560 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
562 g_warning ("losing last reference to undestroyed window\n");
563 _gdk_window_destroy (window, FALSE);
566 /* We use TRUE here, to keep us from actually calling
567 * XDestroyWindow() on the window
569 _gdk_window_destroy (window, TRUE);
572 gdk_window_drop_cairo_surface (obj);
576 g_object_unref (obj->impl);
580 if (obj->impl_window != obj)
582 g_object_unref (obj->impl_window);
583 obj->impl_window = NULL;
587 cairo_region_destroy (obj->shape);
589 if (obj->input_shape)
590 cairo_region_destroy (obj->input_shape);
593 gdk_cursor_unref (obj->cursor);
595 if (obj->device_cursor)
596 g_hash_table_destroy (obj->device_cursor);
598 if (obj->device_events)
599 g_hash_table_destroy (obj->device_events);
601 if (obj->devices_inside)
602 g_list_free (obj->devices_inside);
604 G_OBJECT_CLASS (parent_class)->finalize (object);
608 gdk_window_set_property (GObject *object,
613 GdkWindow *window = (GdkWindow *)object;
618 gdk_window_set_cursor (window, g_value_get_boxed (value));
622 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
628 gdk_window_get_property (GObject *object,
633 GdkWindow *window = (GdkWindow *) object;
638 g_value_set_boxed (value, gdk_window_get_cursor (window));
642 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
648 gdk_window_is_offscreen (GdkWindowObject *window)
650 return window->window_type == GDK_WINDOW_OFFSCREEN;
653 static GdkWindowObject *
654 gdk_window_get_impl_window (GdkWindowObject *window)
656 return window->impl_window;
660 _gdk_window_get_impl_window (GdkWindow *window)
662 return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
666 gdk_window_has_impl (GdkWindowObject *window)
668 return window->impl_window == window;
672 gdk_window_is_toplevel (GdkWindowObject *window)
675 window->parent == NULL ||
676 window->parent->window_type == GDK_WINDOW_ROOT;
680 _gdk_window_has_impl (GdkWindow *window)
682 return gdk_window_has_impl ((GdkWindowObject *)window);
686 gdk_window_has_no_impl (GdkWindowObject *window)
688 return window->impl_window != window;
692 remove_child_area (GdkWindowObject *private,
693 GdkWindowObject *until,
695 cairo_region_t *region)
697 GdkWindowObject *child;
698 cairo_region_t *child_region;
701 cairo_region_t *shape;
703 for (l = private->children; l; l = l->next)
710 /* If region is empty already, no need to do
711 anything potentially costly */
712 if (cairo_region_is_empty (region))
715 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
718 /* Ignore offscreen children, as they don't draw in their parent and
719 * don't take part in the clipping */
720 if (gdk_window_is_offscreen (child))
725 r.width = child->width;
726 r.height = child->height;
728 /* Bail early if child totally outside region */
729 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
732 child_region = cairo_region_create_rectangle (&r);
736 /* Adjust shape region to parent window coords */
737 cairo_region_translate (child->shape, child->x, child->y);
738 cairo_region_intersect (child_region, child->shape);
739 cairo_region_translate (child->shape, -child->x, -child->y);
741 else if (private->window_type == GDK_WINDOW_FOREIGN)
743 shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
746 cairo_region_intersect (child_region, shape);
747 cairo_region_destroy (shape);
753 if (child->input_shape)
754 cairo_region_intersect (child_region, child->input_shape);
755 else if (private->window_type == GDK_WINDOW_FOREIGN)
757 shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
760 cairo_region_intersect (child_region, shape);
761 cairo_region_destroy (shape);
766 cairo_region_subtract (region, child_region);
767 cairo_region_destroy (child_region);
772 static GdkVisibilityState
773 effective_visibility (GdkWindowObject *private)
775 GdkVisibilityState native;
777 if (!gdk_window_is_viewable ((GdkWindow *)private))
778 return GDK_VISIBILITY_NOT_VIEWABLE;
780 native = private->impl_window->native_visibility;
782 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
783 private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
784 return GDK_VISIBILITY_FULLY_OBSCURED;
785 else if (native == GDK_VISIBILITY_UNOBSCURED)
786 return private->visibility;
787 else /* native PARTIAL, private partial or unobscured */
788 return GDK_VISIBILITY_PARTIAL;
792 gdk_window_update_visibility (GdkWindowObject *private)
794 GdkVisibilityState new_visibility;
797 new_visibility = effective_visibility (private);
799 if (new_visibility != private->effective_visibility)
801 private->effective_visibility = new_visibility;
803 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
804 private->event_mask & GDK_VISIBILITY_NOTIFY)
806 event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
808 event->visibility.state = new_visibility;
814 gdk_window_update_visibility_recursively (GdkWindowObject *private,
815 GdkWindowObject *only_for_impl)
817 GdkWindowObject *child;
820 gdk_window_update_visibility (private);
821 for (l = private->children; l != NULL; l = l->next)
824 if ((only_for_impl == NULL) ||
825 (only_for_impl == child->impl_window))
826 gdk_window_update_visibility_recursively (child, only_for_impl);
831 should_apply_clip_as_shape (GdkWindowObject *private)
834 gdk_window_has_impl (private) &&
835 /* Not for offscreens */
836 !gdk_window_is_offscreen (private) &&
837 /* or for toplevels */
838 !gdk_window_is_toplevel (private) &&
839 /* or for foreign windows */
840 private->window_type != GDK_WINDOW_FOREIGN &&
841 /* or for the root window */
842 private->window_type != GDK_WINDOW_ROOT;
846 apply_shape (GdkWindowObject *private,
847 cairo_region_t *region)
849 GdkWindowImplIface *impl_iface;
851 /* We trash whether we applied a shape so that
852 we can avoid unsetting it many times, which
853 could happen in e.g. apply_clip_as_shape as
854 windows get resized */
855 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
857 impl_iface->shape_combine_region ((GdkWindow *)private,
859 else if (private->applied_shape)
860 impl_iface->shape_combine_region ((GdkWindow *)private,
863 private->applied_shape = region != NULL;
867 region_rect_equal (const cairo_region_t *region,
868 const GdkRectangle *rect)
870 GdkRectangle extents;
872 if (cairo_region_num_rectangles (region) != 1)
875 cairo_region_get_extents (region, &extents);
877 return extents.x == rect->x &&
878 extents.y == rect->y &&
879 extents.width == rect->width &&
880 extents.height == rect->height;
884 apply_clip_as_shape (GdkWindowObject *private)
889 r.width = private->width;
890 r.height = private->height;
892 /* We only apply the clip region if would differ
893 from the actual clip region implied by the size
894 of the window. This is to avoid unneccessarily
895 adding meaningless shapes to all native subwindows */
896 if (!region_rect_equal (private->clip_region, &r))
897 apply_shape (private, private->clip_region);
899 apply_shape (private, NULL);
903 recompute_visible_regions_internal (GdkWindowObject *private,
904 gboolean recalculate_clip,
905 gboolean recalculate_siblings,
906 gboolean recalculate_children)
910 GdkWindowObject *child;
911 cairo_region_t *new_clip, *old_clip_region_with_children;
912 gboolean clip_region_changed;
913 gboolean abs_pos_changed;
914 int old_abs_x, old_abs_y;
916 old_abs_x = private->abs_x;
917 old_abs_y = private->abs_y;
919 /* Update absolute position */
920 if (gdk_window_has_impl (private))
922 /* Native window starts here */
928 private->abs_x = private->parent->abs_x + private->x;
929 private->abs_y = private->parent->abs_y + private->y;
933 private->abs_x != old_abs_x ||
934 private->abs_y != old_abs_y;
936 /* Update clip region based on:
939 * siblings in parents above window
941 clip_region_changed = FALSE;
942 if (recalculate_clip)
944 if (private->viewable)
946 /* Calculate visible region (sans children) in parent window coords */
949 r.width = private->width;
950 r.height = private->height;
951 new_clip = cairo_region_create_rectangle (&r);
953 if (!gdk_window_is_toplevel (private))
955 cairo_region_intersect (new_clip, private->parent->clip_region);
957 /* Remove all overlapping children from parent.
958 * Unless we're all native, because then we don't need to take
959 * siblings into account since X does that clipping for us.
960 * This makes things like SWT that modify the raw X stacking
961 * order without GDKs knowledge work.
963 if (!_gdk_native_windows)
964 remove_child_area (private->parent, private, FALSE, new_clip);
967 /* Convert from parent coords to window coords */
968 cairo_region_translate (new_clip, -private->x, -private->y);
971 cairo_region_intersect (new_clip, private->shape);
974 new_clip = cairo_region_create ();
976 if (private->clip_region == NULL ||
977 !cairo_region_equal (private->clip_region, new_clip))
978 clip_region_changed = TRUE;
980 if (private->clip_region)
981 cairo_region_destroy (private->clip_region);
982 private->clip_region = new_clip;
984 old_clip_region_with_children = private->clip_region_with_children;
985 private->clip_region_with_children = cairo_region_copy (private->clip_region);
986 if (private->window_type != GDK_WINDOW_ROOT)
987 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
989 if (clip_region_changed ||
990 !cairo_region_equal (private->clip_region_with_children, old_clip_region_with_children))
991 private->clip_tag = new_region_tag ();
993 if (old_clip_region_with_children)
994 cairo_region_destroy (old_clip_region_with_children);
997 if (clip_region_changed)
999 GdkVisibilityState visibility;
1000 gboolean fully_visible;
1002 if (cairo_region_is_empty (private->clip_region))
1003 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
1008 fully_visible = cairo_region_equal (private->clip_region,
1015 r.width = private->width;
1016 r.height = private->height;
1017 fully_visible = region_rect_equal (private->clip_region, &r);
1021 visibility = GDK_VISIBILITY_UNOBSCURED;
1023 visibility = GDK_VISIBILITY_PARTIAL;
1026 if (private->visibility != visibility)
1028 private->visibility = visibility;
1029 gdk_window_update_visibility (private);
1033 /* Update all children, recursively (except for root, where children are not exact). */
1034 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1035 private->window_type != GDK_WINDOW_ROOT)
1037 for (l = private->children; l; l = l->next)
1040 /* Only recalculate clip if the the clip region changed, otherwise
1041 * there is no way the child clip region could change (its has not e.g. moved)
1042 * Except if recalculate_children is set to force child updates
1044 recompute_visible_regions_internal (child,
1045 recalculate_clip && (clip_region_changed || recalculate_children),
1050 if (clip_region_changed &&
1051 should_apply_clip_as_shape (private))
1052 apply_clip_as_shape (private);
1054 if (recalculate_siblings &&
1055 !gdk_window_is_toplevel (private))
1057 /* If we moved a child window in parent or changed the stacking order, then we
1058 * need to recompute the visible area of all the other children in the parent
1060 for (l = private->parent->children; l; l = l->next)
1064 if (child != private)
1065 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1068 /* We also need to recompute the _with_children clip for the parent */
1069 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1072 if (private->cairo_surface && gdk_window_has_impl (private))
1074 GdkWindowImplIface *iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1076 private->cairo_surface = iface->resize_cairo_surface (private->impl,
1077 private->cairo_surface,
1081 else if (private->cairo_surface)
1082 gdk_window_drop_cairo_surface (private);
1085 /* Call this when private has changed in one or more of these ways:
1089 * stacking order of window changed
1092 * It will recalculate abs_x/y and the clip regions
1094 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1095 * for recalculate_siblings. (Mostly used internally for the recursion)
1097 * If a child window was removed (and you can't use that child for
1098 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1101 recompute_visible_regions (GdkWindowObject *private,
1102 gboolean recalculate_siblings,
1103 gboolean recalculate_children)
1105 recompute_visible_regions_internal (private,
1107 recalculate_siblings,
1108 recalculate_children);
1112 _gdk_window_update_size (GdkWindow *window)
1114 recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1117 /* Find the native window that would be just above "child"
1118 * in the native stacking order if "child" was a native window
1119 * (it doesn't have to be native). If there is no such native
1120 * window inside this native parent then NULL is returned.
1121 * If child is NULL, find lowest native window in parent.
1123 static GdkWindowObject *
1124 find_native_sibling_above_helper (GdkWindowObject *parent,
1125 GdkWindowObject *child)
1132 l = g_list_find (parent->children, child);
1133 g_assert (l != NULL); /* Better be a child of its parent... */
1134 l = l->prev; /* Start looking at the one above the child */
1137 l = g_list_last (parent->children);
1139 for (; l != NULL; l = l->prev)
1143 if (gdk_window_has_impl (w))
1146 g_assert (parent != w);
1147 w = find_native_sibling_above_helper (w, NULL);
1156 static GdkWindowObject *
1157 find_native_sibling_above (GdkWindowObject *parent,
1158 GdkWindowObject *child)
1162 w = find_native_sibling_above_helper (parent, child);
1166 if (gdk_window_has_impl (parent))
1169 return find_native_sibling_above (parent->parent, parent);
1173 get_native_device_event_mask (GdkWindowObject *private,
1176 GdkEventMask event_mask;
1179 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1181 event_mask = private->event_mask;
1183 if (_gdk_native_windows ||
1184 private->window_type == GDK_WINDOW_ROOT ||
1185 private->window_type == GDK_WINDOW_FOREIGN)
1191 /* Do whatever the app asks to, since the app
1192 * may be asking for weird things for native windows,
1193 * but don't use motion hints as that may affect non-native
1194 * child windows that don't want it. Also, we need to
1195 * set all the app-specified masks since they will be picked
1196 * up by any implicit grabs (i.e. if they were not set as
1197 * native we would not get the events we need). */
1198 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1200 /* We need thse for all native windows so we can
1201 emulate events on children: */
1204 GDK_VISIBILITY_NOTIFY_MASK |
1205 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1207 /* Additionally we select for pointer and button events
1208 * for toplevels as we need to get these to emulate
1209 * them for non-native subwindows. Even though we don't
1210 * select on them for all native windows we will get them
1211 * as the events are propagated out to the first window
1212 * that select for them.
1213 * Not selecting for button press on all windows is an
1214 * important thing, because in X only one client can do
1215 * so, and we don't want to unexpectedly prevent another
1216 * client from doing it.
1218 * We also need to do the same if the app selects for button presses
1219 * because then we will get implicit grabs for this window, and the
1220 * event mask used for that grab is based on the rest of the mask
1221 * for the window, but we might need more events than this window
1222 * lists due to some non-native child window.
1224 if (gdk_window_is_toplevel (private) ||
1225 mask & GDK_BUTTON_PRESS_MASK)
1227 GDK_POINTER_MOTION_MASK |
1228 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1236 get_native_grab_event_mask (GdkEventMask grab_mask)
1238 /* Similar to the above but for pointer events only */
1240 GDK_POINTER_MOTION_MASK |
1241 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1242 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1245 ~GDK_POINTER_MOTION_HINT_MASK);
1249 get_native_event_mask (GdkWindowObject *private)
1251 return get_native_device_event_mask (private, NULL);
1254 /* Puts the native window in the right order wrt the other native windows
1255 * in the hierarchy, given the position it has in the client side data.
1256 * This is useful if some operation changed the stacking order.
1257 * This calls assumes the native window is now topmost in its native parent.
1260 sync_native_window_stack_position (GdkWindow *window)
1262 GdkWindowObject *above;
1263 GdkWindowObject *private;
1264 GdkWindowImplIface *impl_iface;
1265 GList listhead = {0};
1267 private = (GdkWindowObject *) window;
1268 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1270 above = find_native_sibling_above (private->parent, private);
1273 listhead.data = window;
1274 impl_iface->restack_under ((GdkWindow *)above,
1281 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1282 * the default root window for the default display.
1283 * @attributes: attributes of the new window
1284 * @attributes_mask: mask indicating which fields in @attributes are valid
1286 * Creates a new #GdkWindow using the attributes from
1287 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1288 * more details. Note: to use this on displays other than the default
1289 * display, @parent must be specified.
1291 * Return value: (transfer none): the new #GdkWindow
1294 gdk_window_new (GdkWindow *parent,
1295 GdkWindowAttr *attributes,
1296 gint attributes_mask)
1299 GdkWindowObject *private;
1303 GdkEventMask event_mask;
1304 GdkWindow *real_parent;
1305 GdkDeviceManager *device_manager;
1307 g_return_val_if_fail (attributes != NULL, NULL);
1311 GDK_NOTE (MULTIHEAD,
1312 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1314 screen = gdk_screen_get_default ();
1315 parent = gdk_screen_get_root_window (screen);
1318 screen = gdk_window_get_screen (parent);
1320 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1322 if (GDK_WINDOW_DESTROYED (parent))
1324 g_warning ("gdk_window_new(): parent is destroyed\n");
1328 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1329 _gdk_native_windows)
1331 g_warning ("Offscreen windows not supported with native-windows gdk");
1335 window = g_object_new (GDK_TYPE_WINDOW, NULL);
1336 private = (GdkWindowObject *) window;
1338 /* Windows with a foreign parent are treated as if they are children
1339 * of the root window, except for actual creation.
1341 real_parent = parent;
1342 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1343 parent = gdk_screen_get_root_window (screen);
1345 private->parent = (GdkWindowObject *)parent;
1347 private->accept_focus = TRUE;
1348 private->focus_on_map = TRUE;
1350 if (attributes_mask & GDK_WA_X)
1355 if (attributes_mask & GDK_WA_Y)
1362 private->width = (attributes->width > 1) ? (attributes->width) : (1);
1363 private->height = (attributes->height > 1) ? (attributes->height) : (1);
1365 #ifdef GDK_WINDOWING_X11
1366 /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1367 * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1369 if (attributes->wclass == GDK_INPUT_ONLY &&
1370 private->parent->window_type == GDK_WINDOW_ROOT &&
1371 !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1373 g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1374 attributes->wclass = GDK_INPUT_OUTPUT;
1378 if (attributes->wclass == GDK_INPUT_ONLY)
1380 /* Backwards compatiblity - we've always ignored
1381 * attributes->window_type for input-only windows
1384 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1385 private->window_type = GDK_WINDOW_TEMP;
1387 private->window_type = GDK_WINDOW_CHILD;
1390 private->window_type = attributes->window_type;
1393 switch (private->window_type)
1395 case GDK_WINDOW_TOPLEVEL:
1396 case GDK_WINDOW_TEMP:
1397 case GDK_WINDOW_OFFSCREEN:
1398 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1399 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1400 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1401 case GDK_WINDOW_CHILD:
1405 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1409 if (attributes_mask & GDK_WA_VISUAL)
1410 private->visual = attributes->visual;
1412 private->visual = gdk_screen_get_system_visual (screen);
1414 private->event_mask = attributes->event_mask;
1416 if (attributes->wclass == GDK_INPUT_OUTPUT)
1418 private->input_only = FALSE;
1419 private->depth = private->visual->depth;
1421 /* XXX: Cache this somehow? */
1422 private->background = cairo_pattern_create_rgb (0, 0, 0);
1427 private->input_only = TRUE;
1430 if (private->parent)
1431 private->parent->children = g_list_prepend (private->parent->children, window);
1433 private->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1434 (GDestroyNotify) gdk_cursor_unref);
1436 native = _gdk_native_windows; /* Default */
1437 if (private->parent->window_type == GDK_WINDOW_ROOT)
1438 native = TRUE; /* Always use native windows for toplevels */
1439 else if (!private->input_only &&
1440 (attributes_mask & GDK_WA_VISUAL &&
1441 attributes->visual != gdk_window_get_visual (GDK_WINDOW (private->parent))))
1442 native = TRUE; /* InputOutput window with different visual than parent, needs native window */
1444 if (gdk_window_is_offscreen (private))
1446 _gdk_offscreen_window_new (window, attributes, attributes_mask);
1447 private->impl_window = private;
1451 event_mask = get_native_event_mask (private);
1453 /* Create the impl */
1454 _gdk_window_impl_new (window, real_parent, screen, event_mask, attributes, attributes_mask);
1455 private->impl_window = private;
1457 /* This will put the native window topmost in the native parent, which may
1458 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1459 if (!_gdk_window_has_impl (real_parent))
1460 sync_native_window_stack_position (window);
1464 private->impl_window = g_object_ref (private->parent->impl_window);
1465 private->impl = g_object_ref (private->impl_window->impl);
1468 recompute_visible_regions (private, TRUE, FALSE);
1470 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1471 (attributes->cursor) :
1474 device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent));
1475 g_signal_connect (device_manager, "device-removed",
1476 G_CALLBACK (device_removed_cb), window);
1482 is_parent_of (GdkWindow *parent,
1493 w = gdk_window_get_parent (w);
1500 change_impl (GdkWindowObject *private,
1501 GdkWindowObject *impl_window,
1505 GdkWindowObject *child;
1506 GdkDrawable *old_impl;
1507 GdkWindowObject *old_impl_window;
1509 old_impl = private->impl;
1510 old_impl_window = private->impl_window;
1511 if (private != impl_window)
1512 private->impl_window = g_object_ref (impl_window);
1514 private->impl_window = private;
1515 private->impl = g_object_ref (new);
1516 if (old_impl_window != private)
1517 g_object_unref (old_impl_window);
1518 g_object_unref (old_impl);
1520 for (l = private->children; l != NULL; l = l->next)
1524 if (child->impl == old_impl)
1525 change_impl (child, impl_window, new);
1530 reparent_to_impl (GdkWindowObject *private)
1533 GdkWindowObject *child;
1535 GdkWindowImplIface *impl_iface;
1537 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1539 /* Enumerate in reverse order so we get the right order for the native
1540 windows (first in childrens list is topmost, and reparent places on top) */
1541 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1545 if (child->impl == private->impl)
1546 reparent_to_impl (child);
1549 show = impl_iface->reparent ((GdkWindow *)child,
1550 (GdkWindow *)private,
1551 child->x, child->y);
1553 gdk_window_show_unraised ((GdkWindow *)child);
1560 * gdk_window_reparent:
1561 * @window: a #GdkWindow
1562 * @new_parent: new parent to move @window into
1563 * @x: X location inside the new parent
1564 * @y: Y location inside the new parent
1566 * Reparents @window into the given @new_parent. The window being
1567 * reparented will be unmapped as a side effect.
1571 gdk_window_reparent (GdkWindow *window,
1572 GdkWindow *new_parent,
1576 GdkWindowObject *private;
1577 GdkWindowObject *new_parent_private;
1578 GdkWindowObject *old_parent;
1580 gboolean show, was_mapped, applied_clip_as_shape;
1581 gboolean do_reparent_to_impl;
1582 GdkEventMask old_native_event_mask;
1583 GdkWindowImplIface *impl_iface;
1585 g_return_if_fail (GDK_IS_WINDOW (window));
1586 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1587 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1589 if (GDK_WINDOW_DESTROYED (window) ||
1590 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1593 screen = gdk_window_get_screen (window);
1595 new_parent = gdk_screen_get_root_window (screen);
1597 private = (GdkWindowObject *) window;
1598 new_parent_private = (GdkWindowObject *)new_parent;
1600 /* No input-output children of input-only windows */
1601 if (new_parent_private->input_only && !private->input_only)
1604 /* Don't create loops in hierarchy */
1605 if (is_parent_of (window, new_parent))
1608 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1609 To make sure we're ok, just wipe it. */
1610 gdk_window_drop_cairo_surface (private);
1612 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1613 old_parent = private->parent;
1615 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1618 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1619 if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1620 new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1621 gdk_window_ensure_native (window);
1623 applied_clip_as_shape = should_apply_clip_as_shape (private);
1625 old_native_event_mask = 0;
1626 do_reparent_to_impl = FALSE;
1627 if (gdk_window_has_impl (private))
1629 old_native_event_mask = get_native_event_mask (private);
1631 show = impl_iface->reparent (window, new_parent, x, y);
1635 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1636 g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1637 new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1640 gdk_window_hide (window);
1642 do_reparent_to_impl = TRUE;
1643 change_impl (private,
1644 new_parent_private->impl_window,
1645 new_parent_private->impl);
1648 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1651 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1653 new_parent = gdk_screen_get_root_window (screen);
1654 new_parent_private = (GdkWindowObject *)new_parent;
1658 old_parent->children = g_list_remove (old_parent->children, window);
1660 private->parent = new_parent_private;
1664 new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1666 /* Switch the window type as appropriate */
1668 switch (GDK_WINDOW_TYPE (new_parent))
1670 case GDK_WINDOW_ROOT:
1671 case GDK_WINDOW_FOREIGN:
1672 if (private->toplevel_window_type != -1)
1673 GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1674 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1675 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1677 case GDK_WINDOW_OFFSCREEN:
1678 case GDK_WINDOW_TOPLEVEL:
1679 case GDK_WINDOW_CHILD:
1680 case GDK_WINDOW_TEMP:
1681 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1682 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1684 /* Save the original window type so we can restore it if the
1685 * window is reparented back to be a toplevel
1687 private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1688 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1692 /* We might have changed window type for a native windows, so we
1693 need to change the event mask too. */
1694 if (gdk_window_has_impl (private))
1696 GdkEventMask native_event_mask = get_native_event_mask (private);
1698 if (native_event_mask != old_native_event_mask)
1699 impl_iface->set_events (window, native_event_mask);
1702 _gdk_window_update_viewable (window);
1704 recompute_visible_regions (private, TRUE, FALSE);
1705 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1706 recompute_visible_regions (old_parent, FALSE, TRUE);
1708 /* We used to apply the clip as the shape, but no more.
1709 Reset this to the real shape */
1710 if (gdk_window_has_impl (private) &&
1711 applied_clip_as_shape &&
1712 !should_apply_clip_as_shape (private))
1713 apply_shape (private, private->shape);
1715 if (do_reparent_to_impl)
1716 reparent_to_impl (private);
1719 /* The reparent will have put the native window topmost in the native parent,
1720 * which may be wrong wrt other native windows in the non-native hierarchy,
1722 if (!gdk_window_has_impl (new_parent_private))
1723 sync_native_window_stack_position (window);
1727 gdk_window_show_unraised (window);
1729 _gdk_synthesize_crossing_events_for_geometry_change (window);
1733 temporary_disable_extension_events (GdkWindowObject *window)
1735 GdkWindowObject *child;
1739 if (window->extension_events != 0)
1741 g_object_set_data (G_OBJECT (window),
1742 "gdk-window-extension-events",
1743 GINT_TO_POINTER (window->extension_events));
1744 gdk_input_set_extension_events ((GdkWindow *)window, 0,
1745 GDK_EXTENSION_EVENTS_NONE);
1750 for (l = window->children; l != NULL; l = l->next)
1754 if (window->impl_window == child->impl_window)
1755 res |= temporary_disable_extension_events (child);
1762 reenable_extension_events (GdkWindowObject *window)
1764 GdkWindowObject *child;
1768 mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1769 "gdk-window-extension-events"));
1773 /* We don't have the mode here, so we pass in cursor.
1774 This works with the current code since mode is not
1775 stored except as part of the mask, and cursor doesn't
1777 gdk_input_set_extension_events ((GdkWindow *)window, mask,
1778 GDK_EXTENSION_EVENTS_CURSOR);
1779 g_object_set_data (G_OBJECT (window),
1780 "gdk-window-extension-events",
1784 for (l = window->children; l != NULL; l = l->next)
1788 if (window->impl_window == child->impl_window)
1789 reenable_extension_events (window);
1794 * gdk_window_ensure_native:
1795 * @window: a #GdkWindow
1797 * Tries to ensure that there is a window-system native window for this
1798 * GdkWindow. This may fail in some situations, returning %FALSE.
1800 * Offscreen window and children of them can never have native windows.
1802 * Some backends may not support native child windows.
1804 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1809 gdk_window_ensure_native (GdkWindow *window)
1811 GdkWindowObject *private;
1812 GdkWindowObject *impl_window;
1813 GdkDrawable *new_impl, *old_impl;
1815 GdkWindowObject *above;
1817 GdkWindowImplIface *impl_iface;
1818 gboolean disabled_extension_events;
1820 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1822 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1823 GDK_WINDOW_DESTROYED (window))
1826 private = (GdkWindowObject *) window;
1828 impl_window = gdk_window_get_impl_window (private);
1830 if (gdk_window_is_offscreen (impl_window))
1831 return FALSE; /* native in offscreens not supported */
1833 if (impl_window == private)
1834 /* Already has an impl, and its not offscreen . */
1837 /* Need to create a native window */
1839 /* First we disable any extension events on the window or its
1840 descendants to handle the native input window moving */
1841 disabled_extension_events = FALSE;
1842 if (impl_window->input_window)
1843 disabled_extension_events = temporary_disable_extension_events (private);
1845 gdk_window_drop_cairo_surface (private);
1847 screen = gdk_window_get_screen (window);
1849 old_impl = private->impl;
1850 _gdk_window_impl_new (window, (GdkWindow *)private->parent,
1852 get_native_event_mask (private),
1854 new_impl = private->impl;
1856 private->impl = old_impl;
1857 change_impl (private, private, new_impl);
1859 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1861 /* Native window creation will put the native window topmost in the
1862 * native parent, which may be wrong wrt the position of the previous
1863 * non-native window wrt to the other non-native children, so correct this.
1865 above = find_native_sibling_above (private->parent, private);
1868 listhead.data = window;
1869 listhead.prev = NULL;
1870 listhead.next = NULL;
1871 impl_iface->restack_under ((GdkWindow *)above, &listhead);
1874 recompute_visible_regions (private, FALSE, FALSE);
1876 /* The shape may not have been set, as the clip region doesn't actually
1877 change, so do it here manually */
1878 if (should_apply_clip_as_shape (private))
1879 apply_clip_as_shape (private);
1881 reparent_to_impl (private);
1883 if (!private->input_only)
1885 impl_iface->set_background (window, private->background);
1888 impl_iface->input_shape_combine_region (window,
1889 private->input_shape,
1892 if (gdk_window_is_viewable (window))
1893 impl_iface->show (window, FALSE);
1895 if (disabled_extension_events)
1896 reenable_extension_events (private);
1902 window_remove_filters (GdkWindow *window)
1904 GdkWindowObject *obj = (GdkWindowObject*) window;
1910 for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
1911 g_free (tmp_list->data);
1913 g_list_free (obj->filters);
1914 obj->filters = NULL;
1919 update_pointer_info_foreach (GdkDisplay *display,
1921 GdkPointerWindowInfo *pointer_info,
1924 GdkWindow *window = user_data;
1926 if (pointer_info->toplevel_under_pointer == window)
1928 g_object_unref (pointer_info->toplevel_under_pointer);
1929 pointer_info->toplevel_under_pointer = NULL;
1934 window_remove_from_pointer_info (GdkWindow *window,
1935 GdkDisplay *display)
1937 _gdk_display_pointer_info_foreach (display,
1938 update_pointer_info_foreach,
1943 * _gdk_window_destroy_hierarchy:
1944 * @window: a #GdkWindow
1945 * @recursing: If TRUE, then this is being called because a parent
1947 * @recursing_native: If TRUE, then this is being called because a native parent
1948 * was destroyed. This generally means that the call to the
1949 * windowing system to destroy the window can be omitted, since
1950 * it will be destroyed as a result of the parent being destroyed.
1951 * Unless @foreign_destroy.
1952 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1953 * external agency. The window has already been destroyed and no
1954 * windowing system calls should be made. (This may never happen
1955 * for some windowing systems.)
1957 * Internal function to destroy a window. Like gdk_window_destroy(),
1958 * but does not drop the reference count created by gdk_window_new().
1961 _gdk_window_destroy_hierarchy (GdkWindow *window,
1963 gboolean recursing_native,
1964 gboolean foreign_destroy)
1966 GdkWindowObject *private;
1967 GdkWindowObject *temp_private;
1968 GdkWindowImplIface *impl_iface;
1969 GdkWindow *temp_window;
1971 GdkDisplay *display;
1975 g_return_if_fail (GDK_IS_WINDOW (window));
1977 private = (GdkWindowObject*) window;
1979 if (GDK_WINDOW_DESTROYED (window))
1982 display = gdk_window_get_display (window);
1983 screen = gdk_window_get_screen (window);
1984 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1985 if (temp_window == window)
1986 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1989 switch (private->window_type)
1991 case GDK_WINDOW_ROOT:
1992 if (!screen->closed)
1994 g_error ("attempted to destroy root window");
1997 /* else fall thru */
1998 case GDK_WINDOW_TOPLEVEL:
1999 case GDK_WINDOW_CHILD:
2000 case GDK_WINDOW_TEMP:
2001 case GDK_WINDOW_FOREIGN:
2002 case GDK_WINDOW_OFFSCREEN:
2003 if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
2005 /* Logically, it probably makes more sense to send
2006 * a "destroy yourself" message to the foreign window
2007 * whether or not it's in our hierarchy; but for historical
2008 * reasons, we only send "destroy yourself" messages to
2009 * foreign windows in our hierarchy.
2011 if (private->parent)
2012 _gdk_windowing_window_destroy_foreign (window);
2014 /* Also for historical reasons, we remove any filters
2015 * on a foreign window when it or a parent is destroyed;
2016 * this likely causes problems if two separate portions
2017 * of code are maintaining filter lists on a foreign window.
2019 window_remove_filters (window);
2023 if (private->parent)
2025 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
2027 if (parent_private->children)
2028 parent_private->children = g_list_remove (parent_private->children, window);
2031 GDK_WINDOW_IS_MAPPED (window))
2033 recompute_visible_regions (private, TRUE, FALSE);
2034 gdk_window_invalidate_in_parent (private);
2038 gdk_window_free_paint_stack (window);
2040 if (private->background)
2042 cairo_pattern_destroy (private->background);
2043 private->background = NULL;
2046 if (private->window_type == GDK_WINDOW_FOREIGN)
2047 g_assert (private->children == NULL);
2050 children = tmp = private->children;
2051 private->children = NULL;
2055 temp_window = tmp->data;
2058 temp_private = (GdkWindowObject*) temp_window;
2060 _gdk_window_destroy_hierarchy (temp_window,
2062 recursing_native || gdk_window_has_impl (private),
2066 g_list_free (children);
2069 _gdk_window_clear_update_area (window);
2071 gdk_window_drop_cairo_surface (private);
2073 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2075 if (gdk_window_has_impl (private))
2076 impl_iface->destroy (window, recursing_native,
2080 /* hide to make sure we repaint and break grabs */
2081 gdk_window_hide (window);
2084 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2085 private->parent = NULL;
2086 private->destroyed = TRUE;
2088 window_remove_filters (window);
2090 window_remove_from_pointer_info (window, display);
2092 if (private->clip_region)
2094 cairo_region_destroy (private->clip_region);
2095 private->clip_region = NULL;
2098 if (private->clip_region_with_children)
2100 cairo_region_destroy (private->clip_region_with_children);
2101 private->clip_region_with_children = NULL;
2104 if (private->outstanding_moves)
2106 g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2107 g_list_free (private->outstanding_moves);
2108 private->outstanding_moves = NULL;
2116 * _gdk_window_destroy:
2117 * @window: a #GdkWindow
2118 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2119 * external agency. The window has already been destroyed and no
2120 * windowing system calls should be made. (This may never happen
2121 * for some windowing systems.)
2123 * Internal function to destroy a window. Like gdk_window_destroy(),
2124 * but does not drop the reference count created by gdk_window_new().
2127 _gdk_window_destroy (GdkWindow *window,
2128 gboolean foreign_destroy)
2130 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2134 * gdk_window_destroy:
2135 * @window: a #GdkWindow
2137 * Destroys the window system resources associated with @window and decrements @window's
2138 * reference count. The window system resources for all children of @window are also
2139 * destroyed, but the children's reference counts are not decremented.
2141 * Note that a window will not be destroyed automatically when its reference count
2142 * reaches zero. You must call this function yourself before that happens.
2146 gdk_window_destroy (GdkWindow *window)
2148 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2149 g_object_unref (window);
2153 * gdk_window_set_user_data:
2154 * @window: a #GdkWindow
2155 * @user_data: user data
2157 * For most purposes this function is deprecated in favor of
2158 * g_object_set_data(). However, for historical reasons GTK+ stores
2159 * the #GtkWidget that owns a #GdkWindow as user data on the
2160 * #GdkWindow. So, custom widget implementations should use
2161 * this function for that. If GTK+ receives an event for a #GdkWindow,
2162 * and the user data for the window is non-%NULL, GTK+ will assume the
2163 * user data is a #GtkWidget, and forward the event to that widget.
2167 gdk_window_set_user_data (GdkWindow *window,
2170 g_return_if_fail (GDK_IS_WINDOW (window));
2172 ((GdkWindowObject*)window)->user_data = user_data;
2176 * gdk_window_get_user_data:
2177 * @window: a #GdkWindow
2178 * @data: return location for user data
2180 * Retrieves the user data for @window, which is normally the widget
2181 * that @window belongs to. See gdk_window_set_user_data().
2185 gdk_window_get_user_data (GdkWindow *window,
2188 g_return_if_fail (GDK_IS_WINDOW (window));
2190 *data = ((GdkWindowObject*)window)->user_data;
2194 * gdk_window_get_window_type:
2195 * @window: a #GdkWindow
2197 * Gets the type of the window. See #GdkWindowType.
2199 * Return value: type of window
2202 gdk_window_get_window_type (GdkWindow *window)
2204 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2206 return GDK_WINDOW_TYPE (window);
2210 * gdk_window_get_visual:
2211 * @window: a #GdkWindow
2213 * Gets the #GdkVisual describing the pixel format of @window.
2215 * Return value: (transfer none): a #GdkVisual
2220 gdk_window_get_visual (GdkWindow *window)
2222 GdkWindowObject *private;
2224 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2226 private = (GdkWindowObject *) window;
2228 return private->visual;
2232 * gdk_window_get_screen:
2233 * @window: a #GdkWindow
2235 * Gets the #GdkScreen associated with a #GdkWindow.
2237 * Return value: (transfer none): the #GdkScreen associated with @window
2242 gdk_window_get_screen (GdkWindow *window)
2244 GdkWindowObject *private;
2246 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2248 private = (GdkWindowObject *) window;
2250 return gdk_visual_get_screen (private->visual);
2254 * gdk_window_get_display:
2255 * @window: a #GdkWindow
2257 * Gets the #GdkDisplay associated with a #GdkWindow.
2259 * Return value: (transfer none): the #GdkDisplay associated with @window
2264 gdk_window_get_display (GdkWindow *window)
2266 GdkWindowObject *private;
2268 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2270 private = (GdkWindowObject *) window;
2272 return gdk_screen_get_display (gdk_visual_get_screen (private->visual));
2275 * gdk_window_is_destroyed:
2276 * @window: a #GdkWindow
2278 * Check to see if a window is destroyed..
2280 * Return value: %TRUE if the window is destroyed
2285 gdk_window_is_destroyed (GdkWindow *window)
2287 return GDK_WINDOW_DESTROYED (window);
2291 to_embedder (GdkWindowObject *window,
2292 gdouble offscreen_x,
2293 gdouble offscreen_y,
2294 gdouble *embedder_x,
2295 gdouble *embedder_y)
2297 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2298 offscreen_x, offscreen_y,
2299 embedder_x, embedder_y);
2303 from_embedder (GdkWindowObject *window,
2306 gdouble *offscreen_x,
2307 gdouble *offscreen_y)
2309 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2310 embedder_x, embedder_y,
2311 offscreen_x, offscreen_y);
2315 * gdk_window_has_native:
2316 * @window: a #GdkWindow
2318 * Checks whether the window has a native window or not. Note that
2319 * you can use gdk_window_ensure_native() if a native window is needed.
2321 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2326 gdk_window_has_native (GdkWindow *window)
2330 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2332 w = GDK_WINDOW_OBJECT (window);
2334 return w->parent == NULL || w->parent->impl != w->impl;
2338 * gdk_window_get_position:
2339 * @window: a #GdkWindow
2340 * @x: X coordinate of window
2341 * @y: Y coordinate of window
2343 * Obtains the position of the window as reported in the
2344 * most-recently-processed #GdkEventConfigure. Contrast with
2345 * gdk_window_get_geometry() which queries the X server for the
2346 * current window position, regardless of which events have been
2347 * received or processed.
2349 * The position coordinates are relative to the window's parent window.
2353 gdk_window_get_position (GdkWindow *window,
2357 GdkWindowObject *obj;
2359 g_return_if_fail (GDK_IS_WINDOW (window));
2361 obj = (GdkWindowObject*) window;
2370 * gdk_window_get_parent:
2371 * @window: a #GdkWindow
2373 * Obtains the parent of @window, as known to GDK. Does not query the
2374 * X server; thus this returns the parent as passed to gdk_window_new(),
2375 * not the actual parent. This should never matter unless you're using
2376 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2377 * matter for toplevel windows, because the window manager may choose
2380 * Note that you should use gdk_window_get_effective_parent() when
2381 * writing generic code that walks up a window hierarchy, because
2382 * gdk_window_get_parent() will most likely not do what you expect if
2383 * there are offscreen windows in the hierarchy.
2385 * Return value: (transfer none): parent of @window
2388 gdk_window_get_parent (GdkWindow *window)
2390 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2392 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2396 * gdk_window_get_effective_parent:
2397 * @window: a #GdkWindow
2399 * Obtains the parent of @window, as known to GDK. Works like
2400 * gdk_window_get_parent() for normal windows, but returns the
2401 * window's embedder for offscreen windows.
2403 * See also: gdk_offscreen_window_get_embedder()
2405 * Return value: (transfer none): effective parent of @window
2410 gdk_window_get_effective_parent (GdkWindow *window)
2412 GdkWindowObject *obj;
2414 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2416 obj = (GdkWindowObject *)window;
2418 if (gdk_window_is_offscreen (obj))
2419 return gdk_offscreen_window_get_embedder (window);
2421 return (GdkWindow *) obj->parent;
2425 * gdk_window_get_toplevel:
2426 * @window: a #GdkWindow
2428 * Gets the toplevel window that's an ancestor of @window.
2430 * Any window type but %GDK_WINDOW_CHILD is considered a
2431 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2432 * has a root window as parent.
2434 * Note that you should use gdk_window_get_effective_toplevel() when
2435 * you want to get to a window's toplevel as seen on screen, because
2436 * gdk_window_get_toplevel() will most likely not do what you expect
2437 * if there are offscreen windows in the hierarchy.
2439 * Return value: (transfer none): the toplevel window containing @window
2442 gdk_window_get_toplevel (GdkWindow *window)
2444 GdkWindowObject *obj;
2446 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2448 obj = (GdkWindowObject *)window;
2450 while (obj->window_type == GDK_WINDOW_CHILD)
2452 if (gdk_window_is_toplevel (obj))
2457 return GDK_WINDOW (obj);
2461 * gdk_window_get_effective_toplevel:
2462 * @window: a #GdkWindow
2464 * Gets the toplevel window that's an ancestor of @window.
2466 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2467 * embedder as its parent, using gdk_window_get_effective_parent().
2469 * See also: gdk_offscreen_window_get_embedder()
2471 * Return value: (transfer none): the effective toplevel window containing @window
2476 gdk_window_get_effective_toplevel (GdkWindow *window)
2480 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2482 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2483 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2490 * gdk_window_get_children:
2491 * @window: a #GdkWindow
2493 * Gets the list of children of @window known to GDK.
2494 * This function only returns children created via GDK,
2495 * so for example it's useless when used with the root window;
2496 * it only returns windows an application created itself.
2498 * The returned list must be freed, but the elements in the
2501 * Return value: (transfer container) (element-type GdkWindow):
2502 * list of child windows inside @window
2505 gdk_window_get_children (GdkWindow *window)
2507 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2509 if (GDK_WINDOW_DESTROYED (window))
2512 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2516 * gdk_window_peek_children:
2517 * @window: a #GdkWindow
2519 * Like gdk_window_get_children(), but does not copy the list of
2520 * children, so the list does not need to be freed.
2522 * Return value: (transfer none) (element-type GdkWindow):
2523 * a reference to the list of child windows in @window
2526 gdk_window_peek_children (GdkWindow *window)
2528 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2530 if (GDK_WINDOW_DESTROYED (window))
2533 return GDK_WINDOW_OBJECT (window)->children;
2537 * gdk_window_add_filter:
2538 * @window: a #GdkWindow
2539 * @function: filter callback
2540 * @data: data to pass to filter callback
2542 * Adds an event filter to @window, allowing you to intercept events
2543 * before they reach GDK. This is a low-level operation and makes it
2544 * easy to break GDK and/or GTK+, so you have to know what you're
2545 * doing. Pass %NULL for @window to get all events for all windows,
2546 * instead of events for a specific window.
2548 * See gdk_display_add_client_message_filter() if you are interested
2549 * in X ClientMessage events.
2552 gdk_window_add_filter (GdkWindow *window,
2553 GdkFilterFunc function,
2556 GdkWindowObject *private;
2558 GdkEventFilter *filter;
2560 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2562 private = (GdkWindowObject*) window;
2563 if (private && GDK_WINDOW_DESTROYED (window))
2566 /* Filters are for the native events on the native window, so
2567 ensure there is a native window. */
2569 gdk_window_ensure_native (window);
2572 tmp_list = private->filters;
2574 tmp_list = _gdk_default_filters;
2578 filter = (GdkEventFilter *)tmp_list->data;
2579 if ((filter->function == function) && (filter->data == data))
2581 filter->ref_count++;
2584 tmp_list = tmp_list->next;
2587 filter = g_new (GdkEventFilter, 1);
2588 filter->function = function;
2589 filter->data = data;
2590 filter->ref_count = 1;
2594 private->filters = g_list_append (private->filters, filter);
2596 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2600 * gdk_window_remove_filter:
2601 * @window: a #GdkWindow
2602 * @function: previously-added filter function
2603 * @data: user data for previously-added filter function
2605 * Remove a filter previously added with gdk_window_add_filter().
2609 gdk_window_remove_filter (GdkWindow *window,
2610 GdkFilterFunc function,
2613 GdkWindowObject *private;
2614 GList *tmp_list, *node;
2615 GdkEventFilter *filter;
2617 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2619 private = (GdkWindowObject*) window;
2622 tmp_list = private->filters;
2624 tmp_list = _gdk_default_filters;
2628 filter = (GdkEventFilter *)tmp_list->data;
2630 tmp_list = tmp_list->next;
2632 if ((filter->function == function) && (filter->data == data))
2634 filter->flags |= GDK_EVENT_FILTER_REMOVED;
2635 filter->ref_count--;
2636 if (filter->ref_count != 0)
2640 private->filters = g_list_remove_link (private->filters, node);
2642 _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
2643 g_list_free_1 (node);
2652 * gdk_screen_get_toplevel_windows:
2653 * @screen: The #GdkScreen where the toplevels are located.
2655 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2656 * A toplevel window is a child of the root window (see
2657 * gdk_get_default_root_window()).
2659 * The returned list should be freed with g_list_free(), but
2660 * its elements need not be freed.
2662 * Return value: (transfer container) (element-type GdkWindow):
2663 * list of toplevel windows, free with g_list_free()
2668 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2670 GdkWindow * root_window;
2671 GList *new_list = NULL;
2674 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2676 root_window = gdk_screen_get_root_window (screen);
2678 tmp_list = ((GdkWindowObject *)root_window)->children;
2681 GdkWindowObject *w = tmp_list->data;
2683 if (w->window_type != GDK_WINDOW_FOREIGN)
2684 new_list = g_list_prepend (new_list, w);
2685 tmp_list = tmp_list->next;
2692 * gdk_window_is_visible:
2693 * @window: a #GdkWindow
2695 * Checks whether the window has been mapped (with gdk_window_show() or
2696 * gdk_window_show_unraised()).
2698 * Return value: %TRUE if the window is mapped
2701 gdk_window_is_visible (GdkWindow *window)
2703 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2705 return GDK_WINDOW_IS_MAPPED (window);
2709 * gdk_window_is_viewable:
2710 * @window: a #GdkWindow
2712 * Check if the window and all ancestors of the window are
2713 * mapped. (This is not necessarily "viewable" in the X sense, since
2714 * we only check as far as we have GDK window parents, not to the root
2717 * Return value: %TRUE if the window is viewable
2720 gdk_window_is_viewable (GdkWindow *window)
2722 GdkWindowObject *private = (GdkWindowObject *)window;
2724 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2726 if (private->destroyed)
2729 return private->viewable;
2733 * gdk_window_get_state:
2734 * @window: a #GdkWindow
2736 * Gets the bitwise OR of the currently active window state flags,
2737 * from the #GdkWindowState enumeration.
2739 * Return value: window state bitfield
2742 gdk_window_get_state (GdkWindow *window)
2744 GdkWindowObject *private = (GdkWindowObject *)window;
2746 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2748 return private->state;
2751 static cairo_content_t
2752 gdk_window_get_content (GdkWindow *window)
2754 cairo_surface_t *surface;
2755 cairo_content_t content;
2757 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2759 surface = _gdk_drawable_ref_cairo_surface (window);
2760 content = cairo_surface_get_content (surface);
2761 cairo_surface_destroy (surface);
2766 /* This creates an empty "implicit" paint region for the impl window.
2767 * By itself this does nothing, but real paints to this window
2768 * or children of it can use this surface as backing to avoid allocating
2769 * multiple surfaces for subwindow rendering. When doing so they
2770 * add to the region of the implicit paint region, which will be
2771 * pushed to the window when the implicit paint region is ended.
2772 * Such paints should not copy anything to the window on paint end, but
2773 * should rely on the implicit paint end.
2774 * The implicit paint will be automatically ended if someone draws
2775 * directly to the window or a child window.
2778 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2780 GdkWindowObject *private = (GdkWindowObject *)window;
2781 GdkWindowPaint *paint;
2783 g_assert (gdk_window_has_impl (private));
2785 if (_gdk_native_windows)
2786 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2788 if (GDK_IS_PAINTABLE (private->impl))
2789 return FALSE; /* Implementation does double buffering */
2791 if (private->paint_stack != NULL ||
2792 private->implicit_paint != NULL)
2793 return FALSE; /* Don't stack implicit paints */
2795 if (private->outstanding_surfaces != 0)
2796 return FALSE; /* May conflict with direct drawing to cairo surface */
2798 /* Never do implicit paints for foreign windows, they don't need
2799 * double buffer combination since they have no client side children,
2800 * and creating surfaces for them is risky since they could disappear
2803 if (private->window_type == GDK_WINDOW_FOREIGN)
2806 paint = g_new (GdkWindowPaint, 1);
2807 paint->region = cairo_region_create (); /* Empty */
2808 paint->uses_implicit = FALSE;
2809 paint->flushed = FALSE;
2810 paint->surface = gdk_window_create_similar_surface (window,
2811 gdk_window_get_content (window),
2812 MAX (rect->width, 1),
2813 MAX (rect->height, 1));
2814 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2816 private->implicit_paint = paint;
2821 /* Ensure that all content related to this (sub)window is pushed to the
2822 native region. If there is an active paint then that area is not
2823 pushed, in order to not show partially finished double buffers. */
2825 gdk_window_flush_implicit_paint (GdkWindow *window)
2827 GdkWindowObject *private = (GdkWindowObject *)window;
2828 GdkWindowObject *impl_window;
2829 GdkWindowPaint *paint;
2830 cairo_region_t *region;
2833 impl_window = gdk_window_get_impl_window (private);
2834 if (impl_window->implicit_paint == NULL)
2837 paint = impl_window->implicit_paint;
2838 paint->flushed = TRUE;
2839 region = cairo_region_copy (private->clip_region_with_children);
2841 /* Don't flush active double buffers, as that may show partially done
2843 for (list = private->paint_stack; list != NULL; list = list->next)
2845 GdkWindowPaint *tmp_paint = list->data;
2847 cairo_region_subtract (region, tmp_paint->region);
2850 cairo_region_translate (region, -private->abs_x, -private->abs_y);
2851 cairo_region_intersect (region, paint->region);
2853 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2857 /* Remove flushed region from the implicit paint */
2858 cairo_region_subtract (paint->region, region);
2860 /* Some regions are valid, push these to window now */
2861 cr = gdk_cairo_create (private->impl);
2862 gdk_cairo_region (cr, region);
2864 cairo_set_source_surface (cr, paint->surface, 0, 0);
2865 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2870 cairo_region_destroy (region);
2873 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2875 gdk_window_end_implicit_paint (GdkWindow *window)
2877 GdkWindowObject *private = (GdkWindowObject *)window;
2878 GdkWindowPaint *paint;
2880 g_assert (gdk_window_has_impl (private));
2882 g_assert (private->implicit_paint != NULL);
2884 paint = private->implicit_paint;
2886 private->implicit_paint = NULL;
2888 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2892 /* Some regions are valid, push these to window now */
2893 cr = gdk_cairo_create (private->impl);
2894 gdk_cairo_region (cr, paint->region);
2896 cairo_set_source_surface (cr, paint->surface, 0, 0);
2897 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2902 cairo_region_destroy (paint->region);
2904 cairo_surface_destroy (paint->surface);
2909 * gdk_window_begin_paint_rect:
2910 * @window: a #GdkWindow
2911 * @rectangle: rectangle you intend to draw to
2913 * A convenience wrapper around gdk_window_begin_paint_region() which
2914 * creates a rectangular region for you. See
2915 * gdk_window_begin_paint_region() for details.
2919 gdk_window_begin_paint_rect (GdkWindow *window,
2920 const GdkRectangle *rectangle)
2922 cairo_region_t *region;
2924 g_return_if_fail (GDK_IS_WINDOW (window));
2926 region = cairo_region_create_rectangle (rectangle);
2927 gdk_window_begin_paint_region (window, region);
2928 cairo_region_destroy (region);
2932 * gdk_window_begin_paint_region:
2933 * @window: a #GdkWindow
2934 * @region: region you intend to draw to
2936 * Indicates that you are beginning the process of redrawing @region.
2937 * A backing store (offscreen buffer) large enough to contain @region
2938 * will be created. The backing store will be initialized with the
2939 * background color or background surface for @window. Then, all
2940 * drawing operations performed on @window will be diverted to the
2941 * backing store. When you call gdk_window_end_paint(), the backing
2942 * store will be copied to @window, making it visible onscreen. Only
2943 * the part of @window contained in @region will be modified; that is,
2944 * drawing operations are clipped to @region.
2946 * The net result of all this is to remove flicker, because the user
2947 * sees the finished product appear all at once when you call
2948 * gdk_window_end_paint(). If you draw to @window directly without
2949 * calling gdk_window_begin_paint_region(), the user may see flicker
2950 * as individual drawing operations are performed in sequence. The
2951 * clipping and background-initializing features of
2952 * gdk_window_begin_paint_region() are conveniences for the
2953 * programmer, so you can avoid doing that work yourself.
2955 * When using GTK+, the widget system automatically places calls to
2956 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2957 * emissions of the expose_event signal. That is, if you're writing an
2958 * expose event handler, you can assume that the exposed area in
2959 * #GdkEventExpose has already been cleared to the window background,
2960 * is already set as the clip region, and already has a backing store.
2961 * Therefore in most cases, application code need not call
2962 * gdk_window_begin_paint_region(). (You can disable the automatic
2963 * calls around expose events on a widget-by-widget basis by calling
2964 * gtk_widget_set_double_buffered().)
2966 * If you call this function multiple times before calling the
2967 * matching gdk_window_end_paint(), the backing stores are pushed onto
2968 * a stack. gdk_window_end_paint() copies the topmost backing store
2969 * onscreen, subtracts the topmost region from all other regions in
2970 * the stack, and pops the stack. All drawing operations affect only
2971 * the topmost backing store in the stack. One matching call to
2972 * gdk_window_end_paint() is required for each call to
2973 * gdk_window_begin_paint_region().
2977 gdk_window_begin_paint_region (GdkWindow *window,
2978 const cairo_region_t *region)
2980 #ifdef USE_BACKING_STORE
2981 GdkWindowObject *private = (GdkWindowObject *)window;
2982 GdkRectangle clip_box;
2983 GdkWindowPaint *paint, *implicit_paint;
2984 GdkWindowObject *impl_window;
2987 g_return_if_fail (GDK_IS_WINDOW (window));
2989 if (GDK_WINDOW_DESTROYED (window))
2992 if (GDK_IS_PAINTABLE (private->impl))
2994 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
2996 if (iface->begin_paint_region)
2997 iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
3002 impl_window = gdk_window_get_impl_window (private);
3003 implicit_paint = impl_window->implicit_paint;
3005 paint = g_new (GdkWindowPaint, 1);
3006 paint->region = cairo_region_copy (region);
3007 paint->region_tag = new_region_tag ();
3009 cairo_region_intersect (paint->region, private->clip_region_with_children);
3010 cairo_region_get_extents (paint->region, &clip_box);
3012 cairo_region_translate (paint->region, private->abs_x, private->abs_y);
3014 /* Mark the region as valid on the implicit paint */
3017 cairo_region_union (implicit_paint->region, paint->region);
3019 /* Convert back to normal coords */
3020 cairo_region_translate (paint->region, -private->abs_x, -private->abs_y);
3024 paint->uses_implicit = TRUE;
3025 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
3026 private->abs_x + clip_box.x,
3027 private->abs_y + clip_box.y,
3028 MAX (clip_box.width, 1),
3029 MAX (clip_box.height, 1));
3033 paint->uses_implicit = FALSE;
3034 paint->surface = gdk_window_create_similar_surface (window,
3035 gdk_window_get_content (window),
3036 MAX (clip_box.width, 1),
3037 MAX (clip_box.height, 1));
3039 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
3041 for (list = private->paint_stack; list != NULL; list = list->next)
3043 GdkWindowPaint *tmp_paint = list->data;
3045 cairo_region_subtract (tmp_paint->region, paint->region);
3048 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
3050 if (!cairo_region_is_empty (paint->region))
3052 gdk_window_clear_backing_region (window,
3056 #endif /* USE_BACKING_STORE */
3060 * gdk_window_end_paint:
3061 * @window: a #GdkWindow
3063 * Indicates that the backing store created by the most recent call to
3064 * gdk_window_begin_paint_region() should be copied onscreen and
3065 * deleted, leaving the next-most-recent backing store or no backing
3066 * store at all as the active paint region. See
3067 * gdk_window_begin_paint_region() for full details. It is an error to
3068 * call this function without a matching
3069 * gdk_window_begin_paint_region() first.
3073 gdk_window_end_paint (GdkWindow *window)
3075 #ifdef USE_BACKING_STORE
3076 GdkWindowObject *private = (GdkWindowObject *)window;
3077 GdkWindowObject *composited;
3078 GdkWindowPaint *paint;
3079 GdkRectangle clip_box;
3080 cairo_region_t *full_clip;
3082 g_return_if_fail (GDK_IS_WINDOW (window));
3084 if (GDK_WINDOW_DESTROYED (window))
3087 if (GDK_IS_PAINTABLE (private->impl))
3089 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3091 if (iface->end_paint)
3092 iface->end_paint ((GdkPaintable*)private->impl);
3096 if (private->paint_stack == NULL)
3098 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3102 paint = private->paint_stack->data;
3104 private->paint_stack = g_slist_delete_link (private->paint_stack,
3105 private->paint_stack);
3107 cairo_region_get_extents (paint->region, &clip_box);
3109 if (!paint->uses_implicit)
3113 gdk_window_flush_outstanding_moves (window);
3115 full_clip = cairo_region_copy (private->clip_region_with_children);
3116 cairo_region_intersect (full_clip, paint->region);
3118 cr = gdk_cairo_create (window);
3119 cairo_set_source_surface (cr, paint->surface, 0, 0);
3120 gdk_cairo_region (cr, full_clip);
3124 cairo_region_destroy (full_clip);
3127 cairo_surface_destroy (paint->surface);
3128 cairo_region_destroy (paint->region);
3131 /* find a composited window in our hierarchy to signal its
3132 * parent to redraw, calculating the clip box as we go...
3134 * stop if parent becomes NULL since then we'd have nowhere
3135 * to draw (ie: 'composited' will always be non-NULL here).
3137 for (composited = private;
3139 composited = composited->parent)
3141 clip_box.x += composited->x;
3142 clip_box.y += composited->y;
3143 clip_box.width = MIN (clip_box.width, composited->parent->width - clip_box.x);
3144 clip_box.height = MIN (clip_box.height, composited->parent->height - clip_box.y);
3146 if (composited->composited)
3148 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3153 #endif /* USE_BACKING_STORE */
3157 gdk_window_free_paint_stack (GdkWindow *window)
3159 GdkWindowObject *private = (GdkWindowObject *)window;
3161 if (private->paint_stack)
3163 GSList *tmp_list = private->paint_stack;
3167 GdkWindowPaint *paint = tmp_list->data;
3169 if (tmp_list == private->paint_stack)
3170 cairo_surface_destroy (paint->surface);
3172 cairo_region_destroy (paint->region);
3175 tmp_list = tmp_list->next;
3178 g_slist_free (private->paint_stack);
3179 private->paint_stack = NULL;
3184 do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3185 cairo_region_t *dest_region, /* In impl window coords */
3188 GdkWindowImplIface *impl_iface;
3190 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (impl_window->impl);
3192 impl_iface->translate ((GdkWindow *) impl_window, dest_region, dx, dy);
3195 static GdkWindowRegionMove *
3196 gdk_window_region_move_new (cairo_region_t *region,
3199 GdkWindowRegionMove *move;
3201 move = g_slice_new (GdkWindowRegionMove);
3202 move->dest_region = cairo_region_copy (region);
3210 gdk_window_region_move_free (GdkWindowRegionMove *move)
3212 cairo_region_destroy (move->dest_region);
3213 g_slice_free (GdkWindowRegionMove, move);
3217 append_move_region (GdkWindowObject *impl_window,
3218 cairo_region_t *new_dest_region,
3221 GdkWindowRegionMove *move, *old_move;
3222 cairo_region_t *new_total_region, *old_total_region;
3223 cairo_region_t *source_overlaps_destination;
3224 cairo_region_t *non_overwritten;
3225 gboolean added_move;
3228 if (cairo_region_is_empty (new_dest_region))
3231 /* In principle this could just append the move to the list of outstanding
3232 moves that will be replayed before drawing anything when we're handling
3233 exposes. However, we'd like to do a bit better since its commonly the case
3234 that we get multiple copies where A is copied to B and then B is copied
3235 to C, and we'd like to express this as a simple copy A to C operation. */
3237 /* We approach this by taking the new move and pushing it ahead of moves
3238 starting at the end of the list and stopping when its not safe to do so.
3239 It's not safe to push past a move if either the source of the new move
3240 is in the destination of the old move, or if the destination of the new
3241 move is in the source of the new move, or if the destination of the new
3242 move overlaps the destination of the old move. We simplify this by
3243 just comparing the total regions (src + dest) */
3244 new_total_region = cairo_region_copy (new_dest_region);
3245 cairo_region_translate (new_total_region, -dx, -dy);
3246 cairo_region_union (new_total_region, new_dest_region);
3249 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3254 old_total_region = cairo_region_copy (old_move->dest_region);
3255 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3256 cairo_region_union (old_total_region, old_move->dest_region);
3258 cairo_region_intersect (old_total_region, new_total_region);
3259 /* If these regions intersect then its not safe to push the
3260 new region before the old one */
3261 if (!cairo_region_is_empty (old_total_region))
3263 /* The area where the new moves source overlaps the old ones
3265 source_overlaps_destination = cairo_region_copy (new_dest_region);
3266 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3267 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3268 cairo_region_translate (source_overlaps_destination, dx, dy);
3270 /* We can do all sort of optimizations here, but to do things safely it becomes
3271 quite complicated. However, a very common case is that you copy something first,
3272 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3273 in the same direction). We'd like to detect this case and optimize it to one
3275 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3277 /* This means we might be able to replace the old move and the new one
3278 with the new one read from the old ones source, and a second copy of
3279 the non-overwritten parts of the old move. However, such a split
3280 is only valid if the source in the old move isn't overwritten
3281 by the destination of the new one */
3283 /* the new destination of old move if split is ok: */
3284 non_overwritten = cairo_region_copy (old_move->dest_region);
3285 cairo_region_subtract (non_overwritten, new_dest_region);
3286 /* move to source region */
3287 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3289 cairo_region_intersect (non_overwritten, new_dest_region);
3290 if (cairo_region_is_empty (non_overwritten))
3293 move = gdk_window_region_move_new (new_dest_region,
3297 impl_window->outstanding_moves =
3298 g_list_insert_before (impl_window->outstanding_moves,
3300 cairo_region_subtract (old_move->dest_region, new_dest_region);
3302 cairo_region_destroy (non_overwritten);
3305 cairo_region_destroy (source_overlaps_destination);
3306 cairo_region_destroy (old_total_region);
3309 cairo_region_destroy (old_total_region);
3312 cairo_region_destroy (new_total_region);
3316 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3319 impl_window->outstanding_moves =
3320 g_list_prepend (impl_window->outstanding_moves,
3323 impl_window->outstanding_moves =
3324 g_list_insert_before (impl_window->outstanding_moves,
3329 /* Moves bits and update area by dx/dy in impl window.
3330 Takes ownership of region to avoid copy (because we may change it) */
3332 move_region_on_impl (GdkWindowObject *impl_window,
3333 cairo_region_t *region, /* In impl window coords */
3336 if ((dx == 0 && dy == 0) ||
3337 cairo_region_is_empty (region))
3339 cairo_region_destroy (region);
3343 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3345 /* Move any old invalid regions in the copy source area by dx/dy */
3346 if (impl_window->update_area)
3348 cairo_region_t *update_area;
3350 update_area = cairo_region_copy (region);
3352 /* Convert from target to source */
3353 cairo_region_translate (update_area, -dx, -dy);
3354 cairo_region_intersect (update_area, impl_window->update_area);
3355 /* We only copy the area, so keep the old update area invalid.
3356 It would be safe to remove it too, as code that uses
3357 move_region_on_impl generally also invalidate the source
3358 area. However, it would just use waste cycles. */
3361 cairo_region_translate (update_area, dx, dy);
3362 cairo_region_union (impl_window->update_area, update_area);
3364 /* This area of the destination is now invalid,
3365 so no need to copy to it. */
3366 cairo_region_subtract (region, update_area);
3368 cairo_region_destroy (update_area);
3371 /* If we're currently exposing this window, don't copy to this
3372 destination, as it will be overdrawn when the expose is done,
3373 instead invalidate it and repaint later. */
3374 if (impl_window->implicit_paint)
3376 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3377 cairo_region_t *exposing;
3379 exposing = cairo_region_copy (implicit_paint->region);
3380 cairo_region_intersect (exposing, region);
3381 cairo_region_subtract (region, exposing);
3383 impl_window_add_update_area (impl_window, exposing);
3384 cairo_region_destroy (exposing);
3387 if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3388 append_move_region (impl_window, region, dx, dy);
3390 do_move_region_bits_on_impl (impl_window,
3393 cairo_region_destroy (region);
3396 /* Flushes all outstanding changes to the window, call this
3397 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3400 gdk_window_flush_outstanding_moves (GdkWindow *window)
3402 GdkWindowObject *private;
3403 GdkWindowObject *impl_window;
3404 GList *l, *outstanding;
3405 GdkWindowRegionMove *move;
3407 private = (GdkWindowObject *) window;
3409 impl_window = gdk_window_get_impl_window (private);
3410 outstanding = impl_window->outstanding_moves;
3411 impl_window->outstanding_moves = NULL;
3413 for (l = outstanding; l != NULL; l = l->next)
3417 do_move_region_bits_on_impl (impl_window,
3418 move->dest_region, move->dx, move->dy);
3420 gdk_window_region_move_free (move);
3423 g_list_free (outstanding);
3428 * @window: a #GdkWindow
3430 * Flush all outstanding cached operations on a window, leaving the
3431 * window in a state which reflects all that has been drawn before.
3433 * Gdk uses multiple kinds of caching to get better performance and
3434 * nicer drawing. For instance, during exposes all paints to a window
3435 * using double buffered rendering are keep on a surface until the last
3436 * window has been exposed. It also delays window moves/scrolls until
3437 * as long as possible until next update to avoid tearing when moving
3440 * Normally this should be completely invisible to applications, as
3441 * we automatically flush the windows when required, but this might
3442 * be needed if you for instance mix direct native drawing with
3443 * gdk drawing. For Gtk widgets that don't use double buffering this
3444 * will be called automatically before sending the expose event.
3449 gdk_window_flush (GdkWindow *window)
3451 gdk_window_flush_outstanding_moves (window);
3452 gdk_window_flush_implicit_paint (window);
3455 /* If we're about to move/resize or otherwise change the
3456 * hierarchy of a client side window in an impl and we're
3457 * called from an expose event handler then we need to
3458 * flush any already painted parts of the implicit paint
3459 * that are not part of the current paint, as these may
3460 * be used when scrolling or may overdraw the changes
3461 * caused by the hierarchy change.
3464 gdk_window_flush_if_exposing (GdkWindow *window)
3466 GdkWindowObject *private;
3467 GdkWindowObject *impl_window;
3469 private = (GdkWindowObject *) window;
3470 impl_window = gdk_window_get_impl_window (private);
3472 /* If we're in an implicit paint (i.e. in an expose handler, flush
3473 all the already finished exposes to get things to an uptodate state. */
3474 if (impl_window->implicit_paint)
3475 gdk_window_flush (window);
3480 gdk_window_flush_recursive_helper (GdkWindowObject *window,
3483 GdkWindowObject *child;
3486 for (l = window->children; l != NULL; l = l->next)
3490 if (child->impl == impl)
3491 /* Same impl, ignore */
3492 gdk_window_flush_recursive_helper (child, impl);
3494 gdk_window_flush_recursive (child);
3499 gdk_window_flush_recursive (GdkWindowObject *window)
3501 gdk_window_flush ((GdkWindow *)window);
3502 gdk_window_flush_recursive_helper (window, window->impl);
3505 static cairo_region_t*
3506 gdk_window_get_clip_region (GdkDrawable *drawable)
3508 GdkWindowObject *private = (GdkWindowObject *)drawable;
3509 cairo_region_t *result;
3511 result = cairo_region_copy (private->clip_region);
3513 if (private->paint_stack)
3515 cairo_region_t *paint_region = cairo_region_create ();
3516 GSList *tmp_list = private->paint_stack;
3520 GdkWindowPaint *paint = tmp_list->data;
3522 cairo_region_union (paint_region, paint->region);
3524 tmp_list = tmp_list->next;
3527 cairo_region_intersect (result, paint_region);
3528 cairo_region_destroy (paint_region);
3534 static cairo_region_t*
3535 gdk_window_get_visible_region (GdkDrawable *drawable)
3537 GdkWindowObject *private = (GdkWindowObject*) drawable;
3539 return cairo_region_copy (private->clip_region);
3543 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3545 GdkWindowObject *private = (GdkWindowObject *) window;
3546 GdkWindowObject *bg_private;
3547 cairo_pattern_t *pattern = NULL;
3548 int x_offset = 0, y_offset = 0;
3551 cr = cairo_create (paint->surface);
3553 for (bg_private = private; bg_private; bg_private = bg_private->parent)
3555 pattern = gdk_window_get_background_pattern ((GdkWindow *) bg_private);
3559 x_offset += bg_private->x;
3560 y_offset += bg_private->y;
3565 cairo_translate (cr, -x_offset, -y_offset);
3566 cairo_set_source (cr, pattern);
3567 cairo_translate (cr, x_offset, y_offset);
3570 cairo_set_source_rgb (cr, 0, 0, 0);
3576 gdk_window_clear_backing_region (GdkWindow *window,
3577 cairo_region_t *region)
3579 GdkWindowObject *private = (GdkWindowObject *)window;
3580 GdkWindowPaint *paint = private->paint_stack->data;
3581 cairo_region_t *clip;
3582 GdkRectangle clipbox;
3585 if (GDK_WINDOW_DESTROYED (window))
3588 cr = setup_backing_rect (window, paint, 0, 0);
3590 clip = cairo_region_copy (paint->region);
3591 cairo_region_intersect (clip, region);
3592 cairo_region_get_extents (clip, &clipbox);
3594 gdk_cairo_region (cr, clip);
3599 cairo_region_destroy (clip);
3603 gdk_window_clear_backing_region_direct (GdkWindow *window,
3604 cairo_region_t *region)
3606 GdkWindowObject *private = (GdkWindowObject *)window;
3607 GdkWindowPaint paint;
3608 cairo_region_t *clip;
3609 GdkRectangle clipbox;
3612 if (GDK_WINDOW_DESTROYED (window))
3615 paint.surface = _gdk_drawable_ref_cairo_surface (window);
3617 cr = setup_backing_rect (window, &paint, 0, 0);
3619 clip = cairo_region_copy (private->clip_region_with_children);
3620 cairo_region_intersect (clip, region);
3621 cairo_region_get_extents (clip, &clipbox);
3623 gdk_cairo_region (cr, clip);
3628 cairo_region_destroy (clip);
3629 cairo_surface_destroy (paint.surface);
3634 gdk_window_clear_region_internal (GdkWindow *window,
3635 cairo_region_t *region)
3637 GdkWindowObject *private = (GdkWindowObject *)window;
3639 if (private->paint_stack)
3640 gdk_window_clear_backing_region (window, region);
3642 gdk_window_clear_backing_region_direct (window, region);
3646 gdk_window_drop_cairo_surface (GdkWindowObject *private)
3648 if (private->cairo_surface)
3650 cairo_surface_finish (private->cairo_surface);
3651 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3653 private->cairo_surface = NULL;
3658 gdk_window_cairo_surface_destroy (void *data)
3660 GdkWindowObject *private = (GdkWindowObject*) data;
3662 private->cairo_surface = NULL;
3663 private->impl_window->outstanding_surfaces--;
3666 static cairo_surface_t *
3667 gdk_window_create_cairo_surface (GdkDrawable *drawable,
3671 GdkWindowObject *private = GDK_WINDOW_OBJECT(drawable);
3672 cairo_surface_t *surface, *subsurface;
3674 surface =_gdk_drawable_ref_cairo_surface (private->impl);
3675 if (gdk_window_has_impl (private))
3678 subsurface = cairo_surface_create_for_rectangle (surface,
3683 cairo_surface_destroy (surface);
3688 static cairo_surface_t *
3689 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
3691 GdkWindowObject *private = (GdkWindowObject*) drawable;
3692 cairo_surface_t *surface;
3694 if (private->paint_stack)
3696 GdkWindowPaint *paint = private->paint_stack->data;
3698 surface = paint->surface;
3699 cairo_surface_reference (surface);
3704 /* This will be drawing directly to the window, so flush implicit paint */
3705 gdk_window_flush ((GdkWindow *)drawable);
3707 if (!private->cairo_surface)
3709 private->cairo_surface = _gdk_drawable_create_cairo_surface (drawable,
3713 if (private->cairo_surface)
3715 private->impl_window->outstanding_surfaces++;
3717 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3718 drawable, gdk_window_cairo_surface_destroy);
3722 cairo_surface_reference (private->cairo_surface);
3724 surface = private->cairo_surface;
3731 gdk_window_set_cairo_clip (GdkDrawable *drawable,
3734 GdkWindowObject *private = (GdkWindowObject*) drawable;
3736 if (!private->paint_stack)
3738 cairo_reset_clip (cr);
3741 cairo_identity_matrix (cr);
3743 cairo_new_path (cr);
3744 gdk_cairo_region (cr, private->clip_region_with_children);
3751 GdkWindowPaint *paint = private->paint_stack->data;
3753 /* Only needs to clip to region if piggybacking
3754 on an implicit paint */
3755 cairo_reset_clip (cr);
3756 if (paint->uses_implicit)
3759 cairo_identity_matrix (cr);
3761 cairo_new_path (cr);
3762 gdk_cairo_region (cr, paint->region);
3770 /* Code for dirty-region queueing
3772 static GSList *update_windows = NULL;
3773 static guint update_idle = 0;
3774 static gboolean debug_updates = FALSE;
3776 static inline gboolean
3777 gdk_window_is_ancestor (GdkWindow *window,
3778 GdkWindow *ancestor)
3782 GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
3784 if (parent == ancestor)
3794 gdk_window_add_update_window (GdkWindow *window)
3797 GSList *prev = NULL;
3798 gboolean has_ancestor_in_list = FALSE;
3800 for (tmp = update_windows; tmp; tmp = tmp->next)
3802 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
3804 /* check if tmp is an ancestor of "window"; if it is, set a
3805 * flag indicating that all following windows are either
3806 * children of "window" or from a differen hierarchy
3808 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3809 has_ancestor_in_list = TRUE;
3811 /* insert in reverse stacking order when adding around siblings,
3812 * so processing updates properly paints over lower stacked windows
3814 if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
3816 gint index = g_list_index (parent->children, window);
3817 for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
3819 gint sibling_index = g_list_index (parent->children, tmp->data);
3820 if (index > sibling_index)
3824 /* here, tmp got advanced past all lower stacked siblings */
3825 tmp = g_slist_prepend (tmp, window);
3829 update_windows = tmp;
3833 /* if "window" has an ancestor in the list and tmp is one of
3834 * "window's" children, insert "window" before tmp
3836 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3838 tmp = g_slist_prepend (tmp, window);
3843 update_windows = tmp;
3847 /* if we're at the end of the list and had an ancestor it it,
3848 * append to the list
3850 if (! tmp->next && has_ancestor_in_list)
3852 tmp = g_slist_append (tmp, window);
3859 /* if all above checks failed ("window" is from a different
3860 * hierarchy than what is already in the list) or the list is
3863 update_windows = g_slist_prepend (update_windows, window);
3867 gdk_window_remove_update_window (GdkWindow *window)
3869 update_windows = g_slist_remove (update_windows, window);
3873 gdk_window_update_idle (gpointer data)
3875 gdk_window_process_all_updates ();
3881 gdk_window_is_toplevel_frozen (GdkWindow *window)
3883 GdkWindowObject *toplevel;
3885 toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
3887 return toplevel->update_and_descendants_freeze_count > 0;
3891 gdk_window_schedule_update (GdkWindow *window)
3894 (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
3895 gdk_window_is_toplevel_frozen (window)))
3900 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
3901 gdk_window_update_idle,
3906 _gdk_window_process_updates_recurse (GdkWindow *window,
3907 cairo_region_t *expose_region)
3909 GdkWindowObject *private = (GdkWindowObject *)window;
3910 GdkWindowObject *child;
3911 cairo_region_t *child_region;
3913 GList *l, *children;
3915 if (cairo_region_is_empty (expose_region))
3918 if (gdk_window_is_offscreen (private->impl_window) &&
3919 private == private->impl_window)
3920 _gdk_window_add_damage ((GdkWindow *) private->impl_window, expose_region);
3922 /* Make this reentrancy safe for expose handlers freeing windows */
3923 children = g_list_copy (private->children);
3924 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3926 /* Iterate over children, starting at topmost */
3927 for (l = children; l != NULL; l = l->next)
3931 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3934 /* Ignore offscreen children, as they don't draw in their parent and
3935 * don't take part in the clipping */
3936 if (gdk_window_is_offscreen (child))
3941 r.width = child->width;
3942 r.height = child->height;
3944 child_region = cairo_region_create_rectangle (&r);
3947 /* Adjust shape region to parent window coords */
3948 cairo_region_translate (child->shape, child->x, child->y);
3949 cairo_region_intersect (child_region, child->shape);
3950 cairo_region_translate (child->shape, -child->x, -child->y);
3953 if (child->impl == private->impl)
3955 /* Client side child, expose */
3956 cairo_region_intersect (child_region, expose_region);
3957 cairo_region_subtract (expose_region, child_region);
3958 cairo_region_translate (child_region, -child->x, -child->y);
3959 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
3963 /* Native child, just remove area from expose region */
3964 cairo_region_subtract (expose_region, child_region);
3966 cairo_region_destroy (child_region);
3969 g_list_foreach (children, (GFunc)g_object_unref, NULL);
3970 g_list_free (children);
3972 if (!cairo_region_is_empty (expose_region) &&
3973 !private->destroyed)
3975 if (private->event_mask & GDK_EXPOSURE_MASK)
3979 event.expose.type = GDK_EXPOSE;
3980 event.expose.window = g_object_ref (window);
3981 event.expose.send_event = FALSE;
3982 event.expose.count = 0;
3983 event.expose.region = expose_region;
3984 cairo_region_get_extents (expose_region, &event.expose.area);
3986 (*_gdk_event_func) (&event, _gdk_event_data);
3988 g_object_unref (window);
3990 else if (private->window_type != GDK_WINDOW_FOREIGN)
3992 /* No exposure mask set, so nothing will be drawn, the
3993 * app relies on the background being what it specified
3994 * for the window. So, we need to clear this manually.
3996 * For foreign windows if expose is not set that generally
3997 * means some other client paints them, so don't clear
4000 * We use begin/end_paint around the clear so that we can
4001 * piggyback on the implicit paint */
4003 gdk_window_begin_paint_region (window, expose_region);
4004 gdk_window_clear_region_internal (window, expose_region);
4005 gdk_window_end_paint (window);
4010 /* Process and remove any invalid area on the native window by creating
4011 * expose events for the window and all non-native descendants.
4012 * Also processes any outstanding moves on the window before doing
4013 * any drawing. Note that its possible to have outstanding moves without
4014 * any invalid area as we use the update idle mechanism to coalesce
4015 * multiple moves as well as multiple invalidations.
4018 gdk_window_process_updates_internal (GdkWindow *window)
4020 GdkWindowObject *private = (GdkWindowObject *)window;
4021 GdkWindowImplIface *impl_iface;
4022 gboolean save_region = FALSE;
4023 GdkRectangle clip_box;
4025 /* Ensure the window lives while updating it */
4026 g_object_ref (window);
4028 /* If an update got queued during update processing, we can get a
4029 * window in the update queue that has an empty update_area.
4032 if (private->update_area)
4034 cairo_region_t *update_area = private->update_area;
4035 private->update_area = NULL;
4037 if (_gdk_event_func && gdk_window_is_viewable (window))
4039 cairo_region_t *expose_region;
4040 gboolean end_implicit;
4042 /* Clip to part visible in toplevel */
4043 cairo_region_intersect (update_area, private->clip_region);
4047 /* Make sure we see the red invalid area before redrawing. */
4048 gdk_display_sync (gdk_window_get_display (window));
4052 /* At this point we will be completely redrawing all of update_area.
4053 * If we have any outstanding moves that end up moving stuff inside
4054 * this area we don't actually need to move that as that part would
4055 * be overdrawn by the expose anyway. So, in order to copy less data
4056 * we remove these areas from the outstanding moves.
4058 if (private->outstanding_moves)
4060 GdkWindowRegionMove *move;
4061 cairo_region_t *remove;
4064 remove = cairo_region_copy (update_area);
4065 /* We iterate backwards, starting from the state that would be
4066 if we had applied all the moves. */
4067 for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
4072 /* Don't need this area */
4073 cairo_region_subtract (move->dest_region, remove);
4075 /* However if any of the destination we do need has a source
4076 in the updated region we do need that as a destination for
4077 the earlier moves */
4078 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
4079 cairo_region_subtract (remove, move->dest_region);
4081 if (cairo_region_is_empty (move->dest_region))
4083 gdk_window_region_move_free (move);
4084 private->outstanding_moves =
4085 g_list_delete_link (private->outstanding_moves, l);
4087 else /* move back */
4088 cairo_region_translate (move->dest_region, move->dx, move->dy);
4090 cairo_region_destroy (remove);
4093 /* By now we a set of window moves that should be applied, and then
4094 * an update region that should be repainted. A trivial implementation
4095 * would just do that in order, however in order to get nicer drawing
4096 * we do some tricks:
4098 * First of all, each subwindow expose may be double buffered by
4099 * itself (depending on widget setting) via
4100 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
4101 * creating a single surface the size of the invalid area on the
4102 * native window which all the individual normal paints will draw
4103 * into. This way in the normal case there will be only one surface
4104 * allocated and only once surface draw done for all the windows
4105 * in this native window.
4106 * There are a couple of reasons this may fail, for instance, some
4107 * backends (like quartz) do its own double buffering, so we disable
4108 * gdk double buffering there. Secondly, some subwindow could be
4109 * non-double buffered and draw directly to the window outside a
4110 * begin/end_paint pair. That will be lead to a gdk_window_flush
4111 * which immediately executes all outstanding moves and paints+removes
4112 * the implicit paint (further paints will allocate their own surfaces).
4114 * Secondly, in the case of implicit double buffering we expose all
4115 * the child windows into the implicit surface before we execute
4116 * the outstanding moves. This way we minimize the time between
4117 * doing the moves and rendering the new update area, thus minimizing
4118 * flashing. Of course, if any subwindow is non-double buffered we
4119 * well flush earlier than that.
4121 * Thirdly, after having done the outstanding moves we queue an
4122 * "antiexpose" on the area that will be drawn by the expose, which
4123 * means that any invalid region on the native window side before
4124 * the first expose drawing operation will be discarded, as it
4125 * has by then been overdrawn with valid data. This means we can
4126 * avoid doing the unnecessary repaint any outstanding expose events.
4129 cairo_region_get_extents (update_area, &clip_box);
4130 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
4131 expose_region = cairo_region_copy (update_area);
4134 /* Rendering is not double buffered by gdk, do outstanding
4135 * moves and queue antiexposure immediately. No need to do
4137 gdk_window_flush_outstanding_moves (window);
4138 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4139 save_region = impl_iface->queue_antiexpose (window, update_area);
4142 /* Render the invalid areas to the implicit paint, by sending exposes.
4143 * May flush if non-double buffered widget draw. */
4144 _gdk_windowing_window_process_updates_recurse (window, expose_region);
4148 /* Do moves right before exposes are rendered to the window */
4149 gdk_window_flush_outstanding_moves (window);
4151 /* By this time we know that any outstanding expose for this
4152 * area is invalid and we can avoid it, so queue an antiexpose.
4153 * However, it may be that due to an non-double buffered expose
4154 * we have already started drawing to the window, so it would
4155 * be to late to anti-expose now. Since this is merely an
4156 * optimization we just avoid doing it at all in that case.
4158 if (private->implicit_paint != NULL &&
4159 !private->implicit_paint->flushed)
4161 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4162 save_region = impl_iface->queue_antiexpose (window, update_area);
4165 gdk_window_end_implicit_paint (window);
4167 cairo_region_destroy (expose_region);
4170 cairo_region_destroy (update_area);
4173 if (private->outstanding_moves)
4175 /* Flush any outstanding moves, may happen if we moved a window but got
4176 no actual invalid area */
4177 gdk_window_flush_outstanding_moves (window);
4180 g_object_unref (window);
4184 flush_all_displays (void)
4186 GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4189 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
4190 gdk_display_flush (tmp_list->data);
4192 g_slist_free (displays);
4195 /* Currently it is not possible to override
4196 * gdk_window_process_all_updates in the same manner as
4197 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4198 * by implementing the GdkPaintable interface. If in the future a
4199 * backend would need this, the right solution would be to add a
4200 * method to GdkDisplay that can be optionally
4201 * NULL. gdk_window_process_all_updates can then walk the list of open
4202 * displays and call the mehod.
4206 * gdk_window_process_all_updates:
4208 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4209 * in the application.
4213 gdk_window_process_all_updates (void)
4215 GSList *old_update_windows = update_windows;
4216 GSList *tmp_list = update_windows;
4217 static gboolean in_process_all_updates = FALSE;
4218 static gboolean got_recursive_update = FALSE;
4220 if (in_process_all_updates)
4222 /* We can't do this now since that would recurse, so
4223 delay it until after the recursion is done. */
4224 got_recursive_update = TRUE;
4229 in_process_all_updates = TRUE;
4230 got_recursive_update = FALSE;
4233 g_source_remove (update_idle);
4235 update_windows = NULL;
4238 _gdk_windowing_before_process_all_updates ();
4240 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4244 GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
4246 if (!GDK_WINDOW_DESTROYED (tmp_list->data))
4248 if (private->update_freeze_count ||
4249 gdk_window_is_toplevel_frozen (tmp_list->data))
4250 gdk_window_add_update_window ((GdkWindow *) private);
4252 gdk_window_process_updates_internal (tmp_list->data);
4255 g_object_unref (tmp_list->data);
4256 tmp_list = tmp_list->next;
4259 g_slist_free (old_update_windows);
4261 flush_all_displays ();
4263 _gdk_windowing_after_process_all_updates ();
4265 in_process_all_updates = FALSE;
4267 /* If we ignored a recursive call, schedule a
4268 redraw now so that it eventually happens,
4269 otherwise we could miss an update if nothing
4270 else schedules an update. */
4271 if (got_recursive_update && !update_idle)
4273 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4274 gdk_window_update_idle,
4279 * gdk_window_process_updates:
4280 * @window: a #GdkWindow
4281 * @update_children: whether to also process updates for child windows
4283 * Sends one or more expose events to @window. The areas in each
4284 * expose event will cover the entire update area for the window (see
4285 * gdk_window_invalidate_region() for details). Normally GDK calls
4286 * gdk_window_process_all_updates() on your behalf, so there's no
4287 * need to call this function unless you want to force expose events
4288 * to be delivered immediately and synchronously (vs. the usual
4289 * case, where GDK delivers them in an idle handler). Occasionally
4290 * this is useful to produce nicer scrolling behavior, for example.
4294 gdk_window_process_updates (GdkWindow *window,
4295 gboolean update_children)
4297 GdkWindowObject *private = (GdkWindowObject *)window;
4298 GdkWindowObject *impl_window;
4300 g_return_if_fail (GDK_IS_WINDOW (window));
4302 if (GDK_WINDOW_DESTROYED (window))
4305 /* Make sure the window lives during the expose callouts */
4306 g_object_ref (window);
4308 impl_window = gdk_window_get_impl_window (private);
4309 if ((impl_window->update_area ||
4310 impl_window->outstanding_moves) &&
4311 !impl_window->update_freeze_count &&
4312 !gdk_window_is_toplevel_frozen (window) &&
4314 /* Don't recurse into process_updates_internal, we'll
4315 * do the update later when idle instead. */
4316 impl_window->implicit_paint == NULL)
4318 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4319 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4322 if (update_children)
4324 /* process updates in reverse stacking order so composition or
4325 * painting over achieves the desired effect for offscreen windows
4327 GList *node, *children;
4329 children = g_list_copy (private->children);
4330 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4332 for (node = g_list_last (children); node; node = node->prev)
4334 gdk_window_process_updates (node->data, TRUE);
4335 g_object_unref (node->data);
4338 g_list_free (children);
4341 g_object_unref (window);
4345 gdk_window_invalidate_rect_full (GdkWindow *window,
4346 const GdkRectangle *rect,
4347 gboolean invalidate_children,
4350 GdkRectangle window_rect;
4351 cairo_region_t *region;
4352 GdkWindowObject *private = (GdkWindowObject *)window;
4354 g_return_if_fail (GDK_IS_WINDOW (window));
4356 if (GDK_WINDOW_DESTROYED (window))
4359 if (private->input_only || !private->viewable)
4366 window_rect.width = private->width;
4367 window_rect.height = private->height;
4368 rect = &window_rect;
4371 region = cairo_region_create_rectangle (rect);
4372 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4373 cairo_region_destroy (region);
4377 * gdk_window_invalidate_rect:
4378 * @window: a #GdkWindow
4379 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4381 * @invalidate_children: whether to also invalidate child windows
4383 * A convenience wrapper around gdk_window_invalidate_region() which
4384 * invalidates a rectangular region. See
4385 * gdk_window_invalidate_region() for details.
4388 gdk_window_invalidate_rect (GdkWindow *window,
4389 const GdkRectangle *rect,
4390 gboolean invalidate_children)
4392 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4396 draw_ugly_color (GdkWindow *window,
4397 const cairo_region_t *region)
4401 cr = gdk_cairo_create (window);
4402 /* Draw ugly color all over the newly-invalid region */
4403 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4404 gdk_cairo_region (cr, region);
4411 impl_window_add_update_area (GdkWindowObject *impl_window,
4412 cairo_region_t *region)
4414 if (impl_window->update_area)
4415 cairo_region_union (impl_window->update_area, region);
4418 gdk_window_add_update_window ((GdkWindow *)impl_window);
4419 impl_window->update_area = cairo_region_copy (region);
4420 gdk_window_schedule_update ((GdkWindow *)impl_window);
4424 /* clear_bg controls if the region will be cleared to
4425 * the background pattern if the exposure mask is not
4426 * set for the window, whereas this might not otherwise be
4427 * done (unless necessary to emulate background settings).
4428 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4429 * need to clear the background, such as when exposing the area beneath a
4430 * hidden or moved window, but not when an app requests repaint or when the
4431 * windowing system exposes a newly visible area (because then the windowing
4432 * system has already cleared the area).
4435 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4436 const cairo_region_t *region,
4438 GdkWindowChildFunc child_func,
4441 GdkWindowObject *private = (GdkWindowObject *)window;
4442 GdkWindowObject *impl_window;
4443 cairo_region_t *visible_region;
4446 g_return_if_fail (GDK_IS_WINDOW (window));
4448 if (GDK_WINDOW_DESTROYED (window))
4451 if (private->input_only ||
4452 !private->viewable ||
4453 cairo_region_is_empty (region) ||
4454 private->window_type == GDK_WINDOW_ROOT)
4457 visible_region = gdk_drawable_get_visible_region (window);
4458 cairo_region_intersect (visible_region, region);
4460 tmp_list = private->children;
4463 GdkWindowObject *child = tmp_list->data;
4465 if (!child->input_only)
4467 cairo_region_t *child_region;
4468 GdkRectangle child_rect;
4470 child_rect.x = child->x;
4471 child_rect.y = child->y;
4472 child_rect.width = child->width;
4473 child_rect.height = child->height;
4474 child_region = cairo_region_create_rectangle (&child_rect);
4476 /* remove child area from the invalid area of the parent */
4477 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4478 !child->composited &&
4479 !gdk_window_is_offscreen (child))
4480 cairo_region_subtract (visible_region, child_region);
4482 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4484 cairo_region_t *tmp = cairo_region_copy (region);
4486 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4487 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4488 cairo_region_intersect (child_region, tmp);
4490 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4491 child_region, clear_bg, child_func, user_data);
4493 cairo_region_destroy (tmp);
4496 cairo_region_destroy (child_region);
4499 tmp_list = tmp_list->next;
4502 impl_window = gdk_window_get_impl_window (private);
4504 if (!cairo_region_is_empty (visible_region) ||
4505 /* Even if we're not exposing anything, make sure we process
4506 idles for windows with outstanding moves */
4507 (impl_window->outstanding_moves != NULL &&
4508 impl_window->update_area == NULL))
4511 draw_ugly_color (window, region);
4513 /* Convert to impl coords */
4514 cairo_region_translate (visible_region, private->abs_x, private->abs_y);
4516 /* Only invalidate area if app requested expose events or if
4517 we need to clear the area (by request or to emulate background
4518 clearing for non-native windows or native windows with no support
4519 for window backgrounds */
4520 if (private->event_mask & GDK_EXPOSURE_MASK ||
4521 clear_bg == CLEAR_BG_ALL ||
4522 clear_bg == CLEAR_BG_WINCLEARED)
4523 impl_window_add_update_area (impl_window, visible_region);
4526 cairo_region_destroy (visible_region);
4530 * gdk_window_invalidate_maybe_recurse:
4531 * @window: a #GdkWindow
4532 * @region: a #cairo_region_t
4533 * @child_func: function to use to decide if to recurse to a child,
4534 * %NULL means never recurse.
4535 * @user_data: data passed to @child_func
4537 * Adds @region to the update area for @window. The update area is the
4538 * region that needs to be redrawn, or "dirty region." The call
4539 * gdk_window_process_updates() sends one or more expose events to the
4540 * window, which together cover the entire update area. An
4541 * application would normally redraw the contents of @window in
4542 * response to those expose events.
4544 * GDK will call gdk_window_process_all_updates() on your behalf
4545 * whenever your program returns to the main loop and becomes idle, so
4546 * normally there's no need to do that manually, you just need to
4547 * invalidate regions that you know should be redrawn.
4549 * The @child_func parameter controls whether the region of
4550 * each child window that intersects @region will also be invalidated.
4551 * Only children for which @child_func returns TRUE will have the area
4555 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4556 const cairo_region_t *region,
4557 GdkWindowChildFunc child_func,
4560 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4561 child_func, user_data);
4565 true_predicate (GdkWindow *window,
4572 gdk_window_invalidate_region_full (GdkWindow *window,
4573 const cairo_region_t *region,
4574 gboolean invalidate_children,
4577 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4578 invalidate_children ?
4579 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4584 * gdk_window_invalidate_region:
4585 * @window: a #GdkWindow
4586 * @region: a #cairo_region_t
4587 * @invalidate_children: %TRUE to also invalidate child windows
4589 * Adds @region to the update area for @window. The update area is the
4590 * region that needs to be redrawn, or "dirty region." The call
4591 * gdk_window_process_updates() sends one or more expose events to the
4592 * window, which together cover the entire update area. An
4593 * application would normally redraw the contents of @window in
4594 * response to those expose events.
4596 * GDK will call gdk_window_process_all_updates() on your behalf
4597 * whenever your program returns to the main loop and becomes idle, so
4598 * normally there's no need to do that manually, you just need to
4599 * invalidate regions that you know should be redrawn.
4601 * The @invalidate_children parameter controls whether the region of
4602 * each child window that intersects @region will also be invalidated.
4603 * If %FALSE, then the update area for child windows will remain
4604 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4605 * fine grained control over which children are invalidated.
4608 gdk_window_invalidate_region (GdkWindow *window,
4609 const cairo_region_t *region,
4610 gboolean invalidate_children)
4612 gdk_window_invalidate_maybe_recurse (window, region,
4613 invalidate_children ?
4614 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4619 * _gdk_window_invalidate_for_expose:
4620 * @window: a #GdkWindow
4621 * @region: a #cairo_region_t
4623 * Adds @region to the update area for @window. The update area is the
4624 * region that needs to be redrawn, or "dirty region." The call
4625 * gdk_window_process_updates() sends one or more expose events to the
4626 * window, which together cover the entire update area. An
4627 * application would normally redraw the contents of @window in
4628 * response to those expose events.
4630 * GDK will call gdk_window_process_all_updates() on your behalf
4631 * whenever your program returns to the main loop and becomes idle, so
4632 * normally there's no need to do that manually, you just need to
4633 * invalidate regions that you know should be redrawn.
4635 * This version of invalidation is used when you recieve expose events
4636 * from the native window system. It exposes the native window, plus
4637 * any non-native child windows (but not native child windows, as those would
4638 * have gotten their own expose events).
4641 _gdk_window_invalidate_for_expose (GdkWindow *window,
4642 cairo_region_t *region)
4644 GdkWindowObject *private = (GdkWindowObject *) window;
4645 GdkWindowRegionMove *move;
4646 cairo_region_t *move_region;
4649 /* Any invalidations comming from the windowing system will
4650 be in areas that may be moved by outstanding moves,
4651 so we need to modify the expose region correspondingly,
4652 otherwise we would expose in the wrong place, as the
4653 outstanding moves will be copied before we draw the
4655 for (l = private->outstanding_moves; l != NULL; l = l->next)
4659 /* covert to move source region */
4660 move_region = cairo_region_copy (move->dest_region);
4661 cairo_region_translate (move_region, -move->dx, -move->dy);
4663 /* Move area of region that intersects with move source
4664 by dx, dy of the move*/
4665 cairo_region_intersect (move_region, region);
4666 cairo_region_subtract (region, move_region);
4667 cairo_region_translate (move_region, move->dx, move->dy);
4668 cairo_region_union (region, move_region);
4670 cairo_region_destroy (move_region);
4673 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4674 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4680 * gdk_window_get_update_area:
4681 * @window: a #GdkWindow
4683 * Transfers ownership of the update area from @window to the caller
4684 * of the function. That is, after calling this function, @window will
4685 * no longer have an invalid/dirty region; the update area is removed
4686 * from @window and handed to you. If a window has no update area,
4687 * gdk_window_get_update_area() returns %NULL. You are responsible for
4688 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4690 * Return value: the update area for @window
4693 gdk_window_get_update_area (GdkWindow *window)
4695 GdkWindowObject *private = (GdkWindowObject *)window;
4696 GdkWindowObject *impl_window;
4697 cairo_region_t *tmp_region;
4699 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4701 impl_window = gdk_window_get_impl_window (private);
4703 if (impl_window->update_area)
4705 tmp_region = cairo_region_copy (private->clip_region_with_children);
4706 /* Convert to impl coords */
4707 cairo_region_translate (tmp_region, private->abs_x, private->abs_y);
4708 cairo_region_intersect (tmp_region, impl_window->update_area);
4710 if (cairo_region_is_empty (tmp_region))
4712 cairo_region_destroy (tmp_region);
4717 cairo_region_subtract (impl_window->update_area, tmp_region);
4719 if (cairo_region_is_empty (impl_window->update_area) &&
4720 impl_window->outstanding_moves == NULL)
4722 cairo_region_destroy (impl_window->update_area);
4723 impl_window->update_area = NULL;
4725 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4728 /* Convert from impl coords */
4729 cairo_region_translate (tmp_region, -private->abs_x, -private->abs_y);
4739 * _gdk_window_clear_update_area:
4740 * @window: a #GdkWindow.
4742 * Internal function to clear the update area for a window. This
4743 * is called when the window is hidden or destroyed.
4746 _gdk_window_clear_update_area (GdkWindow *window)
4748 GdkWindowObject *private = (GdkWindowObject *)window;
4750 g_return_if_fail (GDK_IS_WINDOW (window));
4752 if (private->update_area)
4754 gdk_window_remove_update_window (window);
4756 cairo_region_destroy (private->update_area);
4757 private->update_area = NULL;
4762 * gdk_window_freeze_updates:
4763 * @window: a #GdkWindow
4765 * Temporarily freezes a window such that it won't receive expose
4766 * events. The window will begin receiving expose events again when
4767 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4768 * has been called more than once, gdk_window_thaw_updates() must be called
4769 * an equal number of times to begin processing exposes.
4772 gdk_window_freeze_updates (GdkWindow *window)
4774 GdkWindowObject *private = (GdkWindowObject *)window;
4775 GdkWindowObject *impl_window;
4777 g_return_if_fail (GDK_IS_WINDOW (window));
4779 impl_window = gdk_window_get_impl_window (private);
4780 impl_window->update_freeze_count++;
4784 * gdk_window_thaw_updates:
4785 * @window: a #GdkWindow
4787 * Thaws a window frozen with gdk_window_freeze_updates().
4790 gdk_window_thaw_updates (GdkWindow *window)
4792 GdkWindowObject *private = (GdkWindowObject *)window;
4793 GdkWindowObject *impl_window;
4795 g_return_if_fail (GDK_IS_WINDOW (window));
4797 impl_window = gdk_window_get_impl_window (private);
4799 g_return_if_fail (impl_window->update_freeze_count > 0);
4801 if (--impl_window->update_freeze_count == 0)
4802 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4806 * gdk_window_freeze_toplevel_updates_libgtk_only:
4807 * @window: a #GdkWindow
4809 * Temporarily freezes a window and all its descendants such that it won't
4810 * receive expose events. The window will begin receiving expose events
4811 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4812 * gdk_window_freeze_toplevel_updates_libgtk_only()
4813 * has been called more than once,
4814 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4815 * an equal number of times to begin processing exposes.
4817 * This function is not part of the GDK public API and is only
4821 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4823 GdkWindowObject *private = (GdkWindowObject *)window;
4825 g_return_if_fail (GDK_IS_WINDOW (window));
4826 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4828 private->update_and_descendants_freeze_count++;
4832 * gdk_window_thaw_toplevel_updates_libgtk_only:
4833 * @window: a #GdkWindow
4835 * Thaws a window frozen with
4836 * gdk_window_freeze_toplevel_updates_libgtk_only().
4838 * This function is not part of the GDK public API and is only
4842 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4844 GdkWindowObject *private = (GdkWindowObject *)window;
4846 g_return_if_fail (GDK_IS_WINDOW (window));
4847 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4848 g_return_if_fail (private->update_and_descendants_freeze_count > 0);
4850 private->update_and_descendants_freeze_count--;
4852 gdk_window_schedule_update (window);
4856 * gdk_window_set_debug_updates:
4857 * @setting: %TRUE to turn on update debugging
4859 * With update debugging enabled, calls to
4860 * gdk_window_invalidate_region() clear the invalidated region of the
4861 * screen to a noticeable color, and GDK pauses for a short time
4862 * before sending exposes to windows during
4863 * gdk_window_process_updates(). The net effect is that you can see
4864 * the invalid region for each window and watch redraws as they
4865 * occur. This allows you to diagnose inefficiencies in your application.
4867 * In essence, because the GDK rendering model prevents all flicker,
4868 * if you are redrawing the same region 400 times you may never
4869 * notice, aside from noticing a speed problem. Enabling update
4870 * debugging causes GTK to flicker slowly and noticeably, so you can
4871 * see exactly what's being redrawn when, in what order.
4873 * The --gtk-debug=updates command line option passed to GTK+ programs
4874 * enables this debug option at application startup time. That's
4875 * usually more useful than calling gdk_window_set_debug_updates()
4876 * yourself, though you might want to use this function to enable
4877 * updates sometime after application startup time.
4881 gdk_window_set_debug_updates (gboolean setting)
4883 debug_updates = setting;
4887 * gdk_window_constrain_size:
4888 * @geometry: a #GdkGeometry structure
4889 * @flags: a mask indicating what portions of @geometry are set
4890 * @width: desired width of window
4891 * @height: desired height of the window
4892 * @new_width: location to store resulting width
4893 * @new_height: location to store resulting height
4895 * Constrains a desired width and height according to a
4896 * set of geometry hints (such as minimum and maximum size).
4899 gdk_window_constrain_size (GdkGeometry *geometry,
4906 /* This routine is partially borrowed from fvwm.
4908 * Copyright 1993, Robert Nation
4909 * You may use this code for any purpose, as long as the original
4910 * copyright remains in the source code and all documentation
4912 * which in turn borrows parts of the algorithm from uwm
4915 gint min_height = 0;
4916 gint base_width = 0;
4917 gint base_height = 0;
4920 gint max_width = G_MAXINT;
4921 gint max_height = G_MAXINT;
4923 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4925 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4927 base_width = geometry->base_width;
4928 base_height = geometry->base_height;
4929 min_width = geometry->min_width;
4930 min_height = geometry->min_height;
4932 else if (flags & GDK_HINT_BASE_SIZE)
4934 base_width = geometry->base_width;
4935 base_height = geometry->base_height;
4936 min_width = geometry->base_width;
4937 min_height = geometry->base_height;
4939 else if (flags & GDK_HINT_MIN_SIZE)
4941 base_width = geometry->min_width;
4942 base_height = geometry->min_height;
4943 min_width = geometry->min_width;
4944 min_height = geometry->min_height;
4947 if (flags & GDK_HINT_MAX_SIZE)
4949 max_width = geometry->max_width ;
4950 max_height = geometry->max_height;
4953 if (flags & GDK_HINT_RESIZE_INC)
4955 xinc = MAX (xinc, geometry->width_inc);
4956 yinc = MAX (yinc, geometry->height_inc);
4959 /* clamp width and height to min and max values
4961 width = CLAMP (width, min_width, max_width);
4962 height = CLAMP (height, min_height, max_height);
4964 /* shrink to base + N * inc
4966 width = base_width + FLOOR (width - base_width, xinc);
4967 height = base_height + FLOOR (height - base_height, yinc);
4969 /* constrain aspect ratio, according to:
4972 * min_aspect <= -------- <= max_aspect
4976 if (flags & GDK_HINT_ASPECT &&
4977 geometry->min_aspect > 0 &&
4978 geometry->max_aspect > 0)
4982 if (geometry->min_aspect * height > width)
4984 delta = FLOOR (height - width / geometry->min_aspect, yinc);
4985 if (height - delta >= min_height)
4989 delta = FLOOR (height * geometry->min_aspect - width, xinc);
4990 if (width + delta <= max_width)
4995 if (geometry->max_aspect * height < width)
4997 delta = FLOOR (width - height * geometry->max_aspect, xinc);
4998 if (width - delta >= min_width)
5002 delta = FLOOR (width / geometry->max_aspect - height, yinc);
5003 if (height + delta <= max_height)
5012 *new_height = height;
5016 * gdk_window_get_pointer:
5017 * @window: a #GdkWindow
5018 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
5019 * return the X coordinate
5020 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
5021 * return the Y coordinate
5022 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
5025 * Obtains the current pointer position and modifier state.
5026 * The position is given in coordinates relative to the upper left
5027 * corner of @window.
5029 * Return value: (transfer none): the window containing the pointer (as with
5030 * gdk_window_at_pointer()), or %NULL if the window containing the
5031 * pointer isn't known to GDK
5033 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
5036 gdk_window_get_pointer (GdkWindow *window,
5039 GdkModifierType *mask)
5041 GdkDisplay *display;
5043 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5045 display = gdk_window_get_display (window);
5047 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
5051 * gdk_window_get_device_position:
5052 * @window: a #GdkWindow.
5053 * @device: #GdkDevice to query to.
5054 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
5055 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
5056 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
5058 * Obtains the current device position and modifier state.
5059 * The position is given in coordinates relative to the upper left
5060 * corner of @window.
5062 * Return value: (transfer none): The window underneath @device (as with
5063 * gdk_display_get_window_at_device_position()), or %NULL if the
5064 * window is not known to GDK.
5069 gdk_window_get_device_position (GdkWindow *window,
5073 GdkModifierType *mask)
5075 GdkDisplay *display;
5077 GdkModifierType tmp_mask;
5080 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5081 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
5086 display = gdk_window_get_display (window);
5087 child = display->device_hooks->window_get_device_position (display, device, window,
5088 &tmp_x, &tmp_y, &tmp_mask);
5097 _gdk_display_enable_motion_hints (display, device);
5103 * gdk_window_at_pointer:
5104 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
5105 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
5107 * Obtains the window underneath the mouse pointer, returning the
5108 * location of that window in @win_x, @win_y. Returns %NULL if the
5109 * window under the mouse pointer is not known to GDK (if the window
5110 * belongs to another application and a #GdkWindow hasn't been created
5111 * for it with gdk_window_foreign_new())
5113 * NOTE: For multihead-aware widgets or applications use
5114 * gdk_display_get_window_at_pointer() instead.
5116 * Return value: (transfer none): window under the mouse pointer
5118 * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
5121 gdk_window_at_pointer (gint *win_x,
5124 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
5128 * gdk_get_default_root_window:
5130 * Obtains the root window (parent all other windows are inside)
5131 * for the default display and screen.
5133 * Return value: (transfer none): the default root window
5136 gdk_get_default_root_window (void)
5138 return gdk_screen_get_root_window (gdk_screen_get_default ());
5142 * gdk_window_foreign_new:
5143 * @anid: a native window handle.
5145 * Wraps a native window for the default display in a #GdkWindow.
5146 * This may fail if the window has been destroyed.
5148 * For example in the X backend, a native window handle is an Xlib
5151 * Return value: (transfer full): the newly-created #GdkWindow wrapper
5152 * for the native window, or %NULL if the window has been destroyed.
5155 gdk_window_foreign_new (GdkNativeWindow anid)
5157 return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
5161 get_all_native_children (GdkWindowObject *private,
5164 GdkWindowObject *child;
5167 for (l = private->children; l != NULL; l = l->next)
5171 if (gdk_window_has_impl (child))
5172 *native = g_list_prepend (*native, child);
5174 get_all_native_children (child, native);
5180 gdk_window_raise_internal (GdkWindow *window)
5182 GdkWindowObject *private = (GdkWindowObject *)window;
5183 GdkWindowObject *parent = private->parent;
5184 GdkWindowObject *above;
5185 GList *native_children;
5187 GdkWindowImplIface *impl_iface;
5191 parent->children = g_list_remove (parent->children, window);
5192 parent->children = g_list_prepend (parent->children, window);
5195 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5196 /* Just do native raise for toplevels */
5197 if (gdk_window_is_toplevel (private) ||
5198 /* The restack_under codepath should work correctly even if the parent
5199 is native, but it relies on the order of ->children to be correct,
5200 and some apps like SWT reorder the x windows without gdks knowledge,
5201 so we use raise directly in order to make these behave as before
5202 when using native windows */
5203 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5205 impl_iface->raise (window);
5207 else if (gdk_window_has_impl (private))
5209 above = find_native_sibling_above (parent, private);
5212 listhead.data = window;
5213 listhead.next = NULL;
5214 listhead.prev = NULL;
5215 impl_iface->restack_under ((GdkWindow *)above,
5219 impl_iface->raise (window);
5223 native_children = NULL;
5224 get_all_native_children (private, &native_children);
5225 if (native_children != NULL)
5227 above = find_native_sibling_above (parent, private);
5230 impl_iface->restack_under ((GdkWindow *)above,
5234 /* Right order, since native_children is bottom-topmost first */
5235 for (l = native_children; l != NULL; l = l->next)
5236 impl_iface->raise (l->data);
5239 g_list_free (native_children);
5245 /* Returns TRUE If the native window was mapped or unmapped */
5247 set_viewable (GdkWindowObject *w,
5250 GdkWindowObject *child;
5251 GdkWindowImplIface *impl_iface;
5254 if (w->viewable == val)
5260 recompute_visible_regions (w, FALSE, FALSE);
5262 for (l = w->children; l != NULL; l = l->next)
5266 if (GDK_WINDOW_IS_MAPPED (child) &&
5267 child->window_type != GDK_WINDOW_FOREIGN)
5268 set_viewable (child, val);
5271 if (!_gdk_native_windows &&
5272 gdk_window_has_impl (w) &&
5273 w->window_type != GDK_WINDOW_FOREIGN &&
5274 !gdk_window_is_toplevel (w))
5276 /* For most native windows we show/hide them not when they are
5277 * mapped/unmapped, because that may not produce the correct results.
5278 * For instance, if a native window have a non-native parent which is
5279 * hidden, but its native parent is viewable then showing the window
5280 * would make it viewable to X but its not viewable wrt the non-native
5281 * hierarchy. In order to handle this we track the gdk side viewability
5282 * and only map really viewable windows.
5284 * There are two exceptions though:
5286 * For foreign windows we don't want ever change the mapped state
5287 * except when explicitly done via gdk_window_show/hide, as this may
5288 * cause problems for client owning the foreign window when its window
5289 * is suddenly mapped or unmapped.
5291 * For toplevel windows embedded in a foreign window (e.g. a plug)
5292 * we sometimes synthesize a map of a window, but the native
5293 * window is really shown by the embedder, so we don't want to
5294 * do the show ourselves. We can't really tell this case from the normal
5295 * toplevel show as such toplevels are seen by gdk as parents of the
5296 * root window, so we make an exception for all toplevels.
5298 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
5299 * like this, so we just always show/hide directly.
5302 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
5304 impl_iface->show ((GdkWindow *)w, FALSE);
5306 impl_iface->hide ((GdkWindow *)w);
5314 /* Returns TRUE If the native window was mapped or unmapped */
5316 _gdk_window_update_viewable (GdkWindow *window)
5318 GdkWindowObject *priv = (GdkWindowObject *)window;
5321 if (priv->window_type == GDK_WINDOW_FOREIGN ||
5322 priv->window_type == GDK_WINDOW_ROOT)
5324 else if (gdk_window_is_toplevel (priv) ||
5325 priv->parent->viewable)
5326 viewable = GDK_WINDOW_IS_MAPPED (priv);
5330 return set_viewable (priv, viewable);
5334 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5336 GdkWindowObject *private;
5337 GdkWindowImplIface *impl_iface;
5338 gboolean was_mapped, was_viewable;
5341 g_return_if_fail (GDK_IS_WINDOW (window));
5343 private = (GdkWindowObject *) window;
5344 if (private->destroyed)
5347 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5348 was_viewable = private->viewable;
5351 /* Keep children in (reverse) stacking order */
5352 gdk_window_raise_internal (window);
5354 if (gdk_window_has_impl (private))
5357 gdk_synthesize_window_state (window,
5358 GDK_WINDOW_STATE_WITHDRAWN,
5366 did_show = _gdk_window_update_viewable (window);
5368 /* If it was already viewable the backend show op won't be called, call it
5369 again to ensure things happen right if the mapped tracking was not right
5370 for e.g. a foreign window.
5371 Dunno if this is strictly needed but its what happened pre-csw.
5372 Also show if not done by gdk_window_update_viewable. */
5373 if (gdk_window_has_impl (private) && (was_viewable || !did_show))
5375 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5376 impl_iface->show ((GdkWindow *)private,
5377 !did_show ? was_mapped : TRUE);
5380 if (!was_mapped && !gdk_window_has_impl (private))
5382 if (private->event_mask & GDK_STRUCTURE_MASK)
5383 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5385 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5386 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5389 if (!was_mapped || raise)
5391 recompute_visible_regions (private, TRUE, FALSE);
5393 /* If any decendants became visible we need to send visibility notify */
5394 gdk_window_update_visibility_recursively (private, NULL);
5396 if (gdk_window_is_viewable (window))
5398 _gdk_synthesize_crossing_events_for_geometry_change (window);
5399 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5405 * gdk_window_show_unraised:
5406 * @window: a #GdkWindow
5408 * Shows a #GdkWindow onscreen, but does not modify its stacking
5409 * order. In contrast, gdk_window_show() will raise the window
5410 * to the top of the window stack.
5412 * On the X11 platform, in Xlib terms, this function calls
5413 * XMapWindow() (it also updates some internal GDK state, which means
5414 * that you can't really use XMapWindow() directly on a GDK window).
5417 gdk_window_show_unraised (GdkWindow *window)
5419 gdk_window_show_internal (window, FALSE);
5424 * @window: a #GdkWindow
5426 * Raises @window to the top of the Z-order (stacking order), so that
5427 * other windows with the same parent window appear below @window.
5428 * This is true whether or not the windows are visible.
5430 * If @window is a toplevel, the window manager may choose to deny the
5431 * request to move the window in the Z-order, gdk_window_raise() only
5432 * requests the restack, does not guarantee it.
5435 gdk_window_raise (GdkWindow *window)
5437 GdkWindowObject *private;
5438 cairo_region_t *old_region, *new_region;
5440 g_return_if_fail (GDK_IS_WINDOW (window));
5442 private = (GdkWindowObject *) window;
5443 if (private->destroyed)
5446 gdk_window_flush_if_exposing (window);
5449 if (gdk_window_is_viewable (window) &&
5450 !private->input_only)
5451 old_region = cairo_region_copy (private->clip_region);
5453 /* Keep children in (reverse) stacking order */
5454 gdk_window_raise_internal (window);
5456 recompute_visible_regions (private, TRUE, FALSE);
5460 new_region = cairo_region_copy (private->clip_region);
5462 cairo_region_subtract (new_region, old_region);
5463 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5465 cairo_region_destroy (old_region);
5466 cairo_region_destroy (new_region);
5471 gdk_window_lower_internal (GdkWindow *window)
5473 GdkWindowObject *private = (GdkWindowObject *)window;
5474 GdkWindowObject *parent = private->parent;
5475 GdkWindowImplIface *impl_iface;
5476 GdkWindowObject *above;
5477 GList *native_children;
5482 parent->children = g_list_remove (parent->children, window);
5483 parent->children = g_list_append (parent->children, window);
5486 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5487 /* Just do native lower for toplevels */
5488 if (gdk_window_is_toplevel (private) ||
5489 /* The restack_under codepath should work correctly even if the parent
5490 is native, but it relies on the order of ->children to be correct,
5491 and some apps like SWT reorder the x windows without gdks knowledge,
5492 so we use lower directly in order to make these behave as before
5493 when using native windows */
5494 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5496 impl_iface->lower (window);
5498 else if (gdk_window_has_impl (private))
5500 above = find_native_sibling_above (parent, private);
5503 listhead.data = window;
5504 listhead.next = NULL;
5505 listhead.prev = NULL;
5506 impl_iface->restack_under ((GdkWindow *)above, &listhead);
5509 impl_iface->raise (window);
5513 native_children = NULL;
5514 get_all_native_children (private, &native_children);
5515 if (native_children != NULL)
5517 above = find_native_sibling_above (parent, private);
5520 impl_iface->restack_under ((GdkWindow *)above,
5524 /* Right order, since native_children is bottom-topmost first */
5525 for (l = native_children; l != NULL; l = l->next)
5526 impl_iface->raise (l->data);
5529 g_list_free (native_children);
5536 gdk_window_invalidate_in_parent (GdkWindowObject *private)
5538 GdkRectangle r, child;
5540 if (gdk_window_is_toplevel (private))
5543 /* get the visible rectangle of the parent */
5545 r.width = private->parent->width;
5546 r.height = private->parent->height;
5548 child.x = private->x;
5549 child.y = private->y;
5550 child.width = private->width;
5551 child.height = private->height;
5552 gdk_rectangle_intersect (&r, &child, &r);
5554 gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
5560 * @window: a #GdkWindow
5562 * Lowers @window to the bottom of the Z-order (stacking order), so that
5563 * other windows with the same parent window appear above @window.
5564 * This is true whether or not the other windows are visible.
5566 * If @window is a toplevel, the window manager may choose to deny the
5567 * request to move the window in the Z-order, gdk_window_lower() only
5568 * requests the restack, does not guarantee it.
5570 * Note that gdk_window_show() raises the window again, so don't call this
5571 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5574 gdk_window_lower (GdkWindow *window)
5576 GdkWindowObject *private;
5578 g_return_if_fail (GDK_IS_WINDOW (window));
5580 private = (GdkWindowObject *) window;
5581 if (private->destroyed)
5584 gdk_window_flush_if_exposing (window);
5586 /* Keep children in (reverse) stacking order */
5587 gdk_window_lower_internal (window);
5589 recompute_visible_regions (private, TRUE, FALSE);
5591 _gdk_synthesize_crossing_events_for_geometry_change (window);
5592 gdk_window_invalidate_in_parent (private);
5596 * gdk_window_restack:
5597 * @window: a #GdkWindow
5598 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5601 * Changes the position of @window in the Z-order (stacking order), so that
5602 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5605 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5606 * lowers the window.
5608 * If @window is a toplevel, the window manager may choose to deny the
5609 * request to move the window in the Z-order, gdk_window_restack() only
5610 * requests the restack, does not guarantee it.
5615 gdk_window_restack (GdkWindow *window,
5619 GdkWindowObject *private;
5620 GdkWindowImplIface *impl_iface;
5621 GdkWindowObject *parent;
5622 GdkWindowObject *above_native;
5623 GList *sibling_link;
5624 GList *native_children;
5627 g_return_if_fail (GDK_IS_WINDOW (window));
5628 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5630 private = (GdkWindowObject *) window;
5631 if (private->destroyed)
5634 if (sibling == NULL)
5637 gdk_window_raise (window);
5639 gdk_window_lower (window);
5643 gdk_window_flush_if_exposing (window);
5645 if (gdk_window_is_toplevel (private))
5647 g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
5648 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5649 impl_iface->restack_toplevel (window, sibling, above);
5653 parent = private->parent;
5656 sibling_link = g_list_find (parent->children, sibling);
5657 g_return_if_fail (sibling_link != NULL);
5658 if (sibling_link == NULL)
5661 parent->children = g_list_remove (parent->children, window);
5663 parent->children = g_list_insert_before (parent->children,
5667 parent->children = g_list_insert_before (parent->children,
5671 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5672 if (gdk_window_has_impl (private))
5674 above_native = find_native_sibling_above (parent, private);
5677 listhead.data = window;
5678 listhead.next = NULL;
5679 listhead.prev = NULL;
5680 impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
5683 impl_iface->raise (window);
5687 native_children = NULL;
5688 get_all_native_children (private, &native_children);
5689 if (native_children != NULL)
5691 above_native = find_native_sibling_above (parent, private);
5693 impl_iface->restack_under ((GdkWindow *)above_native,
5697 /* Right order, since native_children is bottom-topmost first */
5698 for (l = native_children; l != NULL; l = l->next)
5699 impl_iface->raise (l->data);
5702 g_list_free (native_children);
5707 recompute_visible_regions (private, TRUE, FALSE);
5709 _gdk_synthesize_crossing_events_for_geometry_change (window);
5710 gdk_window_invalidate_in_parent (private);
5716 * @window: a #GdkWindow
5718 * Like gdk_window_show_unraised(), but also raises the window to the
5719 * top of the window stack (moves the window to the front of the
5722 * This function maps a window so it's visible onscreen. Its opposite
5723 * is gdk_window_hide().
5725 * When implementing a #GtkWidget, you should call this function on the widget's
5726 * #GdkWindow as part of the "map" method.
5729 gdk_window_show (GdkWindow *window)
5731 gdk_window_show_internal (window, TRUE);
5736 * @window: a #GdkWindow
5738 * For toplevel windows, withdraws them, so they will no longer be
5739 * known to the window manager; for all windows, unmaps them, so
5740 * they won't be displayed. Normally done automatically as
5741 * part of gtk_widget_hide().
5744 gdk_window_hide (GdkWindow *window)
5746 GdkWindowObject *private;
5747 GdkWindowImplIface *impl_iface;
5748 gboolean was_mapped, did_hide;
5750 g_return_if_fail (GDK_IS_WINDOW (window));
5752 private = (GdkWindowObject *) window;
5753 if (private->destroyed)
5756 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5758 if (gdk_window_has_impl (private))
5761 if (GDK_WINDOW_IS_MAPPED (window))
5762 gdk_synthesize_window_state (window,
5764 GDK_WINDOW_STATE_WITHDRAWN);
5766 else if (was_mapped)
5768 GdkDisplay *display;
5769 GdkDeviceManager *device_manager;
5772 /* May need to break grabs on children */
5773 display = gdk_window_get_display (window);
5774 device_manager = gdk_display_get_device_manager (display);
5776 /* Get all devices */
5777 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5778 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5779 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5781 for (d = devices; d; d = d->next)
5783 GdkDevice *device = d->data;
5785 if (_gdk_display_end_device_grab (display, device,
5786 _gdk_windowing_window_get_next_serial (display),
5789 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5792 private->state = GDK_WINDOW_STATE_WITHDRAWN;
5793 g_list_free (devices);
5796 did_hide = _gdk_window_update_viewable (window);
5798 /* Hide foreign window as those are not handled by update_viewable. */
5799 if (gdk_window_has_impl (private) && (!did_hide))
5801 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5802 impl_iface->hide (window);
5805 recompute_visible_regions (private, TRUE, FALSE);
5807 /* all decendants became non-visible, we need to send visibility notify */
5808 gdk_window_update_visibility_recursively (private, NULL);
5810 if (was_mapped && !gdk_window_has_impl (private))
5812 if (private->event_mask & GDK_STRUCTURE_MASK)
5813 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5815 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5816 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5818 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5821 /* Invalidate the rect */
5823 gdk_window_invalidate_in_parent (private);
5827 * gdk_window_withdraw:
5828 * @window: a toplevel #GdkWindow
5830 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5831 * This function is not really useful as gdk_window_hide() automatically
5832 * withdraws toplevel windows before hiding them.
5835 gdk_window_withdraw (GdkWindow *window)
5837 GdkWindowObject *private;
5838 GdkWindowImplIface *impl_iface;
5839 gboolean was_mapped;
5841 g_return_if_fail (GDK_IS_WINDOW (window));
5843 private = (GdkWindowObject *) window;
5844 if (private->destroyed)
5847 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5849 if (gdk_window_has_impl (private))
5851 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5852 impl_iface->withdraw (window);
5856 if (private->event_mask & GDK_STRUCTURE_MASK)
5857 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5859 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5860 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5862 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5865 recompute_visible_regions (private, TRUE, FALSE);
5870 * gdk_window_set_events:
5871 * @window: a #GdkWindow
5872 * @event_mask: event mask for @window
5874 * The event mask for a window determines which events will be reported
5875 * for that window from all master input devices. For example, an event mask
5876 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5877 * press events. The event mask is the bitwise OR of values from the
5878 * #GdkEventMask enumeration.
5881 gdk_window_set_events (GdkWindow *window,
5882 GdkEventMask event_mask)
5884 GdkWindowObject *private;
5885 GdkWindowImplIface *impl_iface;
5886 GdkDisplay *display;
5888 g_return_if_fail (GDK_IS_WINDOW (window));
5890 private = (GdkWindowObject *) window;
5891 if (private->destroyed)
5894 /* If motion hint is disabled, enable motion events again */
5895 display = gdk_window_get_display (window);
5896 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5897 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5899 GList *devices = private->devices_inside;
5903 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5904 devices = devices->next;
5908 private->event_mask = event_mask;
5910 if (gdk_window_has_impl (private))
5912 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5913 impl_iface->set_events (window,
5914 get_native_event_mask (private));
5920 * gdk_window_get_events:
5921 * @window: a #GdkWindow
5923 * Gets the event mask for @window for all master input devices. See
5924 * gdk_window_set_events().
5926 * Return value: event mask for @window
5929 gdk_window_get_events (GdkWindow *window)
5931 GdkWindowObject *private;
5933 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5935 private = (GdkWindowObject *) window;
5936 if (private->destroyed)
5939 return private->event_mask;
5943 * gdk_window_set_device_events:
5944 * @window: a #GdkWindow
5945 * @device: #GdkDevice to enable events for.
5946 * @event_mask: event mask for @window
5948 * Sets the event mask for a given device (Normally a floating device, not
5949 * attached to any visible pointer) to @window. For example, an event mask
5950 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5951 * press events. The event mask is the bitwise OR of values from the
5952 * #GdkEventMask enumeration.
5957 gdk_window_set_device_events (GdkWindow *window,
5959 GdkEventMask event_mask)
5961 GdkEventMask device_mask;
5962 GdkWindowObject *private;
5963 GdkDisplay *display;
5966 g_return_if_fail (GDK_IS_WINDOW (window));
5967 g_return_if_fail (GDK_IS_DEVICE (device));
5969 if (GDK_WINDOW_DESTROYED (window))
5972 private = (GdkWindowObject *) window;
5974 /* If motion hint is disabled, enable motion events again */
5975 display = gdk_window_get_display (window);
5976 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5977 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5978 _gdk_display_enable_motion_hints (display, device);
5980 if (G_UNLIKELY (!private->device_events))
5981 private->device_events = g_hash_table_new (NULL, NULL);
5983 if (event_mask == 0)
5985 /* FIXME: unsetting events on a master device
5986 * would restore private->event_mask
5988 g_hash_table_remove (private->device_events, device);
5991 g_hash_table_insert (private->device_events, device,
5992 GINT_TO_POINTER (event_mask));
5994 if (_gdk_native_windows)
5997 native = gdk_window_get_toplevel (window);
5999 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
6001 native = gdk_offscreen_window_get_embedder (native);
6003 if (native == NULL ||
6004 (!_gdk_window_has_impl (native) &&
6005 !gdk_window_is_viewable (native)))
6008 native = gdk_window_get_toplevel (native);
6011 device_mask = get_native_device_event_mask (private, device);
6012 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
6016 * gdk_window_get_device_events:
6017 * @window: a #GdkWindow.
6018 * @device: a #GdkDevice.
6020 * Returns the event mask for @window corresponding to an specific device.
6022 * Returns: device event mask for @window
6027 gdk_window_get_device_events (GdkWindow *window,
6030 GdkWindowObject *private;
6033 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6034 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
6036 if (GDK_WINDOW_DESTROYED (window))
6039 private = (GdkWindowObject *) window;
6041 if (!private->device_events)
6044 mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
6046 /* FIXME: device could be controlled by private->event_mask */
6052 gdk_window_move_resize_toplevel (GdkWindow *window,
6059 GdkWindowObject *private;
6060 cairo_region_t *old_region, *new_region;
6061 GdkWindowImplIface *impl_iface;
6063 int old_x, old_y, old_abs_x, old_abs_y;
6067 private = (GdkWindowObject *) window;
6075 is_resize = (width != -1) || (height != -1);
6077 if (gdk_window_is_viewable (window) &&
6078 !private->input_only)
6081 old_region = cairo_region_copy (private->clip_region);
6084 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6085 impl_iface->move_resize (window, with_move, x, y, width, height);
6087 dx = private->x - old_x;
6088 dy = private->y - old_y;
6090 old_abs_x = private->abs_x;
6091 old_abs_y = private->abs_y;
6093 /* Avoid recomputing for pure toplevel moves, for performance reasons */
6095 recompute_visible_regions (private, TRUE, FALSE);
6099 new_region = cairo_region_copy (private->clip_region);
6101 /* This is the newly exposed area (due to any resize),
6102 * X will expose it, but lets do that without the
6105 cairo_region_subtract (new_region, old_region);
6106 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
6108 cairo_region_destroy (old_region);
6109 cairo_region_destroy (new_region);
6112 _gdk_synthesize_crossing_events_for_geometry_change (window);
6117 move_native_children (GdkWindowObject *private)
6120 GdkWindowObject *child;
6121 GdkWindowImplIface *impl_iface;
6123 for (l = private->children; l; l = l->next)
6127 if (child->impl != private->impl)
6129 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
6130 impl_iface->move_resize ((GdkWindow *)child, TRUE,
6132 child->width, child->height);
6135 move_native_children (child);
6140 collect_native_child_region_helper (GdkWindowObject *window,
6142 cairo_region_t **region,
6146 GdkWindowObject *child;
6147 cairo_region_t *tmp;
6150 for (l = window->children; l != NULL; l = l->next)
6154 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
6157 if (child->impl != impl)
6159 tmp = cairo_region_copy (child->clip_region);
6160 cairo_region_translate (tmp,
6161 x_offset + child->x,
6162 y_offset + child->y);
6163 if (*region == NULL)
6167 cairo_region_union (*region, tmp);
6168 cairo_region_destroy (tmp);
6172 collect_native_child_region_helper (child, impl, region,
6173 x_offset + child->x,
6174 y_offset + child->y);
6180 static cairo_region_t *
6181 collect_native_child_region (GdkWindowObject *window,
6182 gboolean include_this)
6184 cairo_region_t *region;
6186 if (include_this && gdk_window_has_impl (window) && window->viewable)
6187 return cairo_region_copy (window->clip_region);
6191 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6198 gdk_window_move_resize_internal (GdkWindow *window,
6205 GdkWindowObject *private;
6206 cairo_region_t *old_region, *new_region, *copy_area;
6207 cairo_region_t *old_native_child_region, *new_native_child_region;
6208 GdkWindowObject *impl_window;
6209 GdkWindowImplIface *impl_iface;
6211 int old_x, old_y, old_abs_x, old_abs_y;
6214 g_return_if_fail (GDK_IS_WINDOW (window));
6216 private = (GdkWindowObject *) window;
6217 if (private->destroyed)
6220 if (gdk_window_is_toplevel (private))
6222 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6226 /* Bail early if no change */
6227 if (private->width == width &&
6228 private->height == height &&
6234 gdk_window_flush_if_exposing (window);
6236 /* Handle child windows */
6241 impl_window = gdk_window_get_impl_window (private);
6246 old_native_child_region = NULL;
6247 if (gdk_window_is_viewable (window) &&
6248 !private->input_only)
6252 old_region = cairo_region_copy (private->clip_region);
6253 /* Adjust region to parent window coords */
6254 cairo_region_translate (old_region, private->x, private->y);
6256 old_native_child_region = collect_native_child_region (private, TRUE);
6257 if (old_native_child_region)
6259 /* Adjust region to parent window coords */
6260 cairo_region_translate (old_native_child_region, private->x, private->y);
6262 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6263 * source or destination for a delayed GdkWindowRegionMove. So, we need
6264 * to flush those here for the parent window and all overlapped subwindows
6265 * of it. And we need to do this before setting the new clips as those will be
6268 gdk_window_flush_recursive (private->parent);
6272 /* Set the new position and size */
6278 if (!(width < 0 && height < 0))
6282 private->width = width;
6285 private->height = height;
6288 dx = private->x - old_x;
6289 dy = private->y - old_y;
6291 old_abs_x = private->abs_x;
6292 old_abs_y = private->abs_y;
6294 recompute_visible_regions (private, TRUE, FALSE);
6296 new_native_child_region = NULL;
6297 if (old_native_child_region)
6299 new_native_child_region = collect_native_child_region (private, TRUE);
6300 /* Adjust region to parent window coords */
6301 cairo_region_translate (new_native_child_region, private->x, private->y);
6304 if (gdk_window_has_impl (private))
6306 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6308 /* Do the actual move after recomputing things, as this will have set the shape to
6309 the now correct one, thus avoiding copying regions that should not be copied. */
6310 impl_iface->move_resize (window, TRUE,
6311 private->x, private->y,
6312 private->width, private->height);
6314 else if (old_abs_x != private->abs_x ||
6315 old_abs_y != private->abs_y)
6316 move_native_children (private);
6320 new_region = cairo_region_copy (private->clip_region);
6321 /* Adjust region to parent window coords */
6322 cairo_region_translate (new_region, private->x, private->y);
6325 * Part of the data at the new location can be copied from the
6326 * old location, this area is the intersection of the old region
6327 * moved as the copy will move it and then intersected with
6331 * Everything in the old and new regions that is not copied must be
6332 * invalidated (including children) as this is newly exposed
6334 copy_area = cairo_region_copy (new_region);
6336 cairo_region_union (new_region, old_region);
6338 if (old_native_child_region)
6340 /* Don't copy from inside native children, as this is copied by
6341 * the native window move.
6343 cairo_region_subtract (old_region, old_native_child_region);
6345 cairo_region_translate (old_region, dx, dy);
6347 cairo_region_intersect (copy_area, old_region);
6349 if (new_native_child_region)
6351 /* Don't copy any bits that would cause a read from the moved
6352 native windows, as we can't read that data */
6353 cairo_region_translate (new_native_child_region, dx, dy);
6354 cairo_region_subtract (copy_area, new_native_child_region);
6355 cairo_region_translate (new_native_child_region, -dx, -dy);
6358 cairo_region_subtract (new_region, copy_area);
6360 /* Convert old region to impl coords */
6361 cairo_region_translate (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
6363 /* convert from parent coords to impl */
6364 cairo_region_translate (copy_area, private->abs_x - private->x, private->abs_y - private->y);
6366 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6368 /* Invalidate affected part in the parent window
6369 * (no higher window should be affected)
6370 * We also invalidate any children in that area, which could include
6371 * this window if it still overlaps that area.
6373 if (old_native_child_region)
6375 /* No need to expose the region that the native window move copies */
6376 cairo_region_translate (old_native_child_region, dx, dy);
6377 cairo_region_intersect (old_native_child_region, new_native_child_region);
6378 cairo_region_subtract (new_region, old_native_child_region);
6380 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
6382 cairo_region_destroy (old_region);
6383 cairo_region_destroy (new_region);
6386 if (old_native_child_region)
6388 cairo_region_destroy (old_native_child_region);
6389 cairo_region_destroy (new_native_child_region);
6392 _gdk_synthesize_crossing_events_for_geometry_change (window);
6399 * @window: a #GdkWindow
6400 * @x: X coordinate relative to window's parent
6401 * @y: Y coordinate relative to window's parent
6403 * Repositions a window relative to its parent window.
6404 * For toplevel windows, window managers may ignore or modify the move;
6405 * you should probably use gtk_window_move() on a #GtkWindow widget
6406 * anyway, instead of using GDK functions. For child windows,
6407 * the move will reliably succeed.
6409 * If you're also planning to resize the window, use gdk_window_move_resize()
6410 * to both move and resize simultaneously, for a nicer visual effect.
6413 gdk_window_move (GdkWindow *window,
6417 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6421 * gdk_window_resize:
6422 * @window: a #GdkWindow
6423 * @width: new width of the window
6424 * @height: new height of the window
6426 * Resizes @window; for toplevel windows, asks the window manager to resize
6427 * the window. The window manager may not allow the resize. When using GTK+,
6428 * use gtk_window_resize() instead of this low-level GDK function.
6430 * Windows may not be resized below 1x1.
6432 * If you're also planning to move the window, use gdk_window_move_resize()
6433 * to both move and resize simultaneously, for a nicer visual effect.
6436 gdk_window_resize (GdkWindow *window,
6440 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6445 * gdk_window_move_resize:
6446 * @window: a #GdkWindow
6447 * @x: new X position relative to window's parent
6448 * @y: new Y position relative to window's parent
6450 * @height: new height
6452 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6453 * except that both operations are performed at once, avoiding strange
6454 * visual effects. (i.e. the user may be able to see the window first
6455 * move, then resize, if you don't use gdk_window_move_resize().)
6458 gdk_window_move_resize (GdkWindow *window,
6464 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6469 * gdk_window_scroll:
6470 * @window: a #GdkWindow
6471 * @dx: Amount to scroll in the X direction
6472 * @dy: Amount to scroll in the Y direction
6474 * Scroll the contents of @window, both pixels and children, by the
6475 * given amount. @window itself does not move. Portions of the window
6476 * that the scroll operation brings in from offscreen areas are
6477 * invalidated. The invalidated region may be bigger than what would
6478 * strictly be necessary.
6480 * For X11, a minimum area will be invalidated if the window has no
6481 * subwindows, or if the edges of the window's parent do not extend
6482 * beyond the edges of the window. In other cases, a multi-step process
6483 * is used to scroll the window which may produce temporary visual
6484 * artifacts and unnecessary invalidations.
6487 gdk_window_scroll (GdkWindow *window,
6491 GdkWindowObject *private = (GdkWindowObject *) window;
6492 GdkWindowObject *impl_window;
6493 cairo_region_t *copy_area, *noncopy_area;
6494 cairo_region_t *old_native_child_region, *new_native_child_region;
6497 g_return_if_fail (GDK_IS_WINDOW (window));
6499 if (dx == 0 && dy == 0)
6502 if (private->destroyed)
6505 gdk_window_flush_if_exposing (window);
6507 old_native_child_region = collect_native_child_region (private, FALSE);
6508 if (old_native_child_region)
6510 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6511 * source or destination for a delayed GdkWindowRegionMove. So, we need
6512 * to flush those here for the window and all overlapped subwindows
6513 * of it. And we need to do this before setting the new clips as those will be
6516 gdk_window_flush_recursive (private);
6520 /* First move all child windows, without causing invalidation */
6522 tmp_list = private->children;
6525 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6526 GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
6528 /* Just update the positions, the bits will move with the copy */
6532 tmp_list = tmp_list->next;
6535 recompute_visible_regions (private, FALSE, TRUE);
6537 new_native_child_region = NULL;
6538 if (old_native_child_region)
6539 new_native_child_region = collect_native_child_region (private, FALSE);
6541 move_native_children (private);
6543 /* Then copy the actual bits of the window w/ child windows */
6545 impl_window = gdk_window_get_impl_window (private);
6547 /* Calculate the area that can be gotten by copying the old area */
6548 copy_area = cairo_region_copy (private->clip_region);
6549 if (old_native_child_region)
6551 /* Don't copy from inside native children, as this is copied by
6552 * the native window move.
6554 cairo_region_subtract (copy_area, old_native_child_region);
6556 /* Don't copy any bits that would cause a read from the moved
6557 native windows, as we can't read that data */
6558 cairo_region_subtract (copy_area, new_native_child_region);
6560 cairo_region_translate (copy_area, dx, dy);
6561 cairo_region_intersect (copy_area, private->clip_region);
6563 /* And the rest need to be invalidated */
6564 noncopy_area = cairo_region_copy (private->clip_region);
6565 cairo_region_subtract (noncopy_area, copy_area);
6567 /* convert from window coords to impl */
6568 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6570 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6572 /* Invalidate not copied regions */
6573 if (old_native_child_region)
6575 /* No need to expose the region that the native window move copies */
6576 cairo_region_translate (old_native_child_region, dx, dy);
6577 cairo_region_intersect (old_native_child_region, new_native_child_region);
6578 cairo_region_subtract (noncopy_area, old_native_child_region);
6580 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6582 cairo_region_destroy (noncopy_area);
6584 if (old_native_child_region)
6586 cairo_region_destroy (old_native_child_region);
6587 cairo_region_destroy (new_native_child_region);
6590 _gdk_synthesize_crossing_events_for_geometry_change (window);
6594 * gdk_window_move_region:
6595 * @window: a #GdkWindow
6596 * @region: The #cairo_region_t to move
6597 * @dx: Amount to move in the X direction
6598 * @dy: Amount to move in the Y direction
6600 * Move the part of @window indicated by @region by @dy pixels in the Y
6601 * direction and @dx pixels in the X direction. The portions of @region
6602 * that not covered by the new position of @region are invalidated.
6604 * Child windows are not moved.
6609 gdk_window_move_region (GdkWindow *window,
6610 const cairo_region_t *region,
6614 GdkWindowObject *private = (GdkWindowObject *) window;
6615 GdkWindowObject *impl_window;
6616 cairo_region_t *nocopy_area;
6617 cairo_region_t *copy_area;
6619 g_return_if_fail (GDK_IS_WINDOW (window));
6620 g_return_if_fail (region != NULL);
6622 if (dx == 0 && dy == 0)
6625 if (private->destroyed)
6628 impl_window = gdk_window_get_impl_window (private);
6630 /* compute source regions */
6631 copy_area = cairo_region_copy (region);
6632 cairo_region_intersect (copy_area, private->clip_region_with_children);
6634 /* compute destination regions */
6635 cairo_region_translate (copy_area, dx, dy);
6636 cairo_region_intersect (copy_area, private->clip_region_with_children);
6638 /* Invalidate parts of the region (source and dest) not covered
6640 nocopy_area = cairo_region_copy (region);
6641 cairo_region_translate (nocopy_area, dx, dy);
6642 cairo_region_union (nocopy_area, region);
6643 cairo_region_subtract (nocopy_area, copy_area);
6645 /* convert from window coords to impl */
6646 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6647 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6649 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6650 cairo_region_destroy (nocopy_area);
6654 * gdk_window_set_background:
6655 * @window: a #GdkWindow
6656 * @color: a #GdkColor
6658 * Sets the background color of @window. (However, when using GTK+,
6659 * set the background of a widget with gtk_widget_modify_bg() - if
6660 * you're an application - or gtk_style_set_background() - if you're
6661 * implementing a custom widget.)
6663 * See also gdk_window_set_background_pattern().
6666 gdk_window_set_background (GdkWindow *window,
6667 const GdkColor *color)
6669 cairo_pattern_t *pattern;
6671 g_return_if_fail (GDK_IS_WINDOW (window));
6673 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6674 color->green / 65535.,
6675 color->blue / 65535.);
6677 gdk_window_set_background_pattern (window, pattern);
6679 cairo_pattern_destroy (pattern);
6683 * gdk_window_set_background_rgba:
6684 * @window: a #GdkWindow
6685 * @rgba: a #GdkRGBA color
6687 * Sets the background color of @window.
6689 * See also gdk_window_set_background_pattern().
6692 gdk_window_set_background_rgba (GdkWindow *window,
6695 cairo_pattern_t *pattern;
6697 g_return_if_fail (GDK_IS_WINDOW (window));
6698 g_return_if_fail (rgba != NULL);
6700 pattern = cairo_pattern_create_rgba (rgba->red, rgba->green,
6701 rgba->blue, rgba->alpha);
6703 gdk_window_set_background_pattern (window, pattern);
6705 cairo_pattern_destroy (pattern);
6709 * gdk_window_set_background_pattern:
6710 * @window: a #GdkWindow
6711 * @pattern: (allow-none): a pattern to use, or %NULL
6713 * Sets the background of @window.
6715 * A background of %NULL means that the window will inherit its
6716 * background form its parent window.
6718 * The windowing system will normally fill a window with its background
6719 * when the window is obscured then exposed.
6722 gdk_window_set_background_pattern (GdkWindow *window,
6723 cairo_pattern_t *pattern)
6725 GdkWindowObject *private;
6727 g_return_if_fail (GDK_IS_WINDOW (window));
6729 private = (GdkWindowObject *) window;
6732 cairo_pattern_reference (pattern);
6733 if (private->background)
6734 cairo_pattern_destroy (private->background);
6735 private->background = pattern;
6737 if (gdk_window_has_impl (private) &&
6738 !private->input_only)
6740 GdkWindowImplIface *impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6741 impl_iface->set_background (window, pattern);
6746 * gdk_window_get_background_pattern:
6749 * Gets the pattern used to clear the background on @window. If @window
6750 * does not have its own background and reuses the parent's, %NULL is
6751 * returned and you'll have to query it yourself.
6753 * Returns: The pattern to use for the background or %NULL to use the
6754 * parent's background.
6759 gdk_window_get_background_pattern (GdkWindow *window)
6761 GdkWindowObject *private = (GdkWindowObject *) window;
6763 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6765 return private->background;
6769 update_cursor_foreach (GdkDisplay *display,
6771 GdkPointerWindowInfo *pointer_info,
6774 GdkWindow *window = user_data;
6775 GdkWindowObject *private = (GdkWindowObject *) window;
6777 if (_gdk_native_windows ||
6778 private->window_type == GDK_WINDOW_ROOT ||
6779 private->window_type == GDK_WINDOW_FOREIGN)
6780 GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_device_cursor (window, device, private->cursor);
6781 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6782 update_cursor (display, device);
6786 * gdk_window_get_cursor:
6787 * @window: a #GdkWindow
6789 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6790 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6791 * there is no custom cursor set on the specified window, and it is
6792 * using the cursor for its parent window.
6794 * Return value: a #GdkCursor, or %NULL. The returned object is owned
6795 * by the #GdkWindow and should not be unreferenced directly. Use
6796 * gdk_window_set_cursor() to unset the cursor of the window
6801 gdk_window_get_cursor (GdkWindow *window)
6803 GdkWindowObject *private;
6805 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6807 private = (GdkWindowObject *) window;
6809 return private->cursor;
6813 * gdk_window_set_cursor:
6814 * @window: a #GdkWindow
6815 * @cursor: (allow-none): a cursor
6817 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6818 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6819 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6820 * to gdk_window_set_cursor() means that @window will use the cursor of its
6821 * parent window. Most windows should use this default.
6824 gdk_window_set_cursor (GdkWindow *window,
6827 GdkWindowObject *private;
6828 GdkDisplay *display;
6830 g_return_if_fail (GDK_IS_WINDOW (window));
6832 private = (GdkWindowObject *) window;
6833 display = gdk_window_get_display (window);
6835 if (private->cursor)
6837 gdk_cursor_unref (private->cursor);
6838 private->cursor = NULL;
6841 if (!GDK_WINDOW_DESTROYED (window))
6844 private->cursor = gdk_cursor_ref (cursor);
6846 _gdk_display_pointer_info_foreach (display,
6847 update_cursor_foreach,
6850 g_object_notify (G_OBJECT (window), "cursor");
6855 * gdk_window_get_device_cursor:
6856 * @window: a #GdkWindow.
6857 * @device: a #GdkDevice.
6859 * Retrieves a #GdkCursor pointer for the @device currently set on the
6860 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6861 * there is no custom cursor set on the specified window, and it is
6862 * using the cursor for its parent window.
6864 * Returns: a #GdkCursor, or %NULL. The returned object is owned
6865 * by the #GdkWindow and should not be unreferenced directly. Use
6866 * gdk_window_set_cursor() to unset the cursor of the window
6871 gdk_window_get_device_cursor (GdkWindow *window,
6874 GdkWindowObject *private;
6876 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6877 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6879 private = (GdkWindowObject *) window;
6881 return g_hash_table_lookup (private->device_cursor, device);
6885 * gdk_window_set_device_cursor:
6886 * @window: a #Gdkwindow
6887 * @device: a #GdkDevice
6888 * @cursor: a #GdkCursor
6890 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6891 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6892 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6893 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6894 * @window will use the cursor of its parent window. Most windows should
6900 gdk_window_set_device_cursor (GdkWindow *window,
6904 GdkWindowObject *private;
6905 GdkDisplay *display;
6907 g_return_if_fail (GDK_IS_WINDOW (window));
6908 g_return_if_fail (GDK_IS_DEVICE (device));
6910 private = (GdkWindowObject *) window;
6911 display = gdk_window_get_display (window);
6914 g_hash_table_remove (private->device_cursor, device);
6916 g_hash_table_replace (private->device_cursor, device, gdk_cursor_ref (cursor));
6918 if (!GDK_WINDOW_DESTROYED (window))
6920 GdkPointerWindowInfo *pointer_info;
6922 pointer_info = _gdk_display_get_pointer_info (display, device);
6924 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6925 update_cursor (display, device);
6930 * gdk_window_get_geometry:
6931 * @window: a #GdkWindow
6932 * @x: return location for X coordinate of window (relative to its parent)
6933 * @y: return location for Y coordinate of window (relative to its parent)
6934 * @width: return location for width of window
6935 * @height: return location for height of window
6936 * @depth: return location for bit depth of window
6938 * Any of the return location arguments to this function may be %NULL,
6939 * if you aren't interested in getting the value of that field.
6941 * The X and Y coordinates returned are relative to the parent window
6942 * of @window, which for toplevels usually means relative to the
6943 * window decorations (titlebar, etc.) rather than relative to the
6944 * root window (screen-size background window).
6946 * On the X11 platform, the geometry is obtained from the X server,
6947 * so reflects the latest position of @window; this may be out-of-sync
6948 * with the position of @window delivered in the most-recently-processed
6949 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6950 * position from the most recent configure event.
6953 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6954 * to call gdk_window_get_position(), gdk_window_get_width() and
6955 * gdk_window_get_height() instead, because it avoids the roundtrip to
6956 * the X server and because these functions support the full 32-bit
6957 * coordinate space, whereas gdk_window_get_geometry() is restricted to
6958 * the 16-bit coordinates of X11.
6962 gdk_window_get_geometry (GdkWindow *window,
6969 GdkWindowObject *private, *parent;
6970 GdkWindowImplIface *impl_iface;
6974 GDK_NOTE (MULTIHEAD,
6975 g_message ("gdk_window_get_geometry(): Window needs "
6976 "to be non-NULL to be multi head safe"));
6977 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
6980 g_return_if_fail (GDK_IS_WINDOW (window));
6982 private = (GdkWindowObject *) window;
6984 if (!GDK_WINDOW_DESTROYED (window))
6986 if (gdk_window_has_impl (private))
6988 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6989 impl_iface->get_geometry (window, x, y,
6992 /* This reports the position wrt to the native parent, we need to convert
6993 it to be relative to the client side parent */
6994 parent = private->parent;
6995 if (parent && !gdk_window_has_impl (parent))
6998 *x -= parent->abs_x;
7000 *y -= parent->abs_y;
7010 *width = private->width;
7012 *height = private->height;
7014 *depth = private->depth;
7020 * gdk_window_get_width:
7021 * @window: a #GdkWindow
7023 * Returns the width of the given @window.
7025 * On the X11 platform the returned size is the size reported in the
7026 * most-recently-processed configure event, rather than the current
7027 * size on the X server.
7029 * Returns: The width of @window
7034 gdk_window_get_width (GdkWindow *window)
7036 GdkWindowObject *private;
7038 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7040 private = (GdkWindowObject *) window;
7042 return private->width;
7046 * gdk_window_get_height:
7047 * @window: a #GdkWindow
7049 * Returns the height of the given @window.
7051 * On the X11 platform the returned size is the size reported in the
7052 * most-recently-processed configure event, rather than the current
7053 * size on the X server.
7055 * Returns: The height of @window
7060 gdk_window_get_height (GdkWindow *window)
7062 GdkWindowObject *private;
7064 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7066 private = (GdkWindowObject *) window;
7068 return private->height;
7072 * gdk_window_get_origin:
7073 * @window: a #GdkWindow
7074 * @x: return location for X coordinate
7075 * @y: return location for Y coordinate
7077 * Obtains the position of a window in root window coordinates.
7078 * (Compare with gdk_window_get_position() and
7079 * gdk_window_get_geometry() which return the position of a window
7080 * relative to its parent window.)
7082 * Return value: not meaningful, ignore
7085 gdk_window_get_origin (GdkWindow *window,
7089 GdkWindowObject *private;
7090 GdkWindowImplIface *impl_iface;
7092 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7094 if (GDK_WINDOW_DESTROYED (window))
7103 private = (GdkWindowObject *) window;
7105 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7106 impl_iface->get_root_coords (window,
7115 * gdk_window_get_root_coords:
7116 * @window: a #GdkWindow
7117 * @x: X coordinate in window
7118 * @y: Y coordinate in window
7119 * @root_x: return location for X coordinate
7120 * @root_y: return location for Y coordinate
7122 * Obtains the position of a window position in root
7123 * window coordinates. This is similar to
7124 * gdk_window_get_origin() but allows you go pass
7125 * in any position in the window, not just the origin.
7130 gdk_window_get_root_coords (GdkWindow *window,
7136 GdkWindowObject *private;
7137 GdkWindowImplIface *impl_iface;
7139 g_return_if_fail (GDK_IS_WINDOW (window));
7141 private = (GdkWindowObject *) window;
7143 if (GDK_WINDOW_DESTROYED (window))
7152 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7153 impl_iface->get_root_coords (window,
7160 * gdk_window_coords_to_parent:
7161 * @window: a child window
7162 * @x: X coordinate in child's coordinate system
7163 * @y: Y coordinate in child's coordinate system
7164 * @parent_x: (out) (allow-none): return location for X coordinate
7165 * in parent's coordinate system, or %NULL
7166 * @parent_y: (out) (allow-none): return location for Y coordinate
7167 * in parent's coordinate system, or %NULL
7169 * Transforms window coordinates from a child window to its parent
7170 * window, where the parent window is the normal parent as returned by
7171 * gdk_window_get_parent() for normal windows, and the window's
7172 * embedder as returned by gdk_offscreen_window_get_embedder() for
7173 * offscreen windows.
7175 * For normal windows, calling this function is equivalent to adding
7176 * the return values of gdk_window_get_position() to the child coordinates.
7177 * For offscreen windows however (which can be arbitrarily transformed),
7178 * this function calls the GdkWindow::to-embedder: signal to translate
7181 * You should always use this function when writing generic code that
7182 * walks up a window hierarchy.
7184 * See also: gdk_window_coords_from_parent()
7189 gdk_window_coords_to_parent (GdkWindow *window,
7195 GdkWindowObject *obj;
7197 g_return_if_fail (GDK_IS_WINDOW (window));
7199 obj = (GdkWindowObject *) window;
7201 if (gdk_window_is_offscreen (obj))
7205 to_embedder (obj, x, y, &px, &py);
7216 *parent_x = x + obj->x;
7219 *parent_y = y + obj->y;
7224 * gdk_window_coords_from_parent:
7225 * @window: a child window
7226 * @parent_x: X coordinate in parent's coordinate system
7227 * @parent_y: Y coordinate in parent's coordinate system
7228 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7229 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7231 * Transforms window coordinates from a parent window to a child
7232 * window, where the parent window is the normal parent as returned by
7233 * gdk_window_get_parent() for normal windows, and the window's
7234 * embedder as returned by gdk_offscreen_window_get_embedder() for
7235 * offscreen windows.
7237 * For normal windows, calling this function is equivalent to subtracting
7238 * the return values of gdk_window_get_position() from the parent coordinates.
7239 * For offscreen windows however (which can be arbitrarily transformed),
7240 * this function calls the GdkWindow::from-embedder: signal to translate
7243 * You should always use this function when writing generic code that
7244 * walks down a window hierarchy.
7246 * See also: gdk_window_coords_to_parent()
7251 gdk_window_coords_from_parent (GdkWindow *window,
7257 GdkWindowObject *obj;
7259 g_return_if_fail (GDK_IS_WINDOW (window));
7261 obj = (GdkWindowObject *) window;
7263 if (gdk_window_is_offscreen (obj))
7267 from_embedder (obj, parent_x, parent_y, &cx, &cy);
7278 *x = parent_x - obj->x;
7281 *y = parent_y - obj->y;
7286 * gdk_window_shape_combine_region:
7287 * @window: a #GdkWindow
7288 * @shape_region: region of window to be non-transparent
7289 * @offset_x: X position of @shape_region in @window coordinates
7290 * @offset_y: Y position of @shape_region in @window coordinates
7292 * Makes pixels in @window outside @shape_region be transparent,
7293 * so that the window may be nonrectangular.
7295 * If @shape_region is %NULL, the shape will be unset, so the whole
7296 * window will be opaque again. @offset_x and @offset_y are ignored
7297 * if @shape_region is %NULL.
7299 * On the X11 platform, this uses an X server extension which is
7300 * widely available on most common platforms, but not available on
7301 * very old X servers, and occasionally the implementation will be
7302 * buggy. On servers without the shape extension, this function
7305 * This function works on both toplevel and child windows.
7308 gdk_window_shape_combine_region (GdkWindow *window,
7309 const cairo_region_t *shape_region,
7313 GdkWindowObject *private;
7314 cairo_region_t *old_region, *new_region, *diff;
7316 g_return_if_fail (GDK_IS_WINDOW (window));
7318 private = (GdkWindowObject *) window;
7320 if (GDK_WINDOW_DESTROYED (window))
7323 private->shaped = (shape_region != NULL);
7326 cairo_region_destroy (private->shape);
7329 if (GDK_WINDOW_IS_MAPPED (window))
7330 old_region = cairo_region_copy (private->clip_region);
7334 private->shape = cairo_region_copy (shape_region);
7335 cairo_region_translate (private->shape, offset_x, offset_y);
7338 private->shape = NULL;
7340 recompute_visible_regions (private, TRUE, FALSE);
7342 if (gdk_window_has_impl (private) &&
7343 !should_apply_clip_as_shape (private))
7344 apply_shape (private, private->shape);
7348 new_region = cairo_region_copy (private->clip_region);
7350 /* New area in the window, needs invalidation */
7351 diff = cairo_region_copy (new_region);
7352 cairo_region_subtract (diff, old_region);
7354 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7356 cairo_region_destroy (diff);
7358 if (!gdk_window_is_toplevel (private))
7360 /* New area in the non-root parent window, needs invalidation */
7361 diff = cairo_region_copy (old_region);
7362 cairo_region_subtract (diff, new_region);
7364 /* Adjust region to parent window coords */
7365 cairo_region_translate (diff, private->x, private->y);
7367 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
7369 cairo_region_destroy (diff);
7372 cairo_region_destroy (new_region);
7373 cairo_region_destroy (old_region);
7378 do_child_shapes (GdkWindow *window,
7381 GdkWindowObject *private;
7383 cairo_region_t *region;
7385 private = (GdkWindowObject *) window;
7389 r.width = private->width;
7390 r.height = private->height;
7392 region = cairo_region_create_rectangle (&r);
7393 remove_child_area (private, NULL, FALSE, region);
7395 if (merge && private->shape)
7396 cairo_region_subtract (region, private->shape);
7398 gdk_window_shape_combine_region (window, region, 0, 0);
7402 * gdk_window_set_child_shapes:
7403 * @window: a #GdkWindow
7405 * Sets the shape mask of @window to the union of shape masks
7406 * for all children of @window, ignoring the shape mask of @window
7407 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7408 * the shape mask of @window in the masks to be merged.
7411 gdk_window_set_child_shapes (GdkWindow *window)
7413 g_return_if_fail (GDK_IS_WINDOW (window));
7415 do_child_shapes (window, FALSE);
7419 * gdk_window_merge_child_shapes:
7420 * @window: a #GdkWindow
7422 * Merges the shape masks for any child windows into the
7423 * shape mask for @window. i.e. the union of all masks
7424 * for @window and its children will become the new mask
7425 * for @window. See gdk_window_shape_combine_region().
7427 * This function is distinct from gdk_window_set_child_shapes()
7428 * because it includes @window's shape mask in the set of shapes to
7432 gdk_window_merge_child_shapes (GdkWindow *window)
7434 g_return_if_fail (GDK_IS_WINDOW (window));
7436 do_child_shapes (window, TRUE);
7440 * gdk_window_input_shape_combine_region:
7441 * @window: a #GdkWindow
7442 * @shape_region: region of window to be non-transparent
7443 * @offset_x: X position of @shape_region in @window coordinates
7444 * @offset_y: Y position of @shape_region in @window coordinates
7446 * Like gdk_window_shape_combine_region(), but the shape applies
7447 * only to event handling. Mouse events which happen while
7448 * the pointer position corresponds to an unset bit in the
7449 * mask will be passed on the window below @window.
7451 * An input shape is typically used with RGBA windows.
7452 * The alpha channel of the window defines which pixels are
7453 * invisible and allows for nicely antialiased borders,
7454 * and the input shape controls where the window is
7457 * On the X11 platform, this requires version 1.1 of the
7460 * On the Win32 platform, this functionality is not present and the
7461 * function does nothing.
7466 gdk_window_input_shape_combine_region (GdkWindow *window,
7467 const cairo_region_t *shape_region,
7471 GdkWindowObject *private;
7472 GdkWindowImplIface *impl_iface;
7474 g_return_if_fail (GDK_IS_WINDOW (window));
7476 private = (GdkWindowObject *) window;
7478 if (GDK_WINDOW_DESTROYED (window))
7481 if (private->input_shape)
7482 cairo_region_destroy (private->input_shape);
7486 private->input_shape = cairo_region_copy (shape_region);
7487 cairo_region_translate (private->input_shape, offset_x, offset_y);
7490 private->input_shape = NULL;
7492 if (gdk_window_has_impl (private))
7494 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7495 impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
7498 /* Pointer may have e.g. moved outside window due to the input mask change */
7499 _gdk_synthesize_crossing_events_for_geometry_change (window);
7503 do_child_input_shapes (GdkWindow *window,
7506 GdkWindowObject *private;
7508 cairo_region_t *region;
7510 private = (GdkWindowObject *) window;
7514 r.width = private->width;
7515 r.height = private->height;
7517 region = cairo_region_create_rectangle (&r);
7518 remove_child_area (private, NULL, TRUE, region);
7520 if (merge && private->shape)
7521 cairo_region_subtract (region, private->shape);
7522 if (merge && private->input_shape)
7523 cairo_region_subtract (region, private->input_shape);
7525 gdk_window_input_shape_combine_region (window, region, 0, 0);
7530 * gdk_window_set_child_input_shapes:
7531 * @window: a #GdkWindow
7533 * Sets the input shape mask of @window to the union of input shape masks
7534 * for all children of @window, ignoring the input shape mask of @window
7535 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7536 * the input shape mask of @window in the masks to be merged.
7541 gdk_window_set_child_input_shapes (GdkWindow *window)
7543 g_return_if_fail (GDK_IS_WINDOW (window));
7545 do_child_input_shapes (window, FALSE);
7549 * gdk_window_merge_child_input_shapes:
7550 * @window: a #GdkWindow
7552 * Merges the input shape masks for any child windows into the
7553 * input shape mask for @window. i.e. the union of all input masks
7554 * for @window and its children will become the new input mask
7555 * for @window. See gdk_window_input_shape_combine_region().
7557 * This function is distinct from gdk_window_set_child_input_shapes()
7558 * because it includes @window's input shape mask in the set of
7559 * shapes to be merged.
7564 gdk_window_merge_child_input_shapes (GdkWindow *window)
7566 g_return_if_fail (GDK_IS_WINDOW (window));
7568 do_child_input_shapes (window, TRUE);
7573 * gdk_window_set_static_gravities:
7574 * @window: a #GdkWindow
7575 * @use_static: %TRUE to turn on static gravity
7577 * Set the bit gravity of the given window to static, and flag it so
7578 * all children get static subwindow gravity. This is used if you are
7579 * implementing scary features that involve deep knowledge of the
7580 * windowing system. Don't worry about it unless you have to.
7582 * Return value: %TRUE if the server supports static gravity
7585 gdk_window_set_static_gravities (GdkWindow *window,
7586 gboolean use_static)
7588 GdkWindowObject *private;
7589 GdkWindowImplIface *impl_iface;
7591 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7593 private = (GdkWindowObject *) window;
7595 if (gdk_window_has_impl (private))
7597 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7598 return impl_iface->set_static_gravities (window, use_static);
7605 * gdk_window_get_composited:
7606 * @window: a #GdkWindow
7608 * Determines whether @window is composited.
7610 * See gdk_window_set_composited().
7612 * Returns: %TRUE if the window is composited.
7617 gdk_window_get_composited (GdkWindow *window)
7619 GdkWindowObject *private;
7621 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7623 private = (GdkWindowObject *)window;
7625 return private->composited;
7629 * gdk_window_set_composited:
7630 * @window: a #GdkWindow
7631 * @composited: %TRUE to set the window as composited
7633 * Sets a #GdkWindow as composited, or unsets it. Composited
7634 * windows do not automatically have their contents drawn to
7635 * the screen. Drawing is redirected to an offscreen buffer
7636 * and an expose event is emitted on the parent of the composited
7637 * window. It is the responsibility of the parent's expose handler
7638 * to manually merge the off-screen content onto the screen in
7639 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7642 * It only makes sense for child windows to be composited; see
7643 * gdk_window_set_opacity() if you need translucent toplevel
7646 * An additional effect of this call is that the area of this
7647 * window is no longer clipped from regions marked for
7648 * invalidation on its parent. Draws done on the parent
7649 * window are also no longer clipped by the child.
7651 * This call is only supported on some systems (currently,
7652 * only X11 with new enough Xcomposite and Xdamage extensions).
7653 * You must call gdk_display_supports_composite() to check if
7654 * setting a window as composited is supported before
7655 * attempting to do so.
7660 gdk_window_set_composited (GdkWindow *window,
7661 gboolean composited)
7663 GdkWindowObject *private = (GdkWindowObject *)window;
7664 GdkDisplay *display;
7666 g_return_if_fail (GDK_IS_WINDOW (window));
7668 composited = composited != FALSE;
7670 if (private->composited == composited)
7674 gdk_window_ensure_native (window);
7676 display = gdk_window_get_display (window);
7678 if (!gdk_display_supports_composite (display) && composited)
7680 g_warning ("gdk_window_set_composited called but "
7681 "compositing is not supported");
7685 _gdk_windowing_window_set_composited (window, composited);
7687 recompute_visible_regions (private, TRUE, FALSE);
7689 if (GDK_WINDOW_IS_MAPPED (window))
7690 gdk_window_invalidate_in_parent (private);
7692 private->composited = composited;
7696 * gdk_window_get_modal_hint:
7697 * @window: A toplevel #GdkWindow.
7699 * Determines whether or not the window manager is hinted that @window
7700 * has modal behaviour.
7702 * Return value: whether or not the window has the modal hint set.
7707 gdk_window_get_modal_hint (GdkWindow *window)
7709 GdkWindowObject *private;
7711 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7713 private = (GdkWindowObject*) window;
7715 return private->modal_hint;
7719 * gdk_window_get_accept_focus:
7720 * @window: a toplevel #GdkWindow.
7722 * Determines whether or not the desktop environment shuld be hinted that
7723 * the window does not want to receive input focus.
7725 * Return value: whether or not the window should receive input focus.
7730 gdk_window_get_accept_focus (GdkWindow *window)
7732 GdkWindowObject *private;
7734 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7736 private = (GdkWindowObject *)window;
7738 return private->accept_focus;
7742 * gdk_window_get_focus_on_map:
7743 * @window: a toplevel #GdkWindow.
7745 * Determines whether or not the desktop environment should be hinted that the
7746 * window does not want to receive input focus when it is mapped.
7748 * Return value: whether or not the window wants to receive input focus when
7754 gdk_window_get_focus_on_map (GdkWindow *window)
7756 GdkWindowObject *private;
7758 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7760 private = (GdkWindowObject *)window;
7762 return private->focus_on_map;
7766 * gdk_window_is_input_only:
7767 * @window: a toplevel #GdkWindow
7769 * Determines whether or not the window is an input only window.
7771 * Return value: %TRUE if @window is input only
7776 gdk_window_is_input_only (GdkWindow *window)
7778 GdkWindowObject *private;
7780 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7782 private = (GdkWindowObject *)window;
7784 return private->input_only;
7788 * gdk_window_is_shaped:
7789 * @window: a toplevel #GdkWindow
7791 * Determines whether or not the window is shaped.
7793 * Return value: %TRUE if @window is shaped
7798 gdk_window_is_shaped (GdkWindow *window)
7800 GdkWindowObject *private;
7802 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7804 private = (GdkWindowObject *)window;
7806 return private->shaped;
7810 window_get_size_rectangle (GdkWindow *window,
7813 GdkWindowObject *private = (GdkWindowObject *) window;
7815 rect->x = rect->y = 0;
7816 rect->width = private->width;
7817 rect->height = private->height;
7820 /* Calculates the real clipping region for a window, in window coordinates,
7821 * taking into account other windows, gc clip region and gc clip mask.
7824 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7825 GdkWindow *base_window,
7826 gboolean do_children,
7827 gint *base_x_offset,
7828 gint *base_y_offset)
7830 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
7831 GdkRectangle visible_rect;
7832 cairo_region_t *real_clip_region;
7833 gint x_offset, y_offset;
7834 GdkWindowObject *parentwin, *lastwin;
7841 if (!private->viewable || private->input_only)
7842 return cairo_region_create ();
7844 window_get_size_rectangle (window, &visible_rect);
7846 /* real_clip_region is in window coordinates */
7847 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7849 x_offset = y_offset = 0;
7853 parentwin = lastwin;
7855 parentwin = lastwin->parent;
7857 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7858 for (; parentwin != NULL &&
7859 (parentwin == private || lastwin != (GdkWindowObject*) base_window);
7860 lastwin = parentwin, parentwin = lastwin->parent)
7863 GdkRectangle real_clip_rect;
7865 if (parentwin != private)
7867 x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
7868 y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
7871 /* children is ordered in reverse stack order */
7872 for (cur = parentwin->children;
7873 cur && cur->data != lastwin;
7876 GdkWindow *child = cur->data;
7877 GdkWindowObject *child_private = (GdkWindowObject *)child;
7879 if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
7882 /* Ignore offscreen children, as they don't draw in their parent and
7883 * don't take part in the clipping */
7884 if (gdk_window_is_offscreen (child_private))
7887 window_get_size_rectangle (child, &visible_rect);
7889 /* Convert rect to "window" coords */
7890 visible_rect.x += child_private->x - x_offset;
7891 visible_rect.y += child_private->y - y_offset;
7893 /* This shortcut is really necessary for performance when there are a lot of windows */
7894 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7895 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7896 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7897 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7898 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7901 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7904 /* Clip to the parent */
7905 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7906 /* Convert rect to "window" coords */
7907 visible_rect.x += - x_offset;
7908 visible_rect.y += - y_offset;
7910 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7914 *base_x_offset = x_offset;
7916 *base_y_offset = y_offset;
7918 return real_clip_region;
7922 _gdk_window_add_damage (GdkWindow *toplevel,
7923 cairo_region_t *damaged_region)
7925 GdkDisplay *display;
7926 GdkEvent event = { 0, };
7927 event.expose.type = GDK_DAMAGE;
7928 event.expose.window = toplevel;
7929 event.expose.send_event = FALSE;
7930 event.expose.region = damaged_region;
7931 cairo_region_get_extents (event.expose.region, &event.expose.area);
7932 display = gdk_window_get_display (event.expose.window);
7933 _gdk_event_queue_append (display, gdk_event_copy (&event));
7936 /* Gets the toplevel for a window as used for events,
7937 i.e. including offscreen parents */
7938 static GdkWindowObject *
7939 get_event_parent (GdkWindowObject *window)
7941 if (gdk_window_is_offscreen (window))
7942 return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7944 return window->parent;
7947 /* Gets the toplevel for a window as used for events,
7948 i.e. including offscreen parents going up to the native
7951 get_event_toplevel (GdkWindow *w)
7953 GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
7954 GdkWindowObject *parent;
7956 while ((parent = get_event_parent (private)) != NULL &&
7957 (parent->window_type != GDK_WINDOW_ROOT))
7960 return GDK_WINDOW (private);
7964 _gdk_window_event_parent_of (GdkWindow *parent,
7975 w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
7982 update_cursor (GdkDisplay *display,
7985 GdkWindowObject *cursor_window, *parent, *toplevel;
7986 GdkWindow *pointer_window;
7987 GdkWindowImplIface *impl_iface;
7988 GdkPointerWindowInfo *pointer_info;
7989 GdkDeviceGrabInfo *grab;
7992 pointer_info = _gdk_display_get_pointer_info (display, device);
7993 pointer_window = pointer_info->window_under_pointer;
7995 /* We ignore the serials here and just pick the last grab
7996 we've sent, as that would shortly be used anyway. */
7997 grab = _gdk_display_get_last_device_grab (display, device);
8000 /* the pointer is not in a descendant of the grab window */
8001 !_gdk_window_event_parent_of (grab->window, pointer_window))
8003 /* use the cursor from the grab window */
8004 cursor_window = (GdkWindowObject *) grab->window;
8008 /* otherwise use the cursor from the pointer window */
8009 cursor_window = (GdkWindowObject *) pointer_window;
8012 /* Find the first window with the cursor actually set, as
8013 the cursor is inherited from the parent */
8014 while (cursor_window->cursor == NULL &&
8015 (parent = get_event_parent (cursor_window)) != NULL &&
8016 parent->window_type != GDK_WINDOW_ROOT)
8017 cursor_window = parent;
8019 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
8022 cursor = cursor_window->cursor;
8024 /* Set all cursors on toplevel, otherwise its tricky to keep track of
8025 * which native window has what cursor set. */
8026 toplevel = (GdkWindowObject *) get_event_toplevel (pointer_window);
8027 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
8028 impl_iface->set_device_cursor ((GdkWindow *) toplevel, device, cursor);
8032 point_in_window (GdkWindowObject *window,
8037 x >= 0 && x < window->width &&
8038 y >= 0 && y < window->height &&
8039 (window->shape == NULL ||
8040 cairo_region_contains_point (window->shape,
8042 (window->input_shape == NULL ||
8043 cairo_region_contains_point (window->input_shape,
8048 convert_native_coords_to_toplevel (GdkWindow *window,
8051 gdouble *toplevel_x,
8052 gdouble *toplevel_y)
8054 GdkWindowObject *private = (GdkWindowObject *)window;
8060 while (!gdk_window_is_toplevel (private))
8064 private = private->parent;
8070 return (GdkWindow *)private;
8074 convert_toplevel_coords_to_window (GdkWindow *window,
8080 GdkWindowObject *private;
8081 GdkWindowObject *parent;
8083 GList *children, *l;
8085 private = GDK_WINDOW_OBJECT (window);
8091 while ((parent = get_event_parent (private)) != NULL &&
8092 (parent->window_type != GDK_WINDOW_ROOT))
8094 children = g_list_prepend (children, private);
8098 for (l = children; l != NULL; l = l->next)
8099 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
8101 g_list_free (children);
8107 static GdkWindowObject *
8108 pick_embedded_child (GdkWindowObject *window,
8112 GdkWindowObject *res;
8115 g_signal_emit (window,
8116 signals[PICK_EMBEDDED_CHILD], 0,
8123 _gdk_window_find_child_at (GdkWindow *window,
8127 GdkWindowObject *private, *sub;
8128 double child_x, child_y;
8131 private = (GdkWindowObject *)window;
8133 if (point_in_window (private, x, y))
8135 /* Children is ordered in reverse stack order, i.e. first is topmost */
8136 for (l = private->children; l != NULL; l = l->next)
8140 if (!GDK_WINDOW_IS_MAPPED (sub))
8143 gdk_window_coords_from_parent ((GdkWindow *)sub,
8145 &child_x, &child_y);
8146 if (point_in_window (sub, child_x, child_y))
8147 return (GdkWindow *)sub;
8150 if (private->num_offscreen_children > 0)
8152 sub = pick_embedded_child (private,
8155 return (GdkWindow *)sub;
8163 _gdk_window_find_descendant_at (GdkWindow *toplevel,
8169 GdkWindowObject *private, *sub;
8170 gdouble child_x, child_y;
8174 private = (GdkWindowObject *)toplevel;
8176 if (point_in_window (private, x, y))
8181 /* Children is ordered in reverse stack order, i.e. first is topmost */
8182 for (l = private->children; l != NULL; l = l->next)
8186 if (!GDK_WINDOW_IS_MAPPED (sub))
8189 gdk_window_coords_from_parent ((GdkWindow *)sub,
8191 &child_x, &child_y);
8192 if (point_in_window (sub, child_x, child_y))
8202 private->num_offscreen_children > 0)
8204 sub = pick_embedded_child (private,
8210 from_embedder (sub, x, y, &x, &y);
8218 /* Not in window at all */
8227 return (GdkWindow *)private;
8232 * @window: a toplevel #GdkWindow
8234 * Emits a short beep associated to @window in the appropriate
8235 * display, if supported. Otherwise, emits a short beep on
8236 * the display just as gdk_display_beep().
8241 gdk_window_beep (GdkWindow *window)
8243 GdkDisplay *display;
8244 GdkWindow *toplevel;
8246 g_return_if_fail (GDK_IS_WINDOW (window));
8248 if (GDK_WINDOW_DESTROYED (window))
8251 toplevel = get_event_toplevel (window);
8252 display = gdk_window_get_display (window);
8254 if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
8255 _gdk_windowing_window_beep (toplevel);
8257 gdk_display_beep (display);
8261 * gdk_window_set_support_multidevice:
8262 * @window: a #GdkWindow.
8263 * @support_multidevice: %TRUE to enable multidevice support in @window.
8265 * This function will enable multidevice features in @window.
8267 * Multidevice aware windows will need to handle properly multiple,
8268 * per device enter/leave events, device grabs and grab ownerships.
8273 gdk_window_set_support_multidevice (GdkWindow *window,
8274 gboolean support_multidevice)
8276 GdkWindowObject *private = (GdkWindowObject *) window;
8278 g_return_if_fail (GDK_IS_WINDOW (window));
8280 if (GDK_WINDOW_DESTROYED (window))
8283 if (private->support_multidevice == support_multidevice)
8286 private->support_multidevice = support_multidevice;
8288 /* FIXME: What to do if called when some pointers are inside the window ? */
8292 * gdk_window_get_support_multidevice:
8293 * @window: a #GdkWindow.
8295 * Returns %TRUE if the window is aware of the existence of multiple
8298 * Returns: %TRUE if the window handles multidevice features.
8303 gdk_window_get_support_multidevice (GdkWindow *window)
8305 GdkWindowObject *private = (GdkWindowObject *) window;
8307 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8309 if (GDK_WINDOW_DESTROYED (window))
8312 return private->support_multidevice;
8315 static const guint type_masks[] = {
8316 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8317 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8318 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8319 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8320 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8321 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8322 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8323 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8324 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8325 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8326 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8327 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8328 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8329 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8330 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8331 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8332 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8333 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8334 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8335 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8336 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8337 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8338 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8339 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8340 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8341 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8342 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8343 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8344 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8345 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8346 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8347 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8348 0, /* GDK_WINDOW_STATE = 32 */
8349 0, /* GDK_SETTING = 33 */
8350 0, /* GDK_OWNER_CHANGE = 34 */
8351 0, /* GDK_GRAB_BROKEN = 35 */
8352 0, /* GDK_DAMAGE = 36 */
8354 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8356 /* send motion events if the right buttons are down */
8358 update_evmask_for_button_motion (guint evmask,
8359 GdkModifierType mask)
8361 if (evmask & GDK_BUTTON_MOTION_MASK &&
8362 mask & (GDK_BUTTON1_MASK |
8367 evmask |= GDK_POINTER_MOTION_MASK;
8369 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8370 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8371 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8372 evmask |= GDK_POINTER_MOTION_MASK;
8378 is_button_type (GdkEventType type)
8380 return type == GDK_BUTTON_PRESS ||
8381 type == GDK_2BUTTON_PRESS ||
8382 type == GDK_3BUTTON_PRESS ||
8383 type == GDK_BUTTON_RELEASE ||
8388 is_motion_type (GdkEventType type)
8390 return type == GDK_MOTION_NOTIFY ||
8391 type == GDK_ENTER_NOTIFY ||
8392 type == GDK_LEAVE_NOTIFY;
8395 static GdkWindowObject *
8396 find_common_ancestor (GdkWindowObject *win1,
8397 GdkWindowObject *win2)
8399 GdkWindowObject *tmp;
8400 GList *path1 = NULL, *path2 = NULL;
8401 GList *list1, *list2;
8404 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8406 path1 = g_list_prepend (path1, tmp);
8407 tmp = get_event_parent (tmp);
8411 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8413 path2 = g_list_prepend (path2, tmp);
8414 tmp = get_event_parent (tmp);
8420 while (list1 && list2 && (list1->data == list2->data))
8422 tmp = (GdkWindowObject *)list1->data;
8423 list1 = g_list_next (list1);
8424 list2 = g_list_next (list2);
8426 g_list_free (path1);
8427 g_list_free (path2);
8433 _gdk_make_event (GdkWindow *window,
8435 GdkEvent *event_in_queue,
8436 gboolean before_event)
8438 GdkEvent *event = gdk_event_new (type);
8440 GdkModifierType the_state;
8442 the_time = gdk_event_get_time (event_in_queue);
8443 gdk_event_get_state (event_in_queue, &the_state);
8445 event->any.window = g_object_ref (window);
8446 event->any.send_event = FALSE;
8447 if (event_in_queue && event_in_queue->any.send_event)
8448 event->any.send_event = TRUE;
8452 case GDK_MOTION_NOTIFY:
8453 event->motion.time = the_time;
8454 event->motion.axes = NULL;
8455 event->motion.state = the_state;
8458 case GDK_BUTTON_PRESS:
8459 case GDK_2BUTTON_PRESS:
8460 case GDK_3BUTTON_PRESS:
8461 case GDK_BUTTON_RELEASE:
8462 event->button.time = the_time;
8463 event->button.axes = NULL;
8464 event->button.state = the_state;
8468 event->scroll.time = the_time;
8469 event->scroll.state = the_state;
8473 case GDK_KEY_RELEASE:
8474 event->key.time = the_time;
8475 event->key.state = the_state;
8478 case GDK_ENTER_NOTIFY:
8479 case GDK_LEAVE_NOTIFY:
8480 event->crossing.time = the_time;
8481 event->crossing.state = the_state;
8484 case GDK_PROPERTY_NOTIFY:
8485 event->property.time = the_time;
8486 event->property.state = the_state;
8489 case GDK_SELECTION_CLEAR:
8490 case GDK_SELECTION_REQUEST:
8491 case GDK_SELECTION_NOTIFY:
8492 event->selection.time = the_time;
8495 case GDK_PROXIMITY_IN:
8496 case GDK_PROXIMITY_OUT:
8497 event->proximity.time = the_time;
8500 case GDK_DRAG_ENTER:
8501 case GDK_DRAG_LEAVE:
8502 case GDK_DRAG_MOTION:
8503 case GDK_DRAG_STATUS:
8504 case GDK_DROP_START:
8505 case GDK_DROP_FINISHED:
8506 event->dnd.time = the_time;
8509 case GDK_FOCUS_CHANGE:
8513 case GDK_CLIENT_EVENT:
8514 case GDK_VISIBILITY_NOTIFY:
8526 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8528 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8531 _gdk_event_queue_append (gdk_window_get_display (window), event);
8537 send_crossing_event (GdkDisplay *display,
8538 GdkWindowObject *toplevel,
8539 GdkWindowObject *window,
8541 GdkCrossingMode mode,
8542 GdkNotifyType notify_type,
8543 GdkWindow *subwindow,
8547 GdkModifierType mask,
8549 GdkEvent *event_in_queue,
8553 guint32 window_event_mask, type_event_mask;
8554 GdkDeviceGrabInfo *grab;
8555 gboolean block_event = FALSE;
8557 grab = _gdk_display_has_device_grab (display, device, serial);
8560 !grab->owner_events)
8562 /* !owner_event => only report events wrt grab window, ignore rest */
8563 if ((GdkWindow *)window != grab->window)
8565 window_event_mask = grab->event_mask;
8568 window_event_mask = window->event_mask;
8570 if (type == GDK_LEAVE_NOTIFY)
8572 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8573 window->devices_inside = g_list_remove (window->devices_inside, device);
8575 if (!window->support_multidevice && window->devices_inside)
8577 /* Block leave events unless it's the last pointer */
8583 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8585 if (!window->support_multidevice && window->devices_inside)
8587 /* Only emit enter events for the first device */
8591 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8592 gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
8593 !g_list_find (window->devices_inside, device))
8594 window->devices_inside = g_list_prepend (window->devices_inside, device);
8600 if (window_event_mask & type_event_mask)
8602 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8603 gdk_event_set_device (event, device);
8604 event->crossing.time = time_;
8605 event->crossing.subwindow = subwindow;
8607 g_object_ref (subwindow);
8608 convert_toplevel_coords_to_window ((GdkWindow *)window,
8609 toplevel_x, toplevel_y,
8610 &event->crossing.x, &event->crossing.y);
8611 event->crossing.x_root = toplevel_x + toplevel->x;
8612 event->crossing.y_root = toplevel_y + toplevel->y;
8613 event->crossing.mode = mode;
8614 event->crossing.detail = notify_type;
8615 event->crossing.focus = FALSE;
8616 event->crossing.state = mask;
8621 /* The coordinates are in the toplevel window that src/dest are in.
8622 * src and dest are always (if != NULL) in the same toplevel, as
8623 * we get a leave-notify and set the window_under_pointer to null
8624 * before crossing to another toplevel.
8627 _gdk_synthesize_crossing_events (GdkDisplay *display,
8631 GdkCrossingMode mode,
8634 GdkModifierType mask,
8636 GdkEvent *event_in_queue,
8638 gboolean non_linear)
8641 GdkWindowObject *win, *last, *next;
8645 GdkWindowObject *toplevel;
8646 GdkNotifyType notify_type;
8648 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8650 a = (GdkWindowObject *)src;
8651 b = (GdkWindowObject *)dest;
8653 return; /* No crossings generated between src and dest */
8655 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8657 if (a && gdk_window_get_device_events (src, device) == 0)
8660 if (b && gdk_window_get_device_events (dest, device) == 0)
8667 c = find_common_ancestor (a, b);
8669 non_linear |= (c != a) && (c != b);
8671 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8673 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
8675 /* Traverse up from a to (excluding) c sending leave events */
8677 notify_type = GDK_NOTIFY_NONLINEAR;
8679 notify_type = GDK_NOTIFY_INFERIOR;
8681 notify_type = GDK_NOTIFY_ANCESTOR;
8682 send_crossing_event (display, toplevel,
8683 a, GDK_LEAVE_NOTIFY,
8687 toplevel_x, toplevel_y,
8695 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8697 notify_type = GDK_NOTIFY_VIRTUAL;
8700 win = get_event_parent (a);
8701 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8703 send_crossing_event (display, toplevel,
8704 win, GDK_LEAVE_NOTIFY,
8709 toplevel_x, toplevel_y,
8715 win = get_event_parent (win);
8720 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8722 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
8724 /* Traverse down from c to b */
8728 win = get_event_parent (b);
8729 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8731 path = g_list_prepend (path, win);
8732 win = get_event_parent (win);
8736 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8738 notify_type = GDK_NOTIFY_VIRTUAL;
8743 win = (GdkWindowObject *)list->data;
8744 list = g_list_next (list);
8746 next = (GdkWindowObject *)list->data;
8750 send_crossing_event (display, toplevel,
8751 win, GDK_ENTER_NOTIFY,
8756 toplevel_x, toplevel_y,
8766 notify_type = GDK_NOTIFY_NONLINEAR;
8768 notify_type = GDK_NOTIFY_ANCESTOR;
8770 notify_type = GDK_NOTIFY_INFERIOR;
8772 send_crossing_event (display, toplevel,
8773 b, GDK_ENTER_NOTIFY,
8778 toplevel_x, toplevel_y,
8785 /* Returns the window inside the event window with the pointer in it
8786 * at the specified coordinates, or NULL if its not in any child of
8787 * the toplevel. It also takes into account !owner_events grabs.
8790 get_pointer_window (GdkDisplay *display,
8791 GdkWindow *event_window,
8797 GdkWindow *pointer_window;
8798 GdkDeviceGrabInfo *grab;
8799 GdkPointerWindowInfo *pointer_info;
8801 pointer_info = _gdk_display_get_pointer_info (display, device);
8803 if (event_window == pointer_info->toplevel_under_pointer)
8805 _gdk_window_find_descendant_at (event_window,
8806 toplevel_x, toplevel_y,
8809 pointer_window = NULL;
8811 grab = _gdk_display_has_device_grab (display, device, serial);
8813 !grab->owner_events &&
8814 pointer_window != grab->window)
8815 pointer_window = NULL;
8817 return pointer_window;
8821 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8825 GdkPointerWindowInfo *device_info;
8827 /* We don't track this if all native, and it can cause issues
8828 with the update_cursor call below */
8829 if (_gdk_native_windows)
8832 device_info = _gdk_display_get_pointer_info (display, device);
8834 if (device_info->window_under_pointer)
8835 g_object_unref (device_info->window_under_pointer);
8836 device_info->window_under_pointer = window;
8840 g_object_ref (window);
8841 update_cursor (display, device);
8844 _gdk_display_enable_motion_hints (display, device);
8849 * @window: the #GdkWindow which will own the grab (the grab window).
8850 * @owner_events: if %FALSE then all pointer events are reported with respect to
8851 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8852 * events for this application are reported as normal, but pointer events outside
8853 * this application are reported with respect to @window and only if selected by
8854 * @event_mask. In either mode, unreported events are discarded.
8855 * @event_mask: specifies the event mask, which is used in accordance with
8856 * @owner_events. Note that only pointer events (i.e. button and motion events)
8858 * @confine_to: If non-%NULL, the pointer will be confined to this
8859 * window during the grab. If the pointer is outside @confine_to, it will
8860 * automatically be moved to the closest edge of @confine_to and enter
8861 * and leave events will be generated as necessary.
8862 * @cursor: the cursor to display while the grab is active. If this is %NULL then
8863 * the normal cursors are used for @window and its descendants, and the cursor
8864 * for @window is used for all other windows.
8865 * @time_: the timestamp of the event which led to this pointer grab. This usually
8866 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8867 * the time isn't known.
8869 * Grabs the pointer (usually a mouse) so that all events are passed to this
8870 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8871 * the grab window becomes unviewable.
8872 * This overrides any previous pointer grab by this client.
8874 * Pointer grabs are used for operations which need complete control over mouse
8875 * events, even if the mouse leaves the application.
8876 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8877 * the #GtkHPaned and #GtkVPaned widgets.
8879 * Note that if the event mask of an X window has selected both button press and
8880 * button release events, then a button press event will cause an automatic
8881 * pointer grab until the button is released.
8882 * X does this automatically since most applications expect to receive button
8883 * press and release events in pairs.
8884 * It is equivalent to a pointer grab on the window with @owner_events set to
8887 * If you set up anything at the time you take the grab that needs to be cleaned
8888 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8889 * are emitted when the grab ends unvoluntarily.
8891 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8893 * Deprecated: 3.0: Use gdk_device_grab() instead.
8896 gdk_pointer_grab (GdkWindow * window,
8897 gboolean owner_events,
8898 GdkEventMask event_mask,
8899 GdkWindow * confine_to,
8904 GdkDisplay *display;
8905 GdkDeviceManager *device_manager;
8907 GdkGrabStatus res = 0;
8909 GList *devices, *dev;
8911 g_return_val_if_fail (window != NULL, 0);
8912 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8913 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8915 /* We need a native window for confine to to work, ensure we have one */
8918 if (!gdk_window_ensure_native (confine_to))
8920 g_warning ("Can't confine to grabbed window, not native");
8925 /* Non-viewable client side window => fail */
8926 if (!_gdk_window_has_impl (window) &&
8927 !gdk_window_is_viewable (window))
8928 return GDK_GRAB_NOT_VIEWABLE;
8930 if (_gdk_native_windows)
8933 native = gdk_window_get_toplevel (window);
8934 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
8936 native = gdk_offscreen_window_get_embedder (native);
8938 if (native == NULL ||
8939 (!_gdk_window_has_impl (native) &&
8940 !gdk_window_is_viewable (native)))
8941 return GDK_GRAB_NOT_VIEWABLE;
8943 native = gdk_window_get_toplevel (native);
8946 display = gdk_window_get_display (window);
8948 serial = _gdk_windowing_window_get_next_serial (display);
8949 device_manager = gdk_display_get_device_manager (display);
8950 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8952 /* FIXME: Should this be generic to all backends? */
8953 /* FIXME: What happens with extended devices? */
8954 for (dev = devices; dev; dev = dev->next)
8958 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
8961 res = _gdk_windowing_device_grab (device,
8965 get_native_grab_event_mask (event_mask),
8970 if (res == GDK_GRAB_SUCCESS)
8971 _gdk_display_add_device_grab (display,
8983 /* FIXME: handle errors when grabbing */
8985 g_list_free (devices);
8991 * gdk_keyboard_grab:
8992 * @window: the #GdkWindow which will own the grab (the grab window).
8993 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8994 * @window. If %TRUE then keyboard events for this application are
8995 * reported as normal, but keyboard events outside this application
8996 * are reported with respect to @window. Both key press and key
8997 * release events are always reported, independant of the event mask
8998 * set by the application.
8999 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
9002 * Grabs the keyboard so that all events are passed to this
9003 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
9004 * This overrides any previous keyboard grab by this client.
9006 * If you set up anything at the time you take the grab that needs to be cleaned
9007 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
9008 * are emitted when the grab ends unvoluntarily.
9010 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
9012 * Deprecated: 3.0: Use gdk_device_grab() instead.
9015 gdk_keyboard_grab (GdkWindow *window,
9016 gboolean owner_events,
9020 GdkDisplay *display;
9021 GdkDeviceManager *device_manager;
9023 GdkGrabStatus res = 0;
9025 GList *devices, *dev;
9027 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
9029 /* Non-viewable client side window => fail */
9030 if (!_gdk_window_has_impl (window) &&
9031 !gdk_window_is_viewable (window))
9032 return GDK_GRAB_NOT_VIEWABLE;
9034 if (_gdk_native_windows)
9037 native = gdk_window_get_toplevel (window);
9039 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
9041 native = gdk_offscreen_window_get_embedder (native);
9043 if (native == NULL ||
9044 (!_gdk_window_has_impl (native) &&
9045 !gdk_window_is_viewable (native)))
9046 return GDK_GRAB_NOT_VIEWABLE;
9048 native = gdk_window_get_toplevel (native);
9051 display = gdk_window_get_display (window);
9053 serial = _gdk_windowing_window_get_next_serial (display);
9054 device_manager = gdk_display_get_device_manager (display);
9055 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
9057 /* FIXME: Should this be generic to all backends? */
9058 /* FIXME: What happens with extended devices? */
9059 for (dev = devices; dev; dev = dev->next)
9063 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
9066 res = _gdk_windowing_device_grab (device,
9070 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
9075 if (res == GDK_GRAB_SUCCESS)
9076 _gdk_display_add_device_grab (display,
9087 /* FIXME: handle errors when grabbing */
9089 g_list_free (devices);
9095 * gdk_window_geometry_changed:
9096 * @window: an embedded offscreen #GdkWindow
9098 * This function informs GDK that the geometry of an embedded
9099 * offscreen window has changed. This is necessary for GDK to keep
9100 * track of which offscreen window the pointer is in.
9105 gdk_window_geometry_changed (GdkWindow *window)
9107 _gdk_synthesize_crossing_events_for_geometry_change (window);
9111 do_synthesize_crossing_event (gpointer data)
9113 GdkDisplay *display;
9114 GdkWindow *changed_toplevel;
9115 GdkWindowObject *changed_toplevel_priv;
9116 GHashTableIter iter;
9117 gpointer key, value;
9120 changed_toplevel = data;
9121 changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
9123 changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
9125 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9128 display = gdk_window_get_display (changed_toplevel);
9129 serial = _gdk_windowing_window_get_next_serial (display);
9130 g_hash_table_iter_init (&iter, display->pointers_info);
9132 while (g_hash_table_iter_next (&iter, &key, &value))
9134 GdkWindow *new_window_under_pointer;
9135 GdkPointerWindowInfo *pointer_info = value;
9136 GdkDevice *device = key;
9138 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9140 new_window_under_pointer =
9141 get_pointer_window (display, changed_toplevel,
9143 pointer_info->toplevel_x,
9144 pointer_info->toplevel_y,
9146 if (new_window_under_pointer != pointer_info->window_under_pointer)
9148 _gdk_synthesize_crossing_events (display,
9149 pointer_info->window_under_pointer,
9150 new_window_under_pointer,
9152 GDK_CROSSING_NORMAL,
9153 pointer_info->toplevel_x,
9154 pointer_info->toplevel_y,
9155 pointer_info->state,
9160 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9169 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9171 GdkDisplay *display;
9172 GdkWindow *toplevel;
9173 GdkWindowObject *toplevel_priv;
9175 if (_gdk_native_windows)
9176 return; /* We use the native crossing events if all native */
9178 display = gdk_window_get_display (changed_window);
9180 toplevel = get_event_toplevel (changed_window);
9181 toplevel_priv = (GdkWindowObject *) toplevel;
9183 if (!toplevel_priv->synthesize_crossing_event_queued)
9185 toplevel_priv->synthesize_crossing_event_queued = TRUE;
9187 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9188 do_synthesize_crossing_event,
9189 g_object_ref (toplevel),
9194 /* Don't use for crossing events */
9196 get_event_window (GdkDisplay *display,
9198 GdkWindow *pointer_window,
9200 GdkModifierType mask,
9205 GdkWindow *grab_window;
9207 GdkDeviceGrabInfo *grab;
9209 grab = _gdk_display_has_device_grab (display, device, serial);
9211 if (grab != NULL && !grab->owner_events)
9213 evmask = grab->event_mask;
9214 evmask = update_evmask_for_button_motion (evmask, mask);
9216 grab_window = grab->window;
9218 if (evmask & type_masks[type])
9221 *evmask_out = evmask;
9228 w = (GdkWindowObject *)pointer_window;
9231 evmask = w->event_mask;
9232 evmask = update_evmask_for_button_motion (evmask, mask);
9234 if (evmask & type_masks[type])
9237 *evmask_out = evmask;
9238 return (GdkWindow *)w;
9241 w = get_event_parent (w);
9247 evmask = grab->event_mask;
9248 evmask = update_evmask_for_button_motion (evmask, mask);
9250 if (evmask & type_masks[type])
9253 *evmask_out = evmask;
9254 return grab->window;
9264 proxy_pointer_event (GdkDisplay *display,
9265 GdkEvent *source_event,
9268 GdkWindow *toplevel_window, *event_window;
9269 GdkWindow *pointer_window;
9270 GdkPointerWindowInfo *pointer_info;
9274 gdouble toplevel_x, toplevel_y;
9276 gboolean non_linear;
9278 event_window = source_event->any.window;
9279 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9280 gdk_event_get_state (source_event, &state);
9281 time_ = gdk_event_get_time (source_event);
9282 device = gdk_event_get_device (source_event);
9283 pointer_info = _gdk_display_get_pointer_info (display, device);
9284 toplevel_window = convert_native_coords_to_toplevel (event_window,
9285 toplevel_x, toplevel_y,
9286 &toplevel_x, &toplevel_y);
9289 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9290 source_event->type == GDK_ENTER_NOTIFY) &&
9291 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9292 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9295 /* If we get crossing events with subwindow unexpectedly being NULL
9296 that means there is a native subwindow that gdk doesn't know about.
9297 We track these and forward them, with the correct virtual window
9299 This is important to get right, as metacity uses gdk for the frame
9300 windows, but gdk doesn't know about the client windows reparented
9302 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9303 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9304 (source_event->type == GDK_ENTER_NOTIFY &&
9305 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9306 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9307 source_event->crossing.subwindow == NULL)
9309 /* Left for an unknown (to gdk) subwindow */
9311 /* Send leave events from window under pointer to event window
9312 that will get the subwindow == NULL window */
9313 _gdk_synthesize_crossing_events (display,
9314 pointer_info->window_under_pointer,
9317 source_event->crossing.mode,
9318 toplevel_x, toplevel_y,
9324 /* Send subwindow == NULL event */
9325 send_crossing_event (display,
9326 (GdkWindowObject *)toplevel_window,
9327 (GdkWindowObject *)event_window,
9329 source_event->crossing.mode,
9330 source_event->crossing.detail,
9333 toplevel_x, toplevel_y,
9338 _gdk_display_set_window_under_pointer (display, device, NULL);
9342 pointer_window = get_pointer_window (display, toplevel_window, device,
9343 toplevel_x, toplevel_y, serial);
9345 if (((source_event->type == GDK_ENTER_NOTIFY &&
9346 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9347 (source_event->type == GDK_LEAVE_NOTIFY &&
9348 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9349 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9350 source_event->crossing.subwindow == NULL)
9352 /* Entered from an unknown (to gdk) subwindow */
9354 /* Send subwindow == NULL event */
9355 send_crossing_event (display,
9356 (GdkWindowObject *)toplevel_window,
9357 (GdkWindowObject *)event_window,
9359 source_event->crossing.mode,
9360 source_event->crossing.detail,
9363 toplevel_x, toplevel_y,
9368 /* Send enter events from event window to pointer_window */
9369 _gdk_synthesize_crossing_events (display,
9373 source_event->crossing.mode,
9374 toplevel_x, toplevel_y,
9377 serial, non_linear);
9378 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9382 if (pointer_info->window_under_pointer != pointer_window)
9384 /* Either a toplevel crossing notify that ended up inside a child window,
9385 or a motion notify that got into another child window */
9387 /* Different than last time, send crossing events */
9388 _gdk_synthesize_crossing_events (display,
9389 pointer_info->window_under_pointer,
9392 GDK_CROSSING_NORMAL,
9393 toplevel_x, toplevel_y,
9396 serial, non_linear);
9397 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9399 else if (source_event->type == GDK_MOTION_NOTIFY)
9401 GdkWindow *event_win;
9405 event_win = get_event_window (display,
9414 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9415 gdk_window_get_device_events (event_win, device) == 0)
9421 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9423 gulong *device_serial;
9425 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9427 if (!device_serial ||
9428 (*device_serial != 0 &&
9429 serial < *device_serial))
9430 event_win = NULL; /* Ignore event */
9434 *device_serial = G_MAXULONG;
9438 if (event_win && !display->ignore_core_events)
9440 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9441 event->motion.time = time_;
9442 convert_toplevel_coords_to_window (event_win,
9443 toplevel_x, toplevel_y,
9444 &event->motion.x, &event->motion.y);
9445 event->motion.x_root = source_event->motion.x_root;
9446 event->motion.y_root = source_event->motion.y_root;
9447 event->motion.state = state;
9448 event->motion.is_hint = is_hint;
9449 event->motion.device = source_event->motion.device;
9450 event->motion.axes = g_memdup (source_event->motion.axes,
9451 sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
9455 /* unlink all move events from queue.
9456 We handle our own, including our emulated masks. */
9460 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9461 GDK_BUTTON2_MASK | \
9462 GDK_BUTTON3_MASK | \
9463 GDK_BUTTON4_MASK | \
9467 proxy_button_event (GdkEvent *source_event,
9470 GdkWindow *toplevel_window, *event_window;
9471 GdkWindow *event_win;
9472 GdkWindow *pointer_window;
9473 GdkWindowObject *parent;
9478 gdouble toplevel_x, toplevel_y;
9479 GdkDisplay *display;
9483 type = source_event->any.type;
9484 event_window = source_event->any.window;
9485 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9486 gdk_event_get_state (source_event, &state);
9487 time_ = gdk_event_get_time (source_event);
9488 device = gdk_event_get_device (source_event);
9489 display = gdk_window_get_display (source_event->any.window);
9490 toplevel_window = convert_native_coords_to_toplevel (event_window,
9491 toplevel_x, toplevel_y,
9492 &toplevel_x, &toplevel_y);
9494 if (type == GDK_BUTTON_PRESS &&
9495 !source_event->any.send_event &&
9496 _gdk_display_has_device_grab (display, device, serial) == NULL)
9499 _gdk_window_find_descendant_at (toplevel_window,
9500 toplevel_x, toplevel_y,
9503 /* Find the event window, that gets the grab */
9504 w = (GdkWindowObject *)pointer_window;
9506 (parent = get_event_parent (w)) != NULL &&
9507 parent->window_type != GDK_WINDOW_ROOT)
9509 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9513 pointer_window = (GdkWindow *)w;
9515 _gdk_display_add_device_grab (display,
9521 gdk_window_get_events (pointer_window),
9525 _gdk_display_device_grab_update (display, device, serial);
9528 pointer_window = get_pointer_window (display, toplevel_window, device,
9529 toplevel_x, toplevel_y,
9532 event_win = get_event_window (display,
9538 if (event_win == NULL || display->ignore_core_events)
9541 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9542 gdk_window_get_device_events (event_win, device) == 0)
9545 event = _gdk_make_event (event_win, type, source_event, FALSE);
9549 case GDK_BUTTON_PRESS:
9550 case GDK_BUTTON_RELEASE:
9551 event->button.button = source_event->button.button;
9552 convert_toplevel_coords_to_window (event_win,
9553 toplevel_x, toplevel_y,
9554 &event->button.x, &event->button.y);
9555 event->button.x_root = source_event->button.x_root;
9556 event->button.y_root = source_event->button.y_root;
9557 event->button.state = state;
9558 event->button.device = source_event->button.device;
9559 event->button.axes = g_memdup (source_event->button.axes,
9560 sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
9562 if (type == GDK_BUTTON_PRESS)
9563 _gdk_event_button_generate (display, event);
9567 event->scroll.direction = source_event->scroll.direction;
9568 convert_toplevel_coords_to_window (event_win,
9569 toplevel_x, toplevel_y,
9570 &event->scroll.x, &event->scroll.y);
9571 event->scroll.x_root = source_event->scroll.x_root;
9572 event->scroll.y_root = source_event->scroll.y_root;
9573 event->scroll.state = state;
9574 event->scroll.device = source_event->scroll.device;
9581 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9584 #ifdef DEBUG_WINDOW_PRINTING
9586 gdk_window_print (GdkWindowObject *window,
9590 const char *window_types[] = {
9600 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9601 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9602 window->x, window->y,
9603 window->width, window->height
9606 if (gdk_window_has_impl (window))
9608 #ifdef GDK_WINDOWING_X11
9609 g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
9613 if (window->window_type != GDK_WINDOW_CHILD)
9614 g_print (" %s", window_types[window->window_type]);
9616 if (window->input_only)
9617 g_print (" input-only");
9620 g_print (" shaped");
9622 if (!gdk_window_is_visible ((GdkWindow *)window))
9623 g_print (" hidden");
9625 g_print (" abs[%d,%d]",
9626 window->abs_x, window->abs_y);
9628 cairo_region_get_extents (window->clip_region, &r);
9629 if (cairo_region_is_empty (window->clip_region))
9630 g_print (" clipbox[empty]");
9632 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9639 gdk_window_print_tree (GdkWindow *window,
9641 gboolean include_input_only)
9643 GdkWindowObject *private;
9646 private = (GdkWindowObject *)window;
9648 if (private->input_only && !include_input_only)
9651 gdk_window_print (private, indent);
9653 for (l = private->children; l != NULL; l = l->next)
9654 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9657 #endif /* DEBUG_WINDOW_PRINTING */
9660 _gdk_windowing_got_event (GdkDisplay *display,
9665 GdkWindow *event_window;
9666 GdkWindowObject *event_private;
9668 gboolean unlink_event;
9669 guint old_state, old_button;
9670 GdkDeviceGrabInfo *button_release_grab;
9671 GdkPointerWindowInfo *pointer_info;
9673 gboolean is_toplevel;
9675 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9676 display->last_event_time = gdk_event_get_time (event);
9678 device = gdk_event_get_device (event);
9684 g_object_get (device, "input-mode", &mode, NULL);
9685 _gdk_display_device_grab_update (display, device, serial);
9687 if (mode == GDK_MODE_DISABLED ||
9688 !_gdk_display_check_grab_ownership (display, device, serial))
9690 /* Device events are blocked by another
9691 * device grab, or the device is disabled
9693 unlink_event = TRUE;
9698 event_window = event->any.window;
9702 pointer_info = _gdk_display_get_pointer_info (display, device);
9703 event_private = GDK_WINDOW_OBJECT (event_window);
9705 #ifdef DEBUG_WINDOW_PRINTING
9706 if (event->type == GDK_KEY_PRESS &&
9707 (event->key.keyval == 0xa7 ||
9708 event->key.keyval == 0xbd))
9710 gdk_window_print_tree (event_window, 0,
9711 event->key.keyval == 0xbd);
9715 if (_gdk_native_windows)
9717 if (event->type == GDK_BUTTON_PRESS &&
9718 !event->any.send_event &&
9719 _gdk_display_has_device_grab (display, device, serial) == NULL)
9721 _gdk_display_add_device_grab (display,
9727 gdk_window_get_events (event_window),
9729 gdk_event_get_time (event),
9731 _gdk_display_device_grab_update (display, device, serial);
9733 if (event->type == GDK_BUTTON_RELEASE &&
9734 !event->any.send_event)
9736 button_release_grab =
9737 _gdk_display_has_device_grab (display, device, serial);
9738 if (button_release_grab &&
9739 button_release_grab->implicit &&
9740 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9742 button_release_grab->serial_end = serial;
9743 button_release_grab->implicit_ungrab = FALSE;
9744 _gdk_display_device_grab_update (display, device, serial);
9748 if (event->type == GDK_BUTTON_PRESS)
9749 _gdk_event_button_generate (display, event);
9754 if (event->type == GDK_VISIBILITY_NOTIFY)
9756 event_private->native_visibility = event->visibility.state;
9757 gdk_window_update_visibility_recursively (event_private,
9762 if (!(is_button_type (event->type) ||
9763 is_motion_type (event->type)) ||
9764 event_private->window_type == GDK_WINDOW_ROOT)
9767 is_toplevel = gdk_window_is_toplevel (event_private);
9769 if ((event->type == GDK_ENTER_NOTIFY ||
9770 event->type == GDK_LEAVE_NOTIFY) &&
9771 (event->crossing.mode == GDK_CROSSING_GRAB ||
9772 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9773 (_gdk_display_has_device_grab (display, device, serial) ||
9774 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9776 /* We synthesize all crossing events due to grabs ourselves,
9777 * so we ignore the native ones caused by our native pointer_grab
9778 * calls. Otherwise we would proxy these crossing event and cause
9779 * multiple copies of crossing events for grabs.
9781 * We do want to handle grabs from other clients though, as for
9782 * instance alt-tab in metacity causes grabs like these and
9783 * we want to handle those. Thus the has_pointer_grab check.
9785 * Implicit grabs on child windows create some grabbing events
9786 * that are sent before the button press. This means we can't
9787 * detect these with the has_pointer_grab check (as the implicit
9788 * grab is only noticed when we get button press event), so we
9789 * detect these events by checking for INFERIOR enter or leave
9790 * events. These should never be a problem to filter out.
9793 /* We ended up in this window after some (perhaps other clients)
9794 grab, so update the toplevel_under_window state */
9796 event->type == GDK_ENTER_NOTIFY &&
9797 event->crossing.mode == GDK_CROSSING_UNGRAB)
9799 if (pointer_info->toplevel_under_pointer)
9800 g_object_unref (pointer_info->toplevel_under_pointer);
9801 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9804 unlink_event = TRUE;
9808 /* Track toplevel_under_pointer */
9811 if (event->type == GDK_ENTER_NOTIFY &&
9812 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9814 if (pointer_info->toplevel_under_pointer)
9815 g_object_unref (pointer_info->toplevel_under_pointer);
9816 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9818 else if (event->type == GDK_LEAVE_NOTIFY &&
9819 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9820 pointer_info->toplevel_under_pointer == event_window)
9822 if (pointer_info->toplevel_under_pointer)
9823 g_object_unref (pointer_info->toplevel_under_pointer);
9824 pointer_info->toplevel_under_pointer = NULL;
9828 /* Store last pointer window and position/state */
9829 old_state = pointer_info->state;
9830 old_button = pointer_info->button;
9832 gdk_event_get_coords (event, &x, &y);
9833 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9834 pointer_info->toplevel_x = x;
9835 pointer_info->toplevel_y = y;
9836 gdk_event_get_state (event, &pointer_info->state);
9837 if (event->type == GDK_BUTTON_PRESS ||
9838 event->type == GDK_BUTTON_RELEASE)
9839 pointer_info->button = event->button.button;
9842 (pointer_info->state != old_state ||
9843 pointer_info->button != old_button))
9844 _gdk_display_enable_motion_hints (display, device);
9846 unlink_event = FALSE;
9847 if (is_motion_type (event->type))
9848 unlink_event = proxy_pointer_event (display,
9851 else if (is_button_type (event->type))
9852 unlink_event = proxy_button_event (event,
9855 if (event->type == GDK_BUTTON_RELEASE &&
9856 !event->any.send_event)
9858 button_release_grab =
9859 _gdk_display_has_device_grab (display, device, serial);
9860 if (button_release_grab &&
9861 button_release_grab->implicit &&
9862 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9864 button_release_grab->serial_end = serial;
9865 button_release_grab->implicit_ungrab = FALSE;
9866 _gdk_display_device_grab_update (display, device, serial);
9873 _gdk_event_queue_remove_link (display, event_link);
9874 g_list_free_1 (event_link);
9875 gdk_event_free (event);
9881 get_extension_event_window (GdkDisplay *display,
9882 GdkWindow *pointer_window,
9887 GdkWindow *grab_window;
9889 GdkDeviceGrabInfo *grab;
9891 /* FIXME: which device? */
9892 grab = _gdk_display_has_device_grab (display, display->core_pointer, serial);
9894 if (grab != NULL && !grab->owner_events)
9896 evmask = grab->event_mask;
9898 grab_window = grab->window;
9900 if (evmask & type_masks[type])
9906 w = (GdkWindowObject *)pointer_window;
9909 evmask = w->extension_events;
9911 if (evmask & type_masks[type])
9912 return (GdkWindow *)w;
9914 w = get_event_parent (w);
9920 evmask = grab->event_mask;
9922 if (evmask & type_masks[type])
9923 return grab->window;
9933 _gdk_window_get_input_window_for_event (GdkWindow *native_window,
9934 GdkEventType event_type,
9938 GdkDisplay *display;
9939 GdkWindow *toplevel_window;
9940 GdkWindow *pointer_window;
9941 GdkWindow *event_win;
9942 gdouble toplevel_x, toplevel_y;
9947 display = gdk_window_get_display (native_window);
9948 toplevel_window = convert_native_coords_to_toplevel (native_window,
9949 toplevel_x, toplevel_y,
9950 &toplevel_x, &toplevel_y);
9951 /* FIXME: which device? */
9952 pointer_window = get_pointer_window (display, toplevel_window, NULL,
9953 toplevel_x, toplevel_y, serial);
9954 event_win = get_extension_event_window (display,
9963 * gdk_window_create_similar_surface:
9964 * @window: window to make new surface similar to
9965 * @content: the content for the new surface
9966 * @width: width of the new surface
9967 * @height: height of the new surface
9969 * Create a new surface that is as compatible as possible with the
9970 * given @window. For example the new surface will have the same
9971 * fallback resolution and font options as @window. Generally, the new
9972 * surface will also use the same backend as @window, unless that is
9973 * not possible for some reason. The type of the returned surface may
9974 * be examined with cairo_surface_get_type().
9976 * Initially the surface contents are all 0 (transparent if contents
9977 * have transparency, black otherwise.)
9979 * Returns: a pointer to the newly allocated surface. The caller
9980 * owns the surface and should call cairo_surface_destroy() when done
9983 * This function always returns a valid pointer, but it will return a
9984 * pointer to a "nil" surface if @other is already in an error state
9985 * or any other error occurs.
9990 gdk_window_create_similar_surface (GdkWindow * window,
9991 cairo_content_t content,
9995 cairo_surface_t *window_surface, *surface;
9997 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9999 window_surface = _gdk_drawable_ref_cairo_surface (window);
10001 surface = cairo_surface_create_similar (window_surface,
10005 cairo_surface_destroy (window_surface);