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 */
39 #include "gdk.h" /* For gdk_rectangle_union() */
40 #include "gdkinternals.h"
42 #include "gdkscreen.h"
43 #include "gdkdeviceprivate.h"
44 #include "gdkdrawable.h"
45 #include "gdkmarshalers.h"
46 #include "gdkscreen.h"
47 #include "gdkwindowimpl.h"
49 #undef DEBUG_WINDOW_PRINTING
54 * @Short_description: Onscreen display areas in the target window system
57 * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
58 * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
59 * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
60 * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
61 * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
64 * <refsect2 id="COMPOSITED-WINDOWS">
65 * <title>Composited Windows</title>
67 * Normally, the windowing system takes care of rendering the contents of a
68 * child window onto its parent window. This mechanism can be intercepted by
69 * calling gdk_window_set_composited() on the child window. For a
70 * <firstterm>composited</firstterm> window it is the responsibility of the
71 * application to render the window contents at the right spot.
73 * <example id="composited-window-example">
74 * <title>Composited windows</title>
76 * <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>
77 * </programlisting></example>
79 * In the example <xref linkend="composited-window-example"/>, a button is
80 * placed inside of an event box inside of a window. The event box is set as
81 * composited and therefore is no longer automatically drawn to the screen.
83 * When the contents of the event box change, an expose event is generated on
84 * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
85 * The expose handler for this widget is responsible for merging the changes
86 * back on the screen in the way that it wishes.
88 * In our case, we merge the contents with a 50% transparency. We also set the
89 * background colour of the window to red. The effect is that the background
90 * shows through the button.
93 * <refsect2 id="OFFSCREEN-WINDOWS">
94 * <title>Offscreen Windows</title>
96 * Offscreen windows are more general than composited windows, since they allow
97 * not only to modify the rendering of the child window onto its parent, but
98 * also to apply coordinate transformations.
100 * To integrate an offscreen window into a window hierarchy, one has to call
101 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
102 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
103 * select an offscreen child at given coordinates, and the
104 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
105 * offscreen window are used to translate coordinates between the embedder and
106 * the offscreen window.
108 * For rendering an offscreen window onto its embedder, the contents of the
109 * offscreen window are available as a surface, via
110 * gdk_offscreen_window_get_surface().
116 /* Historically a GdkWindow always matches a platform native window,
117 * be it a toplevel window or a child window. In this setup the
118 * GdkWindow (and other GdkDrawables) were platform independent classes,
119 * and the actual platform specific implementation was in a delegate
120 * object availible as "impl" in the window object.
122 * With the addition of client side windows and offscreen windows this
123 * changes a bit. The application-visible GdkWindow object behaves as
124 * it did before, but not all such windows now have a corresponding native
125 * window. Instead windows that are "client side" are emulated by the gdk
126 * code such that clipping, drawing, moving, events etc work as expected.
128 * For GdkWindows that have a native window the "impl" object is the
129 * same as before. However, for all client side windows the impl object
130 * is shared with its parent (i.e. all client windows descendants of one
131 * native window has the same impl.
133 * Additionally there is a new type of platform independent impl object,
134 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
135 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
136 * windows). Such windows work by allocating a #cairo_surface_t as the backing
137 * store for drawing operations, which is resized with the window.
139 * GdkWindows have a pointer to the "impl window" they are in, i.e.
140 * the topmost GdkWindow which have the same "impl" value. This is stored
141 * in impl_window, which is different from the window itself only for client
143 * All GdkWindows (native or not) track the position of the window in the parent
144 * (x, y), the size of the window (width, height), the position of the window
145 * with respect to the impl window (abs_x, abs_y). We also track the clip
146 * region of the window wrt parent windows and siblings, in window-relative
147 * coordinates with and without child windows included (clip_region,
148 * clip_region_with_children).
150 * All toplevel windows are native windows, but also child windows can be
151 * native (although not children of offscreens). We always listen to
152 * a basic set of events (see get_native_event_mask) for these windows
153 * so that we can emulate events for any client side children.
155 * For native windows we apply the calculated clip region as a window shape
156 * so that eg. client side siblings that overlap the native child properly
157 * draws over the native child window.
159 * In order to minimize flicker and for performance we use a couple of cacheing
160 * tricks. First of all, every time we do a window to window copy area, for instance
161 * when moving a client side window or when scrolling/moving a region in a window
162 * we store this in outstanding_moves instead of applying immediately. We then
163 * delay this move until we really need it (because something depends on being
164 * able to read it), or until we're handing a redraw from an expose/invalidation
165 * (actually we delay it past redraw, but before blitting the double buffer
166 * to the window). This gives us two advantages. First of all it minimizes the time
167 * from the window is moved to the exposes related to that move, secondly it allows
168 * us to be smart about how to do the copy. We combine multiple moves into one (when
169 * possible) and we don't actually do copies to anything that is or will be
170 * invalidated and exposed anyway.
172 * Secondly, we use something called a "implicit paint" during repaint handling.
173 * An implicit paint is similar to a regular paint for the paint stack, but it is
174 * not put on the stack. Instead, it is set on the impl window, and later when
175 * regular gdk_window_begin_paint_region() happen on a window of this impl window
176 * we reuse the surface from the implicit paint. During repaint we create and at the
177 * end flush an implicit paint, which means we can collect all the paints on
178 * multiple client side windows in the same backing store.
181 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
183 /* This adds a local value to the GdkVisibilityState enum */
184 #define GDK_VISIBILITY_NOT_VIEWABLE 3
187 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
201 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
205 struct _GdkWindowPaint
207 cairo_region_t *region;
208 cairo_surface_t *surface;
209 guint uses_implicit : 1;
215 cairo_region_t *dest_region; /* The destination region */
216 int dx, dy; /* The amount that the source was moved to reach dest_region */
217 } GdkWindowRegionMove;
221 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
222 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
225 static void gdk_window_drop_cairo_surface (GdkWindowObject *private);
226 static void gdk_window_set_cairo_clip (GdkDrawable *drawable,
229 static cairo_region_t* gdk_window_get_clip_region (GdkDrawable *drawable);
230 static cairo_region_t* gdk_window_get_visible_region (GdkDrawable *drawable);
232 static void gdk_window_free_paint_stack (GdkWindow *window);
234 static void gdk_window_init (GdkWindowObject *window);
235 static void gdk_window_class_init (GdkWindowObjectClass *klass);
236 static void gdk_window_finalize (GObject *object);
238 static void gdk_window_set_property (GObject *object,
242 static void gdk_window_get_property (GObject *object,
247 static void gdk_window_clear_backing_region (GdkWindow *window,
248 cairo_region_t *region);
250 static void recompute_visible_regions (GdkWindowObject *private,
251 gboolean recalculate_siblings,
252 gboolean recalculate_children);
253 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
254 static void gdk_window_flush_recursive (GdkWindowObject *window);
255 static void do_move_region_bits_on_impl (GdkWindowObject *private,
256 cairo_region_t *region, /* In impl window coords */
258 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
259 static void move_native_children (GdkWindowObject *private);
260 static void update_cursor (GdkDisplay *display,
262 static void impl_window_add_update_area (GdkWindowObject *impl_window,
263 cairo_region_t *region);
264 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
265 static void gdk_window_invalidate_region_full (GdkWindow *window,
266 const cairo_region_t *region,
267 gboolean invalidate_children,
269 static void gdk_window_invalidate_rect_full (GdkWindow *window,
270 const GdkRectangle *rect,
271 gboolean invalidate_children,
274 static guint signals[LAST_SIGNAL] = { 0 };
276 static gpointer parent_class = NULL;
278 static const cairo_user_data_key_t gdk_window_cairo_key;
281 new_region_tag (void)
283 static guint32 tag = 0;
289 gdk_window_object_get_type (void)
291 static GType object_type = 0;
294 object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
296 sizeof (GdkWindowObjectClass),
297 (GClassInitFunc) gdk_window_class_init,
298 sizeof (GdkWindowObject),
299 (GInstanceInitFunc) gdk_window_init,
306 _gdk_paintable_get_type (void)
308 static GType paintable_type = 0;
312 const GTypeInfo paintable_info =
314 sizeof (GdkPaintableIface), /* class_size */
315 NULL, /* base_init */
316 NULL, /* base_finalize */
319 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
320 g_intern_static_string ("GdkPaintable"),
323 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
326 return paintable_type;
330 gdk_window_init (GdkWindowObject *window)
332 /* 0-initialization is good for all other fields. */
334 window->window_type = GDK_WINDOW_CHILD;
336 window->state = GDK_WINDOW_STATE_WITHDRAWN;
339 window->toplevel_window_type = -1;
341 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
342 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
343 /* Default to unobscured since some backends don't send visibility events */
344 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
347 /* Stop and return on the first non-NULL parent */
349 accumulate_get_window (GSignalInvocationHint *ihint,
351 const GValue *handler_return,
354 g_value_copy (handler_return, return_accu);
355 /* Continue while returning NULL */
356 return g_value_get_object (handler_return) == NULL;
360 create_surface_accumulator (GSignalInvocationHint *ihint,
362 const GValue *handler_return,
365 g_value_copy (handler_return, return_accu);
367 /* Stop on the first non-NULL return value */
368 return g_value_get_boxed (handler_return) == NULL;
371 static GQuark quark_pointer_window = 0;
374 gdk_window_class_init (GdkWindowObjectClass *klass)
376 GObjectClass *object_class = G_OBJECT_CLASS (klass);
377 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
379 parent_class = g_type_class_peek_parent (klass);
381 object_class->finalize = gdk_window_finalize;
382 object_class->set_property = gdk_window_set_property;
383 object_class->get_property = gdk_window_get_property;
385 drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
386 drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
387 drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
388 drawable_class->get_clip_region = gdk_window_get_clip_region;
389 drawable_class->get_visible_region = gdk_window_get_visible_region;
391 klass->create_surface = _gdk_offscreen_window_create_surface;
393 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
401 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
402 * gdk_window_get_cursor() for details.
406 g_object_class_install_property (object_class,
408 g_param_spec_boxed ("cursor",
415 * GdkWindow::pick-embedded-child:
416 * @window: the window on which the signal is emitted
417 * @x: x coordinate in the window
418 * @y: y coordinate in the window
420 * The ::pick-embedded-child signal is emitted to find an embedded
421 * child at the given position.
423 * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
427 signals[PICK_EMBEDDED_CHILD] =
428 g_signal_new (g_intern_static_string ("pick-embedded-child"),
429 G_OBJECT_CLASS_TYPE (object_class),
432 accumulate_get_window, NULL,
433 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
440 * GdkWindow::to-embedder:
441 * @window: the offscreen window on which the signal is emitted
442 * @offscreen-x: x coordinate in the offscreen window
443 * @offscreen-y: y coordinate in the offscreen window
444 * @embedder-x: return location for the x coordinate in the embedder window
445 * @embedder-y: return location for the y coordinate in the embedder window
447 * The ::to-embedder signal is emitted to translate coordinates
448 * in an offscreen window to its embedder.
450 * See also #GtkWindow::from-embedder.
454 signals[TO_EMBEDDER] =
455 g_signal_new (g_intern_static_string ("to-embedder"),
456 G_OBJECT_CLASS_TYPE (object_class),
460 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
469 * GdkWindow::from-embedder:
470 * @window: the offscreen window on which the signal is emitted
471 * @embedder-x: x coordinate in the embedder window
472 * @embedder-y: y coordinate in the embedder window
473 * @offscreen-x: return location for the x coordinate in the offscreen window
474 * @offscreen-y: return location for the y coordinate in the offscreen window
476 * The ::from-embedder signal is emitted to translate coordinates
477 * in the embedder of an offscreen window to the offscreen window.
479 * See also #GtkWindow::to-embedder.
483 signals[FROM_EMBEDDER] =
484 g_signal_new (g_intern_static_string ("from-embedder"),
485 G_OBJECT_CLASS_TYPE (object_class),
489 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
498 * GdkWindow::create-surface:
499 * @window: the offscreen window on which the signal is emitted
500 * @width: the width of the offscreen surface to create
501 * @height: the height of the offscreen surface to create
503 * The ::create-surface signal is emitted when an offscreen window
504 * needs its surface (re)created, which happens either when the the
505 * window is first drawn to, or when the window is being
506 * resized. The first signal handler that returns a non-%NULL
507 * surface will stop any further signal emission, and its surface
510 * Note that it is not possible to access the window's previous
511 * surface from within any callback of this signal. Calling
512 * gdk_offscreen_window_get_surface() will lead to a crash.
514 * Returns: the newly created #cairo_surface_t for the offscreen window
518 signals[CREATE_SURFACE] =
519 g_signal_new (g_intern_static_string ("create-surface"),
520 G_OBJECT_CLASS_TYPE (object_class),
522 G_STRUCT_OFFSET (GdkWindowObjectClass, create_surface),
523 create_surface_accumulator, NULL,
524 _gdk_marshal_BOXED__INT_INT,
525 CAIRO_GOBJECT_TYPE_SURFACE,
532 device_removed_cb (GdkDeviceManager *device_manager,
536 GdkWindowObject *private;
538 private = (GdkWindowObject *) window;
540 private->devices_inside = g_list_remove (private->devices_inside, device);
541 g_hash_table_remove (private->device_cursor, device);
543 if (private->device_events)
544 g_hash_table_remove (private->device_events, device);
548 gdk_window_finalize (GObject *object)
550 GdkWindow *window = GDK_WINDOW (object);
551 GdkWindowObject *obj = (GdkWindowObject *) object;
552 GdkDeviceManager *device_manager;
554 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
555 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
557 if (!GDK_WINDOW_DESTROYED (window))
559 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
561 g_warning ("losing last reference to undestroyed window\n");
562 _gdk_window_destroy (window, FALSE);
565 /* We use TRUE here, to keep us from actually calling
566 * XDestroyWindow() on the window
568 _gdk_window_destroy (window, TRUE);
571 gdk_window_drop_cairo_surface (obj);
575 g_object_unref (obj->impl);
579 if (obj->impl_window != obj)
581 g_object_unref (obj->impl_window);
582 obj->impl_window = NULL;
586 cairo_region_destroy (obj->shape);
588 if (obj->input_shape)
589 cairo_region_destroy (obj->input_shape);
592 gdk_cursor_unref (obj->cursor);
594 if (obj->device_cursor)
595 g_hash_table_destroy (obj->device_cursor);
597 if (obj->device_events)
598 g_hash_table_destroy (obj->device_events);
600 if (obj->devices_inside)
601 g_list_free (obj->devices_inside);
603 G_OBJECT_CLASS (parent_class)->finalize (object);
607 gdk_window_set_property (GObject *object,
612 GdkWindow *window = (GdkWindow *)object;
617 gdk_window_set_cursor (window, g_value_get_boxed (value));
621 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
627 gdk_window_get_property (GObject *object,
632 GdkWindow *window = (GdkWindow *) object;
637 g_value_set_boxed (value, gdk_window_get_cursor (window));
641 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
647 gdk_window_is_offscreen (GdkWindowObject *window)
649 return window->window_type == GDK_WINDOW_OFFSCREEN;
652 static GdkWindowObject *
653 gdk_window_get_impl_window (GdkWindowObject *window)
655 return window->impl_window;
659 _gdk_window_get_impl_window (GdkWindow *window)
661 return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
665 gdk_window_has_impl (GdkWindowObject *window)
667 return window->impl_window == window;
671 gdk_window_is_toplevel (GdkWindowObject *window)
674 window->parent == NULL ||
675 window->parent->window_type == GDK_WINDOW_ROOT;
679 _gdk_window_has_impl (GdkWindow *window)
681 return gdk_window_has_impl ((GdkWindowObject *)window);
685 gdk_window_has_no_impl (GdkWindowObject *window)
687 return window->impl_window != window;
691 remove_child_area (GdkWindowObject *private,
692 GdkWindowObject *until,
694 cairo_region_t *region)
696 GdkWindowObject *child;
697 cairo_region_t *child_region;
700 cairo_region_t *shape;
702 for (l = private->children; l; l = l->next)
709 /* If region is empty already, no need to do
710 anything potentially costly */
711 if (cairo_region_is_empty (region))
714 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
717 /* Ignore offscreen children, as they don't draw in their parent and
718 * don't take part in the clipping */
719 if (gdk_window_is_offscreen (child))
724 r.width = child->width;
725 r.height = child->height;
727 /* Bail early if child totally outside region */
728 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
731 child_region = cairo_region_create_rectangle (&r);
735 /* Adjust shape region to parent window coords */
736 cairo_region_translate (child->shape, child->x, child->y);
737 cairo_region_intersect (child_region, child->shape);
738 cairo_region_translate (child->shape, -child->x, -child->y);
740 else if (private->window_type == GDK_WINDOW_FOREIGN)
742 shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
745 cairo_region_intersect (child_region, shape);
746 cairo_region_destroy (shape);
752 if (child->input_shape)
753 cairo_region_intersect (child_region, child->input_shape);
754 else if (private->window_type == GDK_WINDOW_FOREIGN)
756 shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
759 cairo_region_intersect (child_region, shape);
760 cairo_region_destroy (shape);
765 cairo_region_subtract (region, child_region);
766 cairo_region_destroy (child_region);
771 static GdkVisibilityState
772 effective_visibility (GdkWindowObject *private)
774 GdkVisibilityState native;
776 if (!gdk_window_is_viewable ((GdkWindow *)private))
777 return GDK_VISIBILITY_NOT_VIEWABLE;
779 native = private->impl_window->native_visibility;
781 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
782 private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
783 return GDK_VISIBILITY_FULLY_OBSCURED;
784 else if (native == GDK_VISIBILITY_UNOBSCURED)
785 return private->visibility;
786 else /* native PARTIAL, private partial or unobscured */
787 return GDK_VISIBILITY_PARTIAL;
791 gdk_window_update_visibility (GdkWindowObject *private)
793 GdkVisibilityState new_visibility;
796 new_visibility = effective_visibility (private);
798 if (new_visibility != private->effective_visibility)
800 private->effective_visibility = new_visibility;
802 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
803 private->event_mask & GDK_VISIBILITY_NOTIFY)
805 event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
807 event->visibility.state = new_visibility;
813 gdk_window_update_visibility_recursively (GdkWindowObject *private,
814 GdkWindowObject *only_for_impl)
816 GdkWindowObject *child;
819 gdk_window_update_visibility (private);
820 for (l = private->children; l != NULL; l = l->next)
823 if ((only_for_impl == NULL) ||
824 (only_for_impl == child->impl_window))
825 gdk_window_update_visibility_recursively (child, only_for_impl);
830 should_apply_clip_as_shape (GdkWindowObject *private)
833 gdk_window_has_impl (private) &&
834 /* Not for offscreens */
835 !gdk_window_is_offscreen (private) &&
836 /* or for toplevels */
837 !gdk_window_is_toplevel (private) &&
838 /* or for foreign windows */
839 private->window_type != GDK_WINDOW_FOREIGN &&
840 /* or for the root window */
841 private->window_type != GDK_WINDOW_ROOT;
845 apply_shape (GdkWindowObject *private,
846 cairo_region_t *region)
848 GdkWindowImplIface *impl_iface;
850 /* We trash whether we applied a shape so that
851 we can avoid unsetting it many times, which
852 could happen in e.g. apply_clip_as_shape as
853 windows get resized */
854 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
856 impl_iface->shape_combine_region ((GdkWindow *)private,
858 else if (private->applied_shape)
859 impl_iface->shape_combine_region ((GdkWindow *)private,
862 private->applied_shape = region != NULL;
866 region_rect_equal (const cairo_region_t *region,
867 const GdkRectangle *rect)
869 GdkRectangle extents;
871 if (cairo_region_num_rectangles (region) != 1)
874 cairo_region_get_extents (region, &extents);
876 return extents.x == rect->x &&
877 extents.y == rect->y &&
878 extents.width == rect->width &&
879 extents.height == rect->height;
883 apply_clip_as_shape (GdkWindowObject *private)
888 r.width = private->width;
889 r.height = private->height;
891 /* We only apply the clip region if would differ
892 from the actual clip region implied by the size
893 of the window. This is to avoid unneccessarily
894 adding meaningless shapes to all native subwindows */
895 if (!region_rect_equal (private->clip_region, &r))
896 apply_shape (private, private->clip_region);
898 apply_shape (private, NULL);
902 recompute_visible_regions_internal (GdkWindowObject *private,
903 gboolean recalculate_clip,
904 gboolean recalculate_siblings,
905 gboolean recalculate_children)
909 GdkWindowObject *child;
910 cairo_region_t *new_clip, *old_clip_region_with_children;
911 gboolean clip_region_changed;
912 gboolean abs_pos_changed;
913 int old_abs_x, old_abs_y;
915 old_abs_x = private->abs_x;
916 old_abs_y = private->abs_y;
918 /* Update absolute position */
919 if (gdk_window_has_impl (private))
921 /* Native window starts here */
927 private->abs_x = private->parent->abs_x + private->x;
928 private->abs_y = private->parent->abs_y + private->y;
932 private->abs_x != old_abs_x ||
933 private->abs_y != old_abs_y;
935 /* Update clip region based on:
938 * siblings in parents above window
940 clip_region_changed = FALSE;
941 if (recalculate_clip)
943 if (private->viewable)
945 /* Calculate visible region (sans children) in parent window coords */
948 r.width = private->width;
949 r.height = private->height;
950 new_clip = cairo_region_create_rectangle (&r);
952 if (!gdk_window_is_toplevel (private))
954 cairo_region_intersect (new_clip, private->parent->clip_region);
956 /* Remove all overlapping children from parent.
957 * Unless we're all native, because then we don't need to take
958 * siblings into account since X does that clipping for us.
959 * This makes things like SWT that modify the raw X stacking
960 * order without GDKs knowledge work.
962 if (!_gdk_native_windows)
963 remove_child_area (private->parent, private, FALSE, new_clip);
966 /* Convert from parent coords to window coords */
967 cairo_region_translate (new_clip, -private->x, -private->y);
970 cairo_region_intersect (new_clip, private->shape);
973 new_clip = cairo_region_create ();
975 if (private->clip_region == NULL ||
976 !cairo_region_equal (private->clip_region, new_clip))
977 clip_region_changed = TRUE;
979 if (private->clip_region)
980 cairo_region_destroy (private->clip_region);
981 private->clip_region = new_clip;
983 old_clip_region_with_children = private->clip_region_with_children;
984 private->clip_region_with_children = cairo_region_copy (private->clip_region);
985 if (private->window_type != GDK_WINDOW_ROOT)
986 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
988 if (clip_region_changed ||
989 !cairo_region_equal (private->clip_region_with_children, old_clip_region_with_children))
990 private->clip_tag = new_region_tag ();
992 if (old_clip_region_with_children)
993 cairo_region_destroy (old_clip_region_with_children);
996 if (clip_region_changed)
998 GdkVisibilityState visibility;
999 gboolean fully_visible;
1001 if (cairo_region_is_empty (private->clip_region))
1002 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
1007 fully_visible = cairo_region_equal (private->clip_region,
1014 r.width = private->width;
1015 r.height = private->height;
1016 fully_visible = region_rect_equal (private->clip_region, &r);
1020 visibility = GDK_VISIBILITY_UNOBSCURED;
1022 visibility = GDK_VISIBILITY_PARTIAL;
1025 if (private->visibility != visibility)
1027 private->visibility = visibility;
1028 gdk_window_update_visibility (private);
1032 /* Update all children, recursively (except for root, where children are not exact). */
1033 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1034 private->window_type != GDK_WINDOW_ROOT)
1036 for (l = private->children; l; l = l->next)
1039 /* Only recalculate clip if the the clip region changed, otherwise
1040 * there is no way the child clip region could change (its has not e.g. moved)
1041 * Except if recalculate_children is set to force child updates
1043 recompute_visible_regions_internal (child,
1044 recalculate_clip && (clip_region_changed || recalculate_children),
1049 if (clip_region_changed &&
1050 should_apply_clip_as_shape (private))
1051 apply_clip_as_shape (private);
1053 if (recalculate_siblings &&
1054 !gdk_window_is_toplevel (private))
1056 /* If we moved a child window in parent or changed the stacking order, then we
1057 * need to recompute the visible area of all the other children in the parent
1059 for (l = private->parent->children; l; l = l->next)
1063 if (child != private)
1064 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1067 /* We also need to recompute the _with_children clip for the parent */
1068 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1071 if (private->cairo_surface && gdk_window_has_impl (private))
1073 GdkWindowImplIface *iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1075 private->cairo_surface = iface->resize_cairo_surface (private->impl,
1076 private->cairo_surface,
1080 else if (private->cairo_surface)
1081 gdk_window_drop_cairo_surface (private);
1084 /* Call this when private has changed in one or more of these ways:
1088 * stacking order of window changed
1091 * It will recalculate abs_x/y and the clip regions
1093 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1094 * for recalculate_siblings. (Mostly used internally for the recursion)
1096 * If a child window was removed (and you can't use that child for
1097 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1100 recompute_visible_regions (GdkWindowObject *private,
1101 gboolean recalculate_siblings,
1102 gboolean recalculate_children)
1104 recompute_visible_regions_internal (private,
1106 recalculate_siblings,
1107 recalculate_children);
1111 _gdk_window_update_size (GdkWindow *window)
1113 recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1116 /* Find the native window that would be just above "child"
1117 * in the native stacking order if "child" was a native window
1118 * (it doesn't have to be native). If there is no such native
1119 * window inside this native parent then NULL is returned.
1120 * If child is NULL, find lowest native window in parent.
1122 static GdkWindowObject *
1123 find_native_sibling_above_helper (GdkWindowObject *parent,
1124 GdkWindowObject *child)
1131 l = g_list_find (parent->children, child);
1132 g_assert (l != NULL); /* Better be a child of its parent... */
1133 l = l->prev; /* Start looking at the one above the child */
1136 l = g_list_last (parent->children);
1138 for (; l != NULL; l = l->prev)
1142 if (gdk_window_has_impl (w))
1145 g_assert (parent != w);
1146 w = find_native_sibling_above_helper (w, NULL);
1155 static GdkWindowObject *
1156 find_native_sibling_above (GdkWindowObject *parent,
1157 GdkWindowObject *child)
1161 w = find_native_sibling_above_helper (parent, child);
1165 if (gdk_window_has_impl (parent))
1168 return find_native_sibling_above (parent->parent, parent);
1172 get_native_device_event_mask (GdkWindowObject *private,
1175 GdkEventMask event_mask;
1178 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1180 event_mask = private->event_mask;
1182 if (_gdk_native_windows ||
1183 private->window_type == GDK_WINDOW_ROOT ||
1184 private->window_type == GDK_WINDOW_FOREIGN)
1190 /* Do whatever the app asks to, since the app
1191 * may be asking for weird things for native windows,
1192 * but don't use motion hints as that may affect non-native
1193 * child windows that don't want it. Also, we need to
1194 * set all the app-specified masks since they will be picked
1195 * up by any implicit grabs (i.e. if they were not set as
1196 * native we would not get the events we need). */
1197 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1199 /* We need thse for all native windows so we can
1200 emulate events on children: */
1203 GDK_VISIBILITY_NOTIFY_MASK |
1204 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1206 /* Additionally we select for pointer and button events
1207 * for toplevels as we need to get these to emulate
1208 * them for non-native subwindows. Even though we don't
1209 * select on them for all native windows we will get them
1210 * as the events are propagated out to the first window
1211 * that select for them.
1212 * Not selecting for button press on all windows is an
1213 * important thing, because in X only one client can do
1214 * so, and we don't want to unexpectedly prevent another
1215 * client from doing it.
1217 * We also need to do the same if the app selects for button presses
1218 * because then we will get implicit grabs for this window, and the
1219 * event mask used for that grab is based on the rest of the mask
1220 * for the window, but we might need more events than this window
1221 * lists due to some non-native child window.
1223 if (gdk_window_is_toplevel (private) ||
1224 mask & GDK_BUTTON_PRESS_MASK)
1226 GDK_POINTER_MOTION_MASK |
1227 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1235 get_native_grab_event_mask (GdkEventMask grab_mask)
1237 /* Similar to the above but for pointer events only */
1239 GDK_POINTER_MOTION_MASK |
1240 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1241 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1244 ~GDK_POINTER_MOTION_HINT_MASK);
1248 get_native_event_mask (GdkWindowObject *private)
1250 return get_native_device_event_mask (private, NULL);
1253 /* Puts the native window in the right order wrt the other native windows
1254 * in the hierarchy, given the position it has in the client side data.
1255 * This is useful if some operation changed the stacking order.
1256 * This calls assumes the native window is now topmost in its native parent.
1259 sync_native_window_stack_position (GdkWindow *window)
1261 GdkWindowObject *above;
1262 GdkWindowObject *private;
1263 GdkWindowImplIface *impl_iface;
1264 GList listhead = {0};
1266 private = (GdkWindowObject *) window;
1267 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1269 above = find_native_sibling_above (private->parent, private);
1272 listhead.data = window;
1273 impl_iface->restack_under ((GdkWindow *)above,
1280 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1281 * the default root window for the default display.
1282 * @attributes: attributes of the new window
1283 * @attributes_mask: mask indicating which fields in @attributes are valid
1285 * Creates a new #GdkWindow using the attributes from
1286 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1287 * more details. Note: to use this on displays other than the default
1288 * display, @parent must be specified.
1290 * Return value: (transfer none): the new #GdkWindow
1293 gdk_window_new (GdkWindow *parent,
1294 GdkWindowAttr *attributes,
1295 gint attributes_mask)
1298 GdkWindowObject *private;
1302 GdkEventMask event_mask;
1303 GdkWindow *real_parent;
1304 GdkDeviceManager *device_manager;
1306 g_return_val_if_fail (attributes != NULL, NULL);
1310 GDK_NOTE (MULTIHEAD,
1311 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1313 screen = gdk_screen_get_default ();
1314 parent = gdk_screen_get_root_window (screen);
1317 screen = gdk_window_get_screen (parent);
1319 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1321 if (GDK_WINDOW_DESTROYED (parent))
1323 g_warning ("gdk_window_new(): parent is destroyed\n");
1327 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1328 _gdk_native_windows)
1330 g_warning ("Offscreen windows not supported with native-windows gdk");
1334 window = g_object_new (GDK_TYPE_WINDOW, NULL);
1335 private = (GdkWindowObject *) window;
1337 /* Windows with a foreign parent are treated as if they are children
1338 * of the root window, except for actual creation.
1340 real_parent = parent;
1341 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1342 parent = gdk_screen_get_root_window (screen);
1344 private->parent = (GdkWindowObject *)parent;
1346 private->accept_focus = TRUE;
1347 private->focus_on_map = TRUE;
1349 if (attributes_mask & GDK_WA_X)
1354 if (attributes_mask & GDK_WA_Y)
1361 private->width = (attributes->width > 1) ? (attributes->width) : (1);
1362 private->height = (attributes->height > 1) ? (attributes->height) : (1);
1364 #ifdef GDK_WINDOWING_X11
1365 /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1366 * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1368 if (attributes->wclass == GDK_INPUT_ONLY &&
1369 private->parent->window_type == GDK_WINDOW_ROOT &&
1370 !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1372 g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1373 attributes->wclass = GDK_INPUT_OUTPUT;
1377 if (attributes->wclass == GDK_INPUT_ONLY)
1379 /* Backwards compatiblity - we've always ignored
1380 * attributes->window_type for input-only windows
1383 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1384 private->window_type = GDK_WINDOW_TEMP;
1386 private->window_type = GDK_WINDOW_CHILD;
1389 private->window_type = attributes->window_type;
1392 switch (private->window_type)
1394 case GDK_WINDOW_TOPLEVEL:
1395 case GDK_WINDOW_TEMP:
1396 case GDK_WINDOW_OFFSCREEN:
1397 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1398 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1399 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1400 case GDK_WINDOW_CHILD:
1404 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1408 if (attributes_mask & GDK_WA_VISUAL)
1409 private->visual = attributes->visual;
1411 private->visual = gdk_screen_get_system_visual (screen);
1413 private->event_mask = attributes->event_mask;
1415 if (attributes->wclass == GDK_INPUT_OUTPUT)
1417 private->input_only = FALSE;
1418 private->depth = private->visual->depth;
1420 /* XXX: Cache this somehow? */
1421 private->background = cairo_pattern_create_rgb (0, 0, 0);
1426 private->input_only = TRUE;
1429 if (private->parent)
1430 private->parent->children = g_list_prepend (private->parent->children, window);
1432 native = _gdk_native_windows; /* Default */
1433 if (private->parent->window_type == GDK_WINDOW_ROOT)
1434 native = TRUE; /* Always use native windows for toplevels */
1435 else if (!private->input_only &&
1436 (attributes_mask & GDK_WA_VISUAL &&
1437 attributes->visual != gdk_window_get_visual (GDK_WINDOW (private->parent))))
1438 native = TRUE; /* InputOutput window with different visual than parent, needs native window */
1440 if (gdk_window_is_offscreen (private))
1442 _gdk_offscreen_window_new (window, attributes, attributes_mask);
1443 private->impl_window = private;
1447 event_mask = get_native_event_mask (private);
1449 /* Create the impl */
1450 _gdk_window_impl_new (window, real_parent, screen, event_mask, attributes, attributes_mask);
1451 private->impl_window = private;
1453 /* This will put the native window topmost in the native parent, which may
1454 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1455 if (!_gdk_window_has_impl (real_parent))
1456 sync_native_window_stack_position (window);
1460 private->impl_window = g_object_ref (private->parent->impl_window);
1461 private->impl = g_object_ref (private->impl_window->impl);
1464 recompute_visible_regions (private, TRUE, FALSE);
1466 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1467 (attributes->cursor) :
1470 private->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1471 (GDestroyNotify) gdk_cursor_unref);
1473 device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent));
1474 g_signal_connect (device_manager, "device-removed",
1475 G_CALLBACK (device_removed_cb), window);
1481 is_parent_of (GdkWindow *parent,
1492 w = gdk_window_get_parent (w);
1499 change_impl (GdkWindowObject *private,
1500 GdkWindowObject *impl_window,
1504 GdkWindowObject *child;
1505 GdkDrawable *old_impl;
1506 GdkWindowObject *old_impl_window;
1508 old_impl = private->impl;
1509 old_impl_window = private->impl_window;
1510 if (private != impl_window)
1511 private->impl_window = g_object_ref (impl_window);
1513 private->impl_window = private;
1514 private->impl = g_object_ref (new);
1515 if (old_impl_window != private)
1516 g_object_unref (old_impl_window);
1517 g_object_unref (old_impl);
1519 for (l = private->children; l != NULL; l = l->next)
1523 if (child->impl == old_impl)
1524 change_impl (child, impl_window, new);
1529 reparent_to_impl (GdkWindowObject *private)
1532 GdkWindowObject *child;
1534 GdkWindowImplIface *impl_iface;
1536 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1538 /* Enumerate in reverse order so we get the right order for the native
1539 windows (first in childrens list is topmost, and reparent places on top) */
1540 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1544 if (child->impl == private->impl)
1545 reparent_to_impl (child);
1548 show = impl_iface->reparent ((GdkWindow *)child,
1549 (GdkWindow *)private,
1550 child->x, child->y);
1552 gdk_window_show_unraised ((GdkWindow *)child);
1559 * gdk_window_reparent:
1560 * @window: a #GdkWindow
1561 * @new_parent: new parent to move @window into
1562 * @x: X location inside the new parent
1563 * @y: Y location inside the new parent
1565 * Reparents @window into the given @new_parent. The window being
1566 * reparented will be unmapped as a side effect.
1570 gdk_window_reparent (GdkWindow *window,
1571 GdkWindow *new_parent,
1575 GdkWindowObject *private;
1576 GdkWindowObject *new_parent_private;
1577 GdkWindowObject *old_parent;
1579 gboolean show, was_mapped, applied_clip_as_shape;
1580 gboolean do_reparent_to_impl;
1581 GdkEventMask old_native_event_mask;
1582 GdkWindowImplIface *impl_iface;
1584 g_return_if_fail (GDK_IS_WINDOW (window));
1585 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1586 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1588 if (GDK_WINDOW_DESTROYED (window) ||
1589 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1592 screen = gdk_window_get_screen (window);
1594 new_parent = gdk_screen_get_root_window (screen);
1596 private = (GdkWindowObject *) window;
1597 new_parent_private = (GdkWindowObject *)new_parent;
1599 /* No input-output children of input-only windows */
1600 if (new_parent_private->input_only && !private->input_only)
1603 /* Don't create loops in hierarchy */
1604 if (is_parent_of (window, new_parent))
1607 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1608 To make sure we're ok, just wipe it. */
1609 gdk_window_drop_cairo_surface (private);
1611 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1612 old_parent = private->parent;
1614 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1617 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1618 if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1619 new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1620 gdk_window_ensure_native (window);
1622 applied_clip_as_shape = should_apply_clip_as_shape (private);
1624 old_native_event_mask = 0;
1625 do_reparent_to_impl = FALSE;
1626 if (gdk_window_has_impl (private))
1628 old_native_event_mask = get_native_event_mask (private);
1630 show = impl_iface->reparent (window, new_parent, x, y);
1634 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1635 g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1636 new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1639 gdk_window_hide (window);
1641 do_reparent_to_impl = TRUE;
1642 change_impl (private,
1643 new_parent_private->impl_window,
1644 new_parent_private->impl);
1647 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1650 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1652 new_parent = gdk_screen_get_root_window (screen);
1653 new_parent_private = (GdkWindowObject *)new_parent;
1657 old_parent->children = g_list_remove (old_parent->children, window);
1659 private->parent = new_parent_private;
1663 new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1665 /* Switch the window type as appropriate */
1667 switch (GDK_WINDOW_TYPE (new_parent))
1669 case GDK_WINDOW_ROOT:
1670 case GDK_WINDOW_FOREIGN:
1671 if (private->toplevel_window_type != -1)
1672 GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1673 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1674 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1676 case GDK_WINDOW_OFFSCREEN:
1677 case GDK_WINDOW_TOPLEVEL:
1678 case GDK_WINDOW_CHILD:
1679 case GDK_WINDOW_TEMP:
1680 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1681 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1683 /* Save the original window type so we can restore it if the
1684 * window is reparented back to be a toplevel
1686 private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1687 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1691 /* We might have changed window type for a native windows, so we
1692 need to change the event mask too. */
1693 if (gdk_window_has_impl (private))
1695 GdkEventMask native_event_mask = get_native_event_mask (private);
1697 if (native_event_mask != old_native_event_mask)
1698 impl_iface->set_events (window, native_event_mask);
1701 _gdk_window_update_viewable (window);
1703 recompute_visible_regions (private, TRUE, FALSE);
1704 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1705 recompute_visible_regions (old_parent, FALSE, TRUE);
1707 /* We used to apply the clip as the shape, but no more.
1708 Reset this to the real shape */
1709 if (gdk_window_has_impl (private) &&
1710 applied_clip_as_shape &&
1711 !should_apply_clip_as_shape (private))
1712 apply_shape (private, private->shape);
1714 if (do_reparent_to_impl)
1715 reparent_to_impl (private);
1718 /* The reparent will have put the native window topmost in the native parent,
1719 * which may be wrong wrt other native windows in the non-native hierarchy,
1721 if (!gdk_window_has_impl (new_parent_private))
1722 sync_native_window_stack_position (window);
1726 gdk_window_show_unraised (window);
1728 _gdk_synthesize_crossing_events_for_geometry_change (window);
1732 temporary_disable_extension_events (GdkWindowObject *window)
1734 GdkWindowObject *child;
1738 if (window->extension_events != 0)
1740 g_object_set_data (G_OBJECT (window),
1741 "gdk-window-extension-events",
1742 GINT_TO_POINTER (window->extension_events));
1743 gdk_input_set_extension_events ((GdkWindow *)window, 0,
1744 GDK_EXTENSION_EVENTS_NONE);
1749 for (l = window->children; l != NULL; l = l->next)
1753 if (window->impl_window == child->impl_window)
1754 res |= temporary_disable_extension_events (child);
1761 reenable_extension_events (GdkWindowObject *window)
1763 GdkWindowObject *child;
1767 mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1768 "gdk-window-extension-events"));
1772 /* We don't have the mode here, so we pass in cursor.
1773 This works with the current code since mode is not
1774 stored except as part of the mask, and cursor doesn't
1776 gdk_input_set_extension_events ((GdkWindow *)window, mask,
1777 GDK_EXTENSION_EVENTS_CURSOR);
1778 g_object_set_data (G_OBJECT (window),
1779 "gdk-window-extension-events",
1783 for (l = window->children; l != NULL; l = l->next)
1787 if (window->impl_window == child->impl_window)
1788 reenable_extension_events (window);
1793 * gdk_window_ensure_native:
1794 * @window: a #GdkWindow
1796 * Tries to ensure that there is a window-system native window for this
1797 * GdkWindow. This may fail in some situations, returning %FALSE.
1799 * Offscreen window and children of them can never have native windows.
1801 * Some backends may not support native child windows.
1803 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1808 gdk_window_ensure_native (GdkWindow *window)
1810 GdkWindowObject *private;
1811 GdkWindowObject *impl_window;
1812 GdkDrawable *new_impl, *old_impl;
1814 GdkWindowObject *above;
1816 GdkWindowImplIface *impl_iface;
1817 gboolean disabled_extension_events;
1819 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1821 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1822 GDK_WINDOW_DESTROYED (window))
1825 private = (GdkWindowObject *) window;
1827 impl_window = gdk_window_get_impl_window (private);
1829 if (gdk_window_is_offscreen (impl_window))
1830 return FALSE; /* native in offscreens not supported */
1832 if (impl_window == private)
1833 /* Already has an impl, and its not offscreen . */
1836 /* Need to create a native window */
1838 /* First we disable any extension events on the window or its
1839 descendants to handle the native input window moving */
1840 disabled_extension_events = FALSE;
1841 if (impl_window->input_window)
1842 disabled_extension_events = temporary_disable_extension_events (private);
1844 gdk_window_drop_cairo_surface (private);
1846 screen = gdk_window_get_screen (window);
1848 old_impl = private->impl;
1849 _gdk_window_impl_new (window, (GdkWindow *)private->parent,
1851 get_native_event_mask (private),
1853 new_impl = private->impl;
1855 private->impl = old_impl;
1856 change_impl (private, private, new_impl);
1858 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1860 /* Native window creation will put the native window topmost in the
1861 * native parent, which may be wrong wrt the position of the previous
1862 * non-native window wrt to the other non-native children, so correct this.
1864 above = find_native_sibling_above (private->parent, private);
1867 listhead.data = window;
1868 listhead.prev = NULL;
1869 listhead.next = NULL;
1870 impl_iface->restack_under ((GdkWindow *)above, &listhead);
1873 recompute_visible_regions (private, FALSE, FALSE);
1875 /* The shape may not have been set, as the clip region doesn't actually
1876 change, so do it here manually */
1877 if (should_apply_clip_as_shape (private))
1878 apply_clip_as_shape (private);
1880 reparent_to_impl (private);
1882 if (!private->input_only)
1884 impl_iface->set_background (window, private->background);
1887 impl_iface->input_shape_combine_region (window,
1888 private->input_shape,
1891 if (gdk_window_is_viewable (window))
1892 impl_iface->show (window, FALSE);
1894 if (disabled_extension_events)
1895 reenable_extension_events (private);
1901 window_remove_filters (GdkWindow *window)
1903 GdkWindowObject *obj = (GdkWindowObject*) window;
1909 for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
1910 g_free (tmp_list->data);
1912 g_list_free (obj->filters);
1913 obj->filters = NULL;
1918 update_pointer_info_foreach (GdkDisplay *display,
1920 GdkPointerWindowInfo *pointer_info,
1923 GdkWindow *window = user_data;
1925 if (pointer_info->toplevel_under_pointer == window)
1927 g_object_unref (pointer_info->toplevel_under_pointer);
1928 pointer_info->toplevel_under_pointer = NULL;
1933 window_remove_from_pointer_info (GdkWindow *window,
1934 GdkDisplay *display)
1936 _gdk_display_pointer_info_foreach (display,
1937 update_pointer_info_foreach,
1942 * _gdk_window_destroy_hierarchy:
1943 * @window: a #GdkWindow
1944 * @recursing: If TRUE, then this is being called because a parent
1946 * @recursing_native: If TRUE, then this is being called because a native parent
1947 * was destroyed. This generally means that the call to the
1948 * windowing system to destroy the window can be omitted, since
1949 * it will be destroyed as a result of the parent being destroyed.
1950 * Unless @foreign_destroy.
1951 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1952 * external agency. The window has already been destroyed and no
1953 * windowing system calls should be made. (This may never happen
1954 * for some windowing systems.)
1956 * Internal function to destroy a window. Like gdk_window_destroy(),
1957 * but does not drop the reference count created by gdk_window_new().
1960 _gdk_window_destroy_hierarchy (GdkWindow *window,
1962 gboolean recursing_native,
1963 gboolean foreign_destroy)
1965 GdkWindowObject *private;
1966 GdkWindowObject *temp_private;
1967 GdkWindowImplIface *impl_iface;
1968 GdkWindow *temp_window;
1970 GdkDisplay *display;
1974 g_return_if_fail (GDK_IS_WINDOW (window));
1976 private = (GdkWindowObject*) window;
1978 if (GDK_WINDOW_DESTROYED (window))
1981 display = gdk_window_get_display (window);
1982 screen = gdk_window_get_screen (window);
1983 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1984 if (temp_window == window)
1985 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1988 switch (private->window_type)
1990 case GDK_WINDOW_ROOT:
1991 if (!screen->closed)
1993 g_error ("attempted to destroy root window");
1996 /* else fall thru */
1997 case GDK_WINDOW_TOPLEVEL:
1998 case GDK_WINDOW_CHILD:
1999 case GDK_WINDOW_TEMP:
2000 case GDK_WINDOW_FOREIGN:
2001 case GDK_WINDOW_OFFSCREEN:
2002 if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
2004 /* Logically, it probably makes more sense to send
2005 * a "destroy yourself" message to the foreign window
2006 * whether or not it's in our hierarchy; but for historical
2007 * reasons, we only send "destroy yourself" messages to
2008 * foreign windows in our hierarchy.
2010 if (private->parent)
2011 _gdk_windowing_window_destroy_foreign (window);
2013 /* Also for historical reasons, we remove any filters
2014 * on a foreign window when it or a parent is destroyed;
2015 * this likely causes problems if two separate portions
2016 * of code are maintaining filter lists on a foreign window.
2018 window_remove_filters (window);
2022 if (private->parent)
2024 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
2026 if (parent_private->children)
2027 parent_private->children = g_list_remove (parent_private->children, window);
2030 GDK_WINDOW_IS_MAPPED (window))
2032 recompute_visible_regions (private, TRUE, FALSE);
2033 gdk_window_invalidate_in_parent (private);
2037 gdk_window_free_paint_stack (window);
2039 if (private->background)
2041 cairo_pattern_destroy (private->background);
2042 private->background = NULL;
2045 if (private->window_type == GDK_WINDOW_FOREIGN)
2046 g_assert (private->children == NULL);
2049 children = tmp = private->children;
2050 private->children = NULL;
2054 temp_window = tmp->data;
2057 temp_private = (GdkWindowObject*) temp_window;
2059 _gdk_window_destroy_hierarchy (temp_window,
2061 recursing_native || gdk_window_has_impl (private),
2065 g_list_free (children);
2068 _gdk_window_clear_update_area (window);
2070 gdk_window_drop_cairo_surface (private);
2072 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2074 if (gdk_window_has_impl (private))
2075 impl_iface->destroy (window, recursing_native,
2079 /* hide to make sure we repaint and break grabs */
2080 gdk_window_hide (window);
2083 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2084 private->parent = NULL;
2085 private->destroyed = TRUE;
2087 window_remove_filters (window);
2089 window_remove_from_pointer_info (window, display);
2091 if (private->clip_region)
2093 cairo_region_destroy (private->clip_region);
2094 private->clip_region = NULL;
2097 if (private->clip_region_with_children)
2099 cairo_region_destroy (private->clip_region_with_children);
2100 private->clip_region_with_children = NULL;
2103 if (private->outstanding_moves)
2105 g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2106 g_list_free (private->outstanding_moves);
2107 private->outstanding_moves = NULL;
2115 * _gdk_window_destroy:
2116 * @window: a #GdkWindow
2117 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2118 * external agency. The window has already been destroyed and no
2119 * windowing system calls should be made. (This may never happen
2120 * for some windowing systems.)
2122 * Internal function to destroy a window. Like gdk_window_destroy(),
2123 * but does not drop the reference count created by gdk_window_new().
2126 _gdk_window_destroy (GdkWindow *window,
2127 gboolean foreign_destroy)
2129 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2133 * gdk_window_destroy:
2134 * @window: a #GdkWindow
2136 * Destroys the window system resources associated with @window and decrements @window's
2137 * reference count. The window system resources for all children of @window are also
2138 * destroyed, but the children's reference counts are not decremented.
2140 * Note that a window will not be destroyed automatically when its reference count
2141 * reaches zero. You must call this function yourself before that happens.
2145 gdk_window_destroy (GdkWindow *window)
2147 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2148 g_object_unref (window);
2152 * gdk_window_set_user_data:
2153 * @window: a #GdkWindow
2154 * @user_data: user data
2156 * For most purposes this function is deprecated in favor of
2157 * g_object_set_data(). However, for historical reasons GTK+ stores
2158 * the #GtkWidget that owns a #GdkWindow as user data on the
2159 * #GdkWindow. So, custom widget implementations should use
2160 * this function for that. If GTK+ receives an event for a #GdkWindow,
2161 * and the user data for the window is non-%NULL, GTK+ will assume the
2162 * user data is a #GtkWidget, and forward the event to that widget.
2166 gdk_window_set_user_data (GdkWindow *window,
2169 g_return_if_fail (GDK_IS_WINDOW (window));
2171 ((GdkWindowObject*)window)->user_data = user_data;
2175 * gdk_window_get_user_data:
2176 * @window: a #GdkWindow
2177 * @data: return location for user data
2179 * Retrieves the user data for @window, which is normally the widget
2180 * that @window belongs to. See gdk_window_set_user_data().
2184 gdk_window_get_user_data (GdkWindow *window,
2187 g_return_if_fail (GDK_IS_WINDOW (window));
2189 *data = ((GdkWindowObject*)window)->user_data;
2193 * gdk_window_get_window_type:
2194 * @window: a #GdkWindow
2196 * Gets the type of the window. See #GdkWindowType.
2198 * Return value: type of window
2201 gdk_window_get_window_type (GdkWindow *window)
2203 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2205 return GDK_WINDOW_TYPE (window);
2209 * gdk_window_get_visual:
2210 * @window: a #GdkWindow
2212 * Gets the #GdkVisual describing the pixel format of @window.
2214 * Return value: a #GdkVisual
2219 gdk_window_get_visual (GdkWindow *window)
2221 GdkWindowObject *private;
2223 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2225 private = (GdkWindowObject *) window;
2227 return private->visual;
2231 * gdk_window_get_screen:
2232 * @window: a #GdkWindow
2234 * Gets the #GdkScreen associated with a #GdkWindow.
2236 * Return value: the #GdkScreen associated with @window
2241 gdk_window_get_screen (GdkWindow *window)
2243 GdkWindowObject *private;
2245 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2247 private = (GdkWindowObject *) window;
2249 return gdk_visual_get_screen (private->visual);
2253 * gdk_window_get_display:
2254 * @window: a #GdkWindow
2256 * Gets the #GdkDisplay associated with a #GdkWindow.
2258 * Return value: the #GdkDisplay associated with @window
2263 gdk_window_get_display (GdkWindow *window)
2265 GdkWindowObject *private;
2267 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2269 private = (GdkWindowObject *) window;
2271 return gdk_screen_get_display (gdk_visual_get_screen (private->visual));
2274 * gdk_window_is_destroyed:
2275 * @window: a #GdkWindow
2277 * Check to see if a window is destroyed..
2279 * Return value: %TRUE if the window is destroyed
2284 gdk_window_is_destroyed (GdkWindow *window)
2286 return GDK_WINDOW_DESTROYED (window);
2290 to_embedder (GdkWindowObject *window,
2291 gdouble offscreen_x,
2292 gdouble offscreen_y,
2293 gdouble *embedder_x,
2294 gdouble *embedder_y)
2296 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2297 offscreen_x, offscreen_y,
2298 embedder_x, embedder_y);
2302 from_embedder (GdkWindowObject *window,
2305 gdouble *offscreen_x,
2306 gdouble *offscreen_y)
2308 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2309 embedder_x, embedder_y,
2310 offscreen_x, offscreen_y);
2314 * gdk_window_has_native:
2315 * @window: a #GdkWindow
2317 * Checks whether the window has a native window or not. Note that
2318 * you can use gdk_window_ensure_native() if a native window is needed.
2320 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2325 gdk_window_has_native (GdkWindow *window)
2329 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2331 w = GDK_WINDOW_OBJECT (window);
2333 return w->parent == NULL || w->parent->impl != w->impl;
2337 * gdk_window_get_position:
2338 * @window: a #GdkWindow
2339 * @x: X coordinate of window
2340 * @y: Y coordinate of window
2342 * Obtains the position of the window as reported in the
2343 * most-recently-processed #GdkEventConfigure. Contrast with
2344 * gdk_window_get_geometry() which queries the X server for the
2345 * current window position, regardless of which events have been
2346 * received or processed.
2348 * The position coordinates are relative to the window's parent window.
2352 gdk_window_get_position (GdkWindow *window,
2356 GdkWindowObject *obj;
2358 g_return_if_fail (GDK_IS_WINDOW (window));
2360 obj = (GdkWindowObject*) window;
2369 * gdk_window_get_parent:
2370 * @window: a #GdkWindow
2372 * Obtains the parent of @window, as known to GDK. Does not query the
2373 * X server; thus this returns the parent as passed to gdk_window_new(),
2374 * not the actual parent. This should never matter unless you're using
2375 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2376 * matter for toplevel windows, because the window manager may choose
2379 * Note that you should use gdk_window_get_effective_parent() when
2380 * writing generic code that walks up a window hierarchy, because
2381 * gdk_window_get_parent() will most likely not do what you expect if
2382 * there are offscreen windows in the hierarchy.
2384 * Return value: (transfer none): parent of @window
2387 gdk_window_get_parent (GdkWindow *window)
2389 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2391 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2395 * gdk_window_get_effective_parent:
2396 * @window: a #GdkWindow
2398 * Obtains the parent of @window, as known to GDK. Works like
2399 * gdk_window_get_parent() for normal windows, but returns the
2400 * window's embedder for offscreen windows.
2402 * See also: gdk_offscreen_window_get_embedder()
2404 * Return value: (transfer none): effective parent of @window
2409 gdk_window_get_effective_parent (GdkWindow *window)
2411 GdkWindowObject *obj;
2413 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2415 obj = (GdkWindowObject *)window;
2417 if (gdk_window_is_offscreen (obj))
2418 return gdk_offscreen_window_get_embedder (window);
2420 return (GdkWindow *) obj->parent;
2424 * gdk_window_get_toplevel:
2425 * @window: a #GdkWindow
2427 * Gets the toplevel window that's an ancestor of @window.
2429 * Any window type but %GDK_WINDOW_CHILD is considered a
2430 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2431 * has a root window as parent.
2433 * Note that you should use gdk_window_get_effective_toplevel() when
2434 * you want to get to a window's toplevel as seen on screen, because
2435 * gdk_window_get_toplevel() will most likely not do what you expect
2436 * if there are offscreen windows in the hierarchy.
2438 * Return value: (transfer none): the toplevel window containing @window
2441 gdk_window_get_toplevel (GdkWindow *window)
2443 GdkWindowObject *obj;
2445 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2447 obj = (GdkWindowObject *)window;
2449 while (obj->window_type == GDK_WINDOW_CHILD)
2451 if (gdk_window_is_toplevel (obj))
2456 return GDK_WINDOW (obj);
2460 * gdk_window_get_effective_toplevel:
2461 * @window: a #GdkWindow
2463 * Gets the toplevel window that's an ancestor of @window.
2465 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2466 * embedder as its parent, using gdk_window_get_effective_parent().
2468 * See also: gdk_offscreen_window_get_embedder()
2470 * Return value: (transfer none): the effective toplevel window containing @window
2475 gdk_window_get_effective_toplevel (GdkWindow *window)
2479 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2481 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2482 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2489 * gdk_window_get_children:
2490 * @window: a #GdkWindow
2492 * Gets the list of children of @window known to GDK.
2493 * This function only returns children created via GDK,
2494 * so for example it's useless when used with the root window;
2495 * it only returns windows an application created itself.
2497 * The returned list must be freed, but the elements in the
2500 * Return value: (transfer container) (element-type GdkWindow):
2501 * list of child windows inside @window
2504 gdk_window_get_children (GdkWindow *window)
2506 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2508 if (GDK_WINDOW_DESTROYED (window))
2511 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2515 * gdk_window_peek_children:
2516 * @window: a #GdkWindow
2518 * Like gdk_window_get_children(), but does not copy the list of
2519 * children, so the list does not need to be freed.
2521 * Return value: (transfer none) (element-type GdkWindow):
2522 * a reference to the list of child windows in @window
2525 gdk_window_peek_children (GdkWindow *window)
2527 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2529 if (GDK_WINDOW_DESTROYED (window))
2532 return GDK_WINDOW_OBJECT (window)->children;
2536 * gdk_window_add_filter:
2537 * @window: a #GdkWindow
2538 * @function: filter callback
2539 * @data: data to pass to filter callback
2541 * Adds an event filter to @window, allowing you to intercept events
2542 * before they reach GDK. This is a low-level operation and makes it
2543 * easy to break GDK and/or GTK+, so you have to know what you're
2544 * doing. Pass %NULL for @window to get all events for all windows,
2545 * instead of events for a specific window.
2547 * See gdk_display_add_client_message_filter() if you are interested
2548 * in X ClientMessage events.
2551 gdk_window_add_filter (GdkWindow *window,
2552 GdkFilterFunc function,
2555 GdkWindowObject *private;
2557 GdkEventFilter *filter;
2559 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2561 private = (GdkWindowObject*) window;
2562 if (private && GDK_WINDOW_DESTROYED (window))
2565 /* Filters are for the native events on the native window, so
2566 ensure there is a native window. */
2568 gdk_window_ensure_native (window);
2571 tmp_list = private->filters;
2573 tmp_list = _gdk_default_filters;
2577 filter = (GdkEventFilter *)tmp_list->data;
2578 if ((filter->function == function) && (filter->data == data))
2580 tmp_list = tmp_list->next;
2583 filter = g_new (GdkEventFilter, 1);
2584 filter->function = function;
2585 filter->data = data;
2588 private->filters = g_list_append (private->filters, filter);
2590 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2594 * gdk_window_remove_filter:
2595 * @window: a #GdkWindow
2596 * @function: previously-added filter function
2597 * @data: user data for previously-added filter function
2599 * Remove a filter previously added with gdk_window_add_filter().
2603 gdk_window_remove_filter (GdkWindow *window,
2604 GdkFilterFunc function,
2607 GdkWindowObject *private;
2608 GList *tmp_list, *node;
2609 GdkEventFilter *filter;
2611 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2613 private = (GdkWindowObject*) window;
2616 tmp_list = private->filters;
2618 tmp_list = _gdk_default_filters;
2622 filter = (GdkEventFilter *)tmp_list->data;
2624 tmp_list = tmp_list->next;
2626 if ((filter->function == function) && (filter->data == data))
2629 private->filters = g_list_remove_link (private->filters, node);
2631 _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
2632 g_list_free_1 (node);
2641 * gdk_screen_get_toplevel_windows:
2642 * @screen: The #GdkScreen where the toplevels are located.
2644 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2645 * A toplevel window is a child of the root window (see
2646 * gdk_get_default_root_window()).
2648 * The returned list should be freed with g_list_free(), but
2649 * its elements need not be freed.
2651 * Return value: (transfer container) (element-type GdkWindow):
2652 * list of toplevel windows, free with g_list_free()
2657 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2659 GdkWindow * root_window;
2660 GList *new_list = NULL;
2663 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2665 root_window = gdk_screen_get_root_window (screen);
2667 tmp_list = ((GdkWindowObject *)root_window)->children;
2670 GdkWindowObject *w = tmp_list->data;
2672 if (w->window_type != GDK_WINDOW_FOREIGN)
2673 new_list = g_list_prepend (new_list, w);
2674 tmp_list = tmp_list->next;
2681 * gdk_window_is_visible:
2682 * @window: a #GdkWindow
2684 * Checks whether the window has been mapped (with gdk_window_show() or
2685 * gdk_window_show_unraised()).
2687 * Return value: %TRUE if the window is mapped
2690 gdk_window_is_visible (GdkWindow *window)
2692 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2694 return GDK_WINDOW_IS_MAPPED (window);
2698 * gdk_window_is_viewable:
2699 * @window: a #GdkWindow
2701 * Check if the window and all ancestors of the window are
2702 * mapped. (This is not necessarily "viewable" in the X sense, since
2703 * we only check as far as we have GDK window parents, not to the root
2706 * Return value: %TRUE if the window is viewable
2709 gdk_window_is_viewable (GdkWindow *window)
2711 GdkWindowObject *private = (GdkWindowObject *)window;
2713 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2715 if (private->destroyed)
2718 return private->viewable;
2722 * gdk_window_get_state:
2723 * @window: a #GdkWindow
2725 * Gets the bitwise OR of the currently active window state flags,
2726 * from the #GdkWindowState enumeration.
2728 * Return value: window state bitfield
2731 gdk_window_get_state (GdkWindow *window)
2733 GdkWindowObject *private = (GdkWindowObject *)window;
2735 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2737 return private->state;
2740 static cairo_content_t
2741 gdk_window_get_content (GdkWindow *window)
2743 cairo_surface_t *surface;
2744 cairo_content_t content;
2746 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2748 surface = _gdk_drawable_ref_cairo_surface (window);
2749 content = cairo_surface_get_content (surface);
2750 cairo_surface_destroy (surface);
2755 /* This creates an empty "implicit" paint region for the impl window.
2756 * By itself this does nothing, but real paints to this window
2757 * or children of it can use this surface as backing to avoid allocating
2758 * multiple surfaces for subwindow rendering. When doing so they
2759 * add to the region of the implicit paint region, which will be
2760 * pushed to the window when the implicit paint region is ended.
2761 * Such paints should not copy anything to the window on paint end, but
2762 * should rely on the implicit paint end.
2763 * The implicit paint will be automatically ended if someone draws
2764 * directly to the window or a child window.
2767 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2769 GdkWindowObject *private = (GdkWindowObject *)window;
2770 GdkWindowPaint *paint;
2772 g_assert (gdk_window_has_impl (private));
2774 if (_gdk_native_windows)
2775 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2777 if (GDK_IS_PAINTABLE (private->impl))
2778 return FALSE; /* Implementation does double buffering */
2780 if (private->paint_stack != NULL ||
2781 private->implicit_paint != NULL)
2782 return FALSE; /* Don't stack implicit paints */
2784 if (private->outstanding_surfaces != 0)
2785 return FALSE; /* May conflict with direct drawing to cairo surface */
2787 /* Never do implicit paints for foreign windows, they don't need
2788 * double buffer combination since they have no client side children,
2789 * and creating surfaces for them is risky since they could disappear
2792 if (private->window_type == GDK_WINDOW_FOREIGN)
2795 paint = g_new (GdkWindowPaint, 1);
2796 paint->region = cairo_region_create (); /* Empty */
2797 paint->uses_implicit = FALSE;
2798 paint->flushed = FALSE;
2799 paint->surface = gdk_window_create_similar_surface (window,
2800 gdk_window_get_content (window),
2801 MAX (rect->width, 1),
2802 MAX (rect->height, 1));
2803 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2805 private->implicit_paint = paint;
2810 /* Ensure that all content related to this (sub)window is pushed to the
2811 native region. If there is an active paint then that area is not
2812 pushed, in order to not show partially finished double buffers. */
2814 gdk_window_flush_implicit_paint (GdkWindow *window)
2816 GdkWindowObject *private = (GdkWindowObject *)window;
2817 GdkWindowObject *impl_window;
2818 GdkWindowPaint *paint;
2819 cairo_region_t *region;
2822 impl_window = gdk_window_get_impl_window (private);
2823 if (impl_window->implicit_paint == NULL)
2826 paint = impl_window->implicit_paint;
2827 paint->flushed = TRUE;
2828 region = cairo_region_copy (private->clip_region_with_children);
2830 /* Don't flush active double buffers, as that may show partially done
2832 for (list = private->paint_stack; list != NULL; list = list->next)
2834 GdkWindowPaint *tmp_paint = list->data;
2836 cairo_region_subtract (region, tmp_paint->region);
2839 cairo_region_translate (region, -private->abs_x, -private->abs_y);
2840 cairo_region_intersect (region, paint->region);
2842 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2846 /* Remove flushed region from the implicit paint */
2847 cairo_region_subtract (paint->region, region);
2849 /* Some regions are valid, push these to window now */
2850 cr = gdk_cairo_create (private->impl);
2851 gdk_cairo_region (cr, region);
2853 cairo_set_source_surface (cr, paint->surface, 0, 0);
2854 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2859 cairo_region_destroy (region);
2862 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2864 gdk_window_end_implicit_paint (GdkWindow *window)
2866 GdkWindowObject *private = (GdkWindowObject *)window;
2867 GdkWindowPaint *paint;
2869 g_assert (gdk_window_has_impl (private));
2871 g_assert (private->implicit_paint != NULL);
2873 paint = private->implicit_paint;
2875 private->implicit_paint = NULL;
2877 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2881 /* Some regions are valid, push these to window now */
2882 cr = gdk_cairo_create (private->impl);
2883 gdk_cairo_region (cr, paint->region);
2885 cairo_set_source_surface (cr, paint->surface, 0, 0);
2886 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2891 cairo_region_destroy (paint->region);
2893 cairo_surface_destroy (paint->surface);
2898 * gdk_window_begin_paint_rect:
2899 * @window: a #GdkWindow
2900 * @rectangle: rectangle you intend to draw to
2902 * A convenience wrapper around gdk_window_begin_paint_region() which
2903 * creates a rectangular region for you. See
2904 * gdk_window_begin_paint_region() for details.
2908 gdk_window_begin_paint_rect (GdkWindow *window,
2909 const GdkRectangle *rectangle)
2911 cairo_region_t *region;
2913 g_return_if_fail (GDK_IS_WINDOW (window));
2915 region = cairo_region_create_rectangle (rectangle);
2916 gdk_window_begin_paint_region (window, region);
2917 cairo_region_destroy (region);
2921 * gdk_window_begin_paint_region:
2922 * @window: a #GdkWindow
2923 * @region: region you intend to draw to
2925 * Indicates that you are beginning the process of redrawing @region.
2926 * A backing store (offscreen buffer) large enough to contain @region
2927 * will be created. The backing store will be initialized with the
2928 * background color or background surface for @window. Then, all
2929 * drawing operations performed on @window will be diverted to the
2930 * backing store. When you call gdk_window_end_paint(), the backing
2931 * store will be copied to @window, making it visible onscreen. Only
2932 * the part of @window contained in @region will be modified; that is,
2933 * drawing operations are clipped to @region.
2935 * The net result of all this is to remove flicker, because the user
2936 * sees the finished product appear all at once when you call
2937 * gdk_window_end_paint(). If you draw to @window directly without
2938 * calling gdk_window_begin_paint_region(), the user may see flicker
2939 * as individual drawing operations are performed in sequence. The
2940 * clipping and background-initializing features of
2941 * gdk_window_begin_paint_region() are conveniences for the
2942 * programmer, so you can avoid doing that work yourself.
2944 * When using GTK+, the widget system automatically places calls to
2945 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2946 * emissions of the expose_event signal. That is, if you're writing an
2947 * expose event handler, you can assume that the exposed area in
2948 * #GdkEventExpose has already been cleared to the window background,
2949 * is already set as the clip region, and already has a backing store.
2950 * Therefore in most cases, application code need not call
2951 * gdk_window_begin_paint_region(). (You can disable the automatic
2952 * calls around expose events on a widget-by-widget basis by calling
2953 * gtk_widget_set_double_buffered().)
2955 * If you call this function multiple times before calling the
2956 * matching gdk_window_end_paint(), the backing stores are pushed onto
2957 * a stack. gdk_window_end_paint() copies the topmost backing store
2958 * onscreen, subtracts the topmost region from all other regions in
2959 * the stack, and pops the stack. All drawing operations affect only
2960 * the topmost backing store in the stack. One matching call to
2961 * gdk_window_end_paint() is required for each call to
2962 * gdk_window_begin_paint_region().
2966 gdk_window_begin_paint_region (GdkWindow *window,
2967 const cairo_region_t *region)
2969 #ifdef USE_BACKING_STORE
2970 GdkWindowObject *private = (GdkWindowObject *)window;
2971 GdkRectangle clip_box;
2972 GdkWindowPaint *paint, *implicit_paint;
2973 GdkWindowObject *impl_window;
2976 g_return_if_fail (GDK_IS_WINDOW (window));
2978 if (GDK_WINDOW_DESTROYED (window))
2981 if (GDK_IS_PAINTABLE (private->impl))
2983 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
2985 if (iface->begin_paint_region)
2986 iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
2991 impl_window = gdk_window_get_impl_window (private);
2992 implicit_paint = impl_window->implicit_paint;
2994 paint = g_new (GdkWindowPaint, 1);
2995 paint->region = cairo_region_copy (region);
2996 paint->region_tag = new_region_tag ();
2998 cairo_region_intersect (paint->region, private->clip_region_with_children);
2999 cairo_region_get_extents (paint->region, &clip_box);
3001 cairo_region_translate (paint->region, private->abs_x, private->abs_y);
3003 /* Mark the region as valid on the implicit paint */
3006 cairo_region_union (implicit_paint->region, paint->region);
3008 /* Convert back to normal coords */
3009 cairo_region_translate (paint->region, -private->abs_x, -private->abs_y);
3013 paint->uses_implicit = TRUE;
3014 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
3015 private->abs_x + clip_box.x,
3016 private->abs_y + clip_box.y,
3017 MAX (clip_box.width, 1),
3018 MAX (clip_box.height, 1));
3022 paint->uses_implicit = FALSE;
3023 paint->surface = gdk_window_create_similar_surface (window,
3024 gdk_window_get_content (window),
3025 MAX (clip_box.width, 1),
3026 MAX (clip_box.height, 1));
3028 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
3030 for (list = private->paint_stack; list != NULL; list = list->next)
3032 GdkWindowPaint *tmp_paint = list->data;
3034 cairo_region_subtract (tmp_paint->region, paint->region);
3037 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
3039 if (!cairo_region_is_empty (paint->region))
3041 gdk_window_clear_backing_region (window,
3045 #endif /* USE_BACKING_STORE */
3049 * gdk_window_end_paint:
3050 * @window: a #GdkWindow
3052 * Indicates that the backing store created by the most recent call to
3053 * gdk_window_begin_paint_region() should be copied onscreen and
3054 * deleted, leaving the next-most-recent backing store or no backing
3055 * store at all as the active paint region. See
3056 * gdk_window_begin_paint_region() for full details. It is an error to
3057 * call this function without a matching
3058 * gdk_window_begin_paint_region() first.
3062 gdk_window_end_paint (GdkWindow *window)
3064 #ifdef USE_BACKING_STORE
3065 GdkWindowObject *private = (GdkWindowObject *)window;
3066 GdkWindowObject *composited;
3067 GdkWindowPaint *paint;
3068 GdkRectangle clip_box;
3069 cairo_region_t *full_clip;
3071 g_return_if_fail (GDK_IS_WINDOW (window));
3073 if (GDK_WINDOW_DESTROYED (window))
3076 if (GDK_IS_PAINTABLE (private->impl))
3078 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3080 if (iface->end_paint)
3081 iface->end_paint ((GdkPaintable*)private->impl);
3085 if (private->paint_stack == NULL)
3087 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3091 paint = private->paint_stack->data;
3093 private->paint_stack = g_slist_delete_link (private->paint_stack,
3094 private->paint_stack);
3096 cairo_region_get_extents (paint->region, &clip_box);
3098 if (!paint->uses_implicit)
3102 gdk_window_flush_outstanding_moves (window);
3104 full_clip = cairo_region_copy (private->clip_region_with_children);
3105 cairo_region_intersect (full_clip, paint->region);
3107 cr = gdk_cairo_create (window);
3108 cairo_set_source_surface (cr, paint->surface, 0, 0);
3109 gdk_cairo_region (cr, full_clip);
3113 cairo_region_destroy (full_clip);
3116 cairo_surface_destroy (paint->surface);
3117 cairo_region_destroy (paint->region);
3120 /* find a composited window in our hierarchy to signal its
3121 * parent to redraw, calculating the clip box as we go...
3123 * stop if parent becomes NULL since then we'd have nowhere
3124 * to draw (ie: 'composited' will always be non-NULL here).
3126 for (composited = private;
3128 composited = composited->parent)
3130 clip_box.x += composited->x;
3131 clip_box.y += composited->y;
3132 clip_box.width = MIN (clip_box.width, composited->parent->width - clip_box.x);
3133 clip_box.height = MIN (clip_box.height, composited->parent->height - clip_box.y);
3135 if (composited->composited)
3137 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3142 #endif /* USE_BACKING_STORE */
3146 gdk_window_free_paint_stack (GdkWindow *window)
3148 GdkWindowObject *private = (GdkWindowObject *)window;
3150 if (private->paint_stack)
3152 GSList *tmp_list = private->paint_stack;
3156 GdkWindowPaint *paint = tmp_list->data;
3158 if (tmp_list == private->paint_stack)
3159 cairo_surface_destroy (paint->surface);
3161 cairo_region_destroy (paint->region);
3164 tmp_list = tmp_list->next;
3167 g_slist_free (private->paint_stack);
3168 private->paint_stack = NULL;
3173 do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3174 cairo_region_t *dest_region, /* In impl window coords */
3177 GdkWindowImplIface *impl_iface;
3179 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (impl_window->impl);
3181 impl_iface->translate ((GdkWindow *) impl_window, dest_region, dx, dy);
3184 static GdkWindowRegionMove *
3185 gdk_window_region_move_new (cairo_region_t *region,
3188 GdkWindowRegionMove *move;
3190 move = g_slice_new (GdkWindowRegionMove);
3191 move->dest_region = cairo_region_copy (region);
3199 gdk_window_region_move_free (GdkWindowRegionMove *move)
3201 cairo_region_destroy (move->dest_region);
3202 g_slice_free (GdkWindowRegionMove, move);
3206 append_move_region (GdkWindowObject *impl_window,
3207 cairo_region_t *new_dest_region,
3210 GdkWindowRegionMove *move, *old_move;
3211 cairo_region_t *new_total_region, *old_total_region;
3212 cairo_region_t *source_overlaps_destination;
3213 cairo_region_t *non_overwritten;
3214 gboolean added_move;
3217 if (cairo_region_is_empty (new_dest_region))
3220 /* In principle this could just append the move to the list of outstanding
3221 moves that will be replayed before drawing anything when we're handling
3222 exposes. However, we'd like to do a bit better since its commonly the case
3223 that we get multiple copies where A is copied to B and then B is copied
3224 to C, and we'd like to express this as a simple copy A to C operation. */
3226 /* We approach this by taking the new move and pushing it ahead of moves
3227 starting at the end of the list and stopping when its not safe to do so.
3228 It's not safe to push past a move if either the source of the new move
3229 is in the destination of the old move, or if the destination of the new
3230 move is in the source of the new move, or if the destination of the new
3231 move overlaps the destination of the old move. We simplify this by
3232 just comparing the total regions (src + dest) */
3233 new_total_region = cairo_region_copy (new_dest_region);
3234 cairo_region_translate (new_total_region, -dx, -dy);
3235 cairo_region_union (new_total_region, new_dest_region);
3238 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3243 old_total_region = cairo_region_copy (old_move->dest_region);
3244 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3245 cairo_region_union (old_total_region, old_move->dest_region);
3247 cairo_region_intersect (old_total_region, new_total_region);
3248 /* If these regions intersect then its not safe to push the
3249 new region before the old one */
3250 if (!cairo_region_is_empty (old_total_region))
3252 /* The area where the new moves source overlaps the old ones
3254 source_overlaps_destination = cairo_region_copy (new_dest_region);
3255 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3256 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3257 cairo_region_translate (source_overlaps_destination, dx, dy);
3259 /* We can do all sort of optimizations here, but to do things safely it becomes
3260 quite complicated. However, a very common case is that you copy something first,
3261 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3262 in the same direction). We'd like to detect this case and optimize it to one
3264 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3266 /* This means we might be able to replace the old move and the new one
3267 with the new one read from the old ones source, and a second copy of
3268 the non-overwritten parts of the old move. However, such a split
3269 is only valid if the source in the old move isn't overwritten
3270 by the destination of the new one */
3272 /* the new destination of old move if split is ok: */
3273 non_overwritten = cairo_region_copy (old_move->dest_region);
3274 cairo_region_subtract (non_overwritten, new_dest_region);
3275 /* move to source region */
3276 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3278 cairo_region_intersect (non_overwritten, new_dest_region);
3279 if (cairo_region_is_empty (non_overwritten))
3282 move = gdk_window_region_move_new (new_dest_region,
3286 impl_window->outstanding_moves =
3287 g_list_insert_before (impl_window->outstanding_moves,
3289 cairo_region_subtract (old_move->dest_region, new_dest_region);
3291 cairo_region_destroy (non_overwritten);
3294 cairo_region_destroy (source_overlaps_destination);
3295 cairo_region_destroy (old_total_region);
3298 cairo_region_destroy (old_total_region);
3301 cairo_region_destroy (new_total_region);
3305 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3308 impl_window->outstanding_moves =
3309 g_list_prepend (impl_window->outstanding_moves,
3312 impl_window->outstanding_moves =
3313 g_list_insert_before (impl_window->outstanding_moves,
3318 /* Moves bits and update area by dx/dy in impl window.
3319 Takes ownership of region to avoid copy (because we may change it) */
3321 move_region_on_impl (GdkWindowObject *impl_window,
3322 cairo_region_t *region, /* In impl window coords */
3325 if ((dx == 0 && dy == 0) ||
3326 cairo_region_is_empty (region))
3328 cairo_region_destroy (region);
3332 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3334 /* Move any old invalid regions in the copy source area by dx/dy */
3335 if (impl_window->update_area)
3337 cairo_region_t *update_area;
3339 update_area = cairo_region_copy (region);
3341 /* Convert from target to source */
3342 cairo_region_translate (update_area, -dx, -dy);
3343 cairo_region_intersect (update_area, impl_window->update_area);
3344 /* We only copy the area, so keep the old update area invalid.
3345 It would be safe to remove it too, as code that uses
3346 move_region_on_impl generally also invalidate the source
3347 area. However, it would just use waste cycles. */
3350 cairo_region_translate (update_area, dx, dy);
3351 cairo_region_union (impl_window->update_area, update_area);
3353 /* This area of the destination is now invalid,
3354 so no need to copy to it. */
3355 cairo_region_subtract (region, update_area);
3357 cairo_region_destroy (update_area);
3360 /* If we're currently exposing this window, don't copy to this
3361 destination, as it will be overdrawn when the expose is done,
3362 instead invalidate it and repaint later. */
3363 if (impl_window->implicit_paint)
3365 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3366 cairo_region_t *exposing;
3368 exposing = cairo_region_copy (implicit_paint->region);
3369 cairo_region_intersect (exposing, region);
3370 cairo_region_subtract (region, exposing);
3372 impl_window_add_update_area (impl_window, exposing);
3373 cairo_region_destroy (exposing);
3376 if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3377 append_move_region (impl_window, region, dx, dy);
3379 do_move_region_bits_on_impl (impl_window,
3382 cairo_region_destroy (region);
3385 /* Flushes all outstanding changes to the window, call this
3386 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3389 gdk_window_flush_outstanding_moves (GdkWindow *window)
3391 GdkWindowObject *private;
3392 GdkWindowObject *impl_window;
3393 GList *l, *outstanding;
3394 GdkWindowRegionMove *move;
3396 private = (GdkWindowObject *) window;
3398 impl_window = gdk_window_get_impl_window (private);
3399 outstanding = impl_window->outstanding_moves;
3400 impl_window->outstanding_moves = NULL;
3402 for (l = outstanding; l != NULL; l = l->next)
3406 do_move_region_bits_on_impl (impl_window,
3407 move->dest_region, move->dx, move->dy);
3409 gdk_window_region_move_free (move);
3412 g_list_free (outstanding);
3417 * @window: a #GdkWindow
3419 * Flush all outstanding cached operations on a window, leaving the
3420 * window in a state which reflects all that has been drawn before.
3422 * Gdk uses multiple kinds of caching to get better performance and
3423 * nicer drawing. For instance, during exposes all paints to a window
3424 * using double buffered rendering are keep on a surface until the last
3425 * window has been exposed. It also delays window moves/scrolls until
3426 * as long as possible until next update to avoid tearing when moving
3429 * Normally this should be completely invisible to applications, as
3430 * we automatically flush the windows when required, but this might
3431 * be needed if you for instance mix direct native drawing with
3432 * gdk drawing. For Gtk widgets that don't use double buffering this
3433 * will be called automatically before sending the expose event.
3438 gdk_window_flush (GdkWindow *window)
3440 gdk_window_flush_outstanding_moves (window);
3441 gdk_window_flush_implicit_paint (window);
3444 /* If we're about to move/resize or otherwise change the
3445 * hierarchy of a client side window in an impl and we're
3446 * called from an expose event handler then we need to
3447 * flush any already painted parts of the implicit paint
3448 * that are not part of the current paint, as these may
3449 * be used when scrolling or may overdraw the changes
3450 * caused by the hierarchy change.
3453 gdk_window_flush_if_exposing (GdkWindow *window)
3455 GdkWindowObject *private;
3456 GdkWindowObject *impl_window;
3458 private = (GdkWindowObject *) window;
3459 impl_window = gdk_window_get_impl_window (private);
3461 /* If we're in an implicit paint (i.e. in an expose handler, flush
3462 all the already finished exposes to get things to an uptodate state. */
3463 if (impl_window->implicit_paint)
3464 gdk_window_flush (window);
3469 gdk_window_flush_recursive_helper (GdkWindowObject *window,
3472 GdkWindowObject *child;
3475 for (l = window->children; l != NULL; l = l->next)
3479 if (child->impl == impl)
3480 /* Same impl, ignore */
3481 gdk_window_flush_recursive_helper (child, impl);
3483 gdk_window_flush_recursive (child);
3488 gdk_window_flush_recursive (GdkWindowObject *window)
3490 gdk_window_flush ((GdkWindow *)window);
3491 gdk_window_flush_recursive_helper (window, window->impl);
3494 static cairo_region_t*
3495 gdk_window_get_clip_region (GdkDrawable *drawable)
3497 GdkWindowObject *private = (GdkWindowObject *)drawable;
3498 cairo_region_t *result;
3500 result = cairo_region_copy (private->clip_region);
3502 if (private->paint_stack)
3504 cairo_region_t *paint_region = cairo_region_create ();
3505 GSList *tmp_list = private->paint_stack;
3509 GdkWindowPaint *paint = tmp_list->data;
3511 cairo_region_union (paint_region, paint->region);
3513 tmp_list = tmp_list->next;
3516 cairo_region_intersect (result, paint_region);
3517 cairo_region_destroy (paint_region);
3523 static cairo_region_t*
3524 gdk_window_get_visible_region (GdkDrawable *drawable)
3526 GdkWindowObject *private = (GdkWindowObject*) drawable;
3528 return cairo_region_copy (private->clip_region);
3532 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3534 GdkWindowObject *private = (GdkWindowObject *) window;
3535 GdkWindowObject *bg_private;
3536 cairo_pattern_t *pattern = NULL;
3537 int x_offset = 0, y_offset = 0;
3540 cr = cairo_create (paint->surface);
3542 for (bg_private = private; bg_private; bg_private = bg_private->parent)
3544 pattern = gdk_window_get_background_pattern ((GdkWindow *) bg_private);
3548 x_offset += bg_private->x;
3549 y_offset += bg_private->y;
3554 cairo_translate (cr, -x_offset, -y_offset);
3555 cairo_set_source (cr, pattern);
3556 cairo_translate (cr, x_offset, y_offset);
3559 cairo_set_source_rgb (cr, 0, 0, 0);
3565 gdk_window_clear_backing_region (GdkWindow *window,
3566 cairo_region_t *region)
3568 GdkWindowObject *private = (GdkWindowObject *)window;
3569 GdkWindowPaint *paint = private->paint_stack->data;
3570 cairo_region_t *clip;
3571 GdkRectangle clipbox;
3574 if (GDK_WINDOW_DESTROYED (window))
3577 cr = setup_backing_rect (window, paint, 0, 0);
3579 clip = cairo_region_copy (paint->region);
3580 cairo_region_intersect (clip, region);
3581 cairo_region_get_extents (clip, &clipbox);
3583 gdk_cairo_region (cr, clip);
3588 cairo_region_destroy (clip);
3592 gdk_window_clear_backing_region_direct (GdkWindow *window,
3593 cairo_region_t *region)
3595 GdkWindowObject *private = (GdkWindowObject *)window;
3596 GdkWindowPaint paint;
3597 cairo_region_t *clip;
3598 GdkRectangle clipbox;
3601 if (GDK_WINDOW_DESTROYED (window))
3604 paint.surface = _gdk_drawable_ref_cairo_surface (window);
3606 cr = setup_backing_rect (window, &paint, 0, 0);
3608 clip = cairo_region_copy (private->clip_region_with_children);
3609 cairo_region_intersect (clip, region);
3610 cairo_region_get_extents (clip, &clipbox);
3612 gdk_cairo_region (cr, clip);
3617 cairo_region_destroy (clip);
3618 cairo_surface_destroy (paint.surface);
3623 gdk_window_clear_region_internal (GdkWindow *window,
3624 cairo_region_t *region)
3626 GdkWindowObject *private = (GdkWindowObject *)window;
3628 if (private->paint_stack)
3629 gdk_window_clear_backing_region (window, region);
3631 gdk_window_clear_backing_region_direct (window, region);
3635 gdk_window_drop_cairo_surface (GdkWindowObject *private)
3637 if (private->cairo_surface)
3639 cairo_surface_finish (private->cairo_surface);
3640 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3642 private->cairo_surface = NULL;
3647 gdk_window_cairo_surface_destroy (void *data)
3649 GdkWindowObject *private = (GdkWindowObject*) data;
3651 private->cairo_surface = NULL;
3652 private->impl_window->outstanding_surfaces--;
3655 static cairo_surface_t *
3656 gdk_window_create_cairo_surface (GdkDrawable *drawable,
3660 GdkWindowObject *private = GDK_WINDOW_OBJECT(drawable);
3661 cairo_surface_t *surface, *subsurface;
3663 surface =_gdk_drawable_ref_cairo_surface (private->impl);
3664 if (gdk_window_has_impl (private))
3667 subsurface = cairo_surface_create_for_rectangle (surface,
3672 cairo_surface_destroy (surface);
3677 static cairo_surface_t *
3678 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
3680 GdkWindowObject *private = (GdkWindowObject*) drawable;
3681 cairo_surface_t *surface;
3683 if (private->paint_stack)
3685 GdkWindowPaint *paint = private->paint_stack->data;
3687 surface = paint->surface;
3688 cairo_surface_reference (surface);
3693 /* This will be drawing directly to the window, so flush implicit paint */
3694 gdk_window_flush ((GdkWindow *)drawable);
3696 if (!private->cairo_surface)
3698 private->cairo_surface = _gdk_drawable_create_cairo_surface (drawable,
3702 if (private->cairo_surface)
3704 private->impl_window->outstanding_surfaces++;
3706 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3707 drawable, gdk_window_cairo_surface_destroy);
3711 cairo_surface_reference (private->cairo_surface);
3713 surface = private->cairo_surface;
3720 gdk_window_set_cairo_clip (GdkDrawable *drawable,
3723 GdkWindowObject *private = (GdkWindowObject*) drawable;
3725 if (!private->paint_stack)
3727 cairo_reset_clip (cr);
3730 cairo_identity_matrix (cr);
3732 cairo_new_path (cr);
3733 gdk_cairo_region (cr, private->clip_region_with_children);
3740 GdkWindowPaint *paint = private->paint_stack->data;
3742 /* Only needs to clip to region if piggybacking
3743 on an implicit paint */
3744 cairo_reset_clip (cr);
3745 if (paint->uses_implicit)
3748 cairo_identity_matrix (cr);
3750 cairo_new_path (cr);
3751 gdk_cairo_region (cr, paint->region);
3759 /* Code for dirty-region queueing
3761 static GSList *update_windows = NULL;
3762 static guint update_idle = 0;
3763 static gboolean debug_updates = FALSE;
3765 static inline gboolean
3766 gdk_window_is_ancestor (GdkWindow *window,
3767 GdkWindow *ancestor)
3771 GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
3773 if (parent == ancestor)
3783 gdk_window_add_update_window (GdkWindow *window)
3786 GSList *prev = NULL;
3787 gboolean has_ancestor_in_list = FALSE;
3789 for (tmp = update_windows; tmp; tmp = tmp->next)
3791 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
3793 /* check if tmp is an ancestor of "window"; if it is, set a
3794 * flag indicating that all following windows are either
3795 * children of "window" or from a differen hierarchy
3797 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3798 has_ancestor_in_list = TRUE;
3800 /* insert in reverse stacking order when adding around siblings,
3801 * so processing updates properly paints over lower stacked windows
3803 if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
3805 gint index = g_list_index (parent->children, window);
3806 for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
3808 gint sibling_index = g_list_index (parent->children, tmp->data);
3809 if (index > sibling_index)
3813 /* here, tmp got advanced past all lower stacked siblings */
3814 tmp = g_slist_prepend (tmp, window);
3818 update_windows = tmp;
3822 /* if "window" has an ancestor in the list and tmp is one of
3823 * "window's" children, insert "window" before tmp
3825 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3827 tmp = g_slist_prepend (tmp, window);
3832 update_windows = tmp;
3836 /* if we're at the end of the list and had an ancestor it it,
3837 * append to the list
3839 if (! tmp->next && has_ancestor_in_list)
3841 tmp = g_slist_append (tmp, window);
3848 /* if all above checks failed ("window" is from a different
3849 * hierarchy than what is already in the list) or the list is
3852 update_windows = g_slist_prepend (update_windows, window);
3856 gdk_window_remove_update_window (GdkWindow *window)
3858 update_windows = g_slist_remove (update_windows, window);
3862 gdk_window_update_idle (gpointer data)
3864 gdk_window_process_all_updates ();
3870 gdk_window_is_toplevel_frozen (GdkWindow *window)
3872 GdkWindowObject *toplevel;
3874 toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
3876 return toplevel->update_and_descendants_freeze_count > 0;
3880 gdk_window_schedule_update (GdkWindow *window)
3883 (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
3884 gdk_window_is_toplevel_frozen (window)))
3889 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
3890 gdk_window_update_idle,
3895 _gdk_window_process_updates_recurse (GdkWindow *window,
3896 cairo_region_t *expose_region)
3898 GdkWindowObject *private = (GdkWindowObject *)window;
3899 GdkWindowObject *child;
3900 cairo_region_t *child_region;
3902 GList *l, *children;
3904 if (cairo_region_is_empty (expose_region))
3907 if (gdk_window_is_offscreen (private->impl_window) &&
3908 private == private->impl_window)
3909 _gdk_window_add_damage ((GdkWindow *) private->impl_window, expose_region);
3911 /* Make this reentrancy safe for expose handlers freeing windows */
3912 children = g_list_copy (private->children);
3913 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3915 /* Iterate over children, starting at topmost */
3916 for (l = children; l != NULL; l = l->next)
3920 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3923 /* Ignore offscreen children, as they don't draw in their parent and
3924 * don't take part in the clipping */
3925 if (gdk_window_is_offscreen (child))
3930 r.width = child->width;
3931 r.height = child->height;
3933 child_region = cairo_region_create_rectangle (&r);
3936 /* Adjust shape region to parent window coords */
3937 cairo_region_translate (child->shape, child->x, child->y);
3938 cairo_region_intersect (child_region, child->shape);
3939 cairo_region_translate (child->shape, -child->x, -child->y);
3942 if (child->impl == private->impl)
3944 /* Client side child, expose */
3945 cairo_region_intersect (child_region, expose_region);
3946 cairo_region_subtract (expose_region, child_region);
3947 cairo_region_translate (child_region, -child->x, -child->y);
3948 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
3952 /* Native child, just remove area from expose region */
3953 cairo_region_subtract (expose_region, child_region);
3955 cairo_region_destroy (child_region);
3958 g_list_foreach (children, (GFunc)g_object_unref, NULL);
3959 g_list_free (children);
3961 if (!cairo_region_is_empty (expose_region) &&
3962 !private->destroyed)
3964 if (private->event_mask & GDK_EXPOSURE_MASK)
3968 event.expose.type = GDK_EXPOSE;
3969 event.expose.window = g_object_ref (window);
3970 event.expose.send_event = FALSE;
3971 event.expose.count = 0;
3972 event.expose.region = expose_region;
3973 cairo_region_get_extents (expose_region, &event.expose.area);
3975 (*_gdk_event_func) (&event, _gdk_event_data);
3977 g_object_unref (window);
3979 else if (private->window_type != GDK_WINDOW_FOREIGN)
3981 /* No exposure mask set, so nothing will be drawn, the
3982 * app relies on the background being what it specified
3983 * for the window. So, we need to clear this manually.
3985 * For foreign windows if expose is not set that generally
3986 * means some other client paints them, so don't clear
3989 * We use begin/end_paint around the clear so that we can
3990 * piggyback on the implicit paint */
3992 gdk_window_begin_paint_region (window, expose_region);
3993 gdk_window_clear_region_internal (window, expose_region);
3994 gdk_window_end_paint (window);
3999 /* Process and remove any invalid area on the native window by creating
4000 * expose events for the window and all non-native descendants.
4001 * Also processes any outstanding moves on the window before doing
4002 * any drawing. Note that its possible to have outstanding moves without
4003 * any invalid area as we use the update idle mechanism to coalesce
4004 * multiple moves as well as multiple invalidations.
4007 gdk_window_process_updates_internal (GdkWindow *window)
4009 GdkWindowObject *private = (GdkWindowObject *)window;
4010 GdkWindowImplIface *impl_iface;
4011 gboolean save_region = FALSE;
4012 GdkRectangle clip_box;
4014 /* Ensure the window lives while updating it */
4015 g_object_ref (window);
4017 /* If an update got queued during update processing, we can get a
4018 * window in the update queue that has an empty update_area.
4021 if (private->update_area)
4023 cairo_region_t *update_area = private->update_area;
4024 private->update_area = NULL;
4026 if (_gdk_event_func && gdk_window_is_viewable (window))
4028 cairo_region_t *expose_region;
4029 gboolean end_implicit;
4031 /* Clip to part visible in toplevel */
4032 cairo_region_intersect (update_area, private->clip_region);
4036 /* Make sure we see the red invalid area before redrawing. */
4037 gdk_display_sync (gdk_window_get_display (window));
4041 /* At this point we will be completely redrawing all of update_area.
4042 * If we have any outstanding moves that end up moving stuff inside
4043 * this area we don't actually need to move that as that part would
4044 * be overdrawn by the expose anyway. So, in order to copy less data
4045 * we remove these areas from the outstanding moves.
4047 if (private->outstanding_moves)
4049 GdkWindowRegionMove *move;
4050 cairo_region_t *remove;
4053 remove = cairo_region_copy (update_area);
4054 /* We iterate backwards, starting from the state that would be
4055 if we had applied all the moves. */
4056 for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
4061 /* Don't need this area */
4062 cairo_region_subtract (move->dest_region, remove);
4064 /* However if any of the destination we do need has a source
4065 in the updated region we do need that as a destination for
4066 the earlier moves */
4067 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
4068 cairo_region_subtract (remove, move->dest_region);
4070 if (cairo_region_is_empty (move->dest_region))
4072 gdk_window_region_move_free (move);
4073 private->outstanding_moves =
4074 g_list_delete_link (private->outstanding_moves, l);
4076 else /* move back */
4077 cairo_region_translate (move->dest_region, move->dx, move->dy);
4079 cairo_region_destroy (remove);
4082 /* By now we a set of window moves that should be applied, and then
4083 * an update region that should be repainted. A trivial implementation
4084 * would just do that in order, however in order to get nicer drawing
4085 * we do some tricks:
4087 * First of all, each subwindow expose may be double buffered by
4088 * itself (depending on widget setting) via
4089 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
4090 * creating a single surface the size of the invalid area on the
4091 * native window which all the individual normal paints will draw
4092 * into. This way in the normal case there will be only one surface
4093 * allocated and only once surface draw done for all the windows
4094 * in this native window.
4095 * There are a couple of reasons this may fail, for instance, some
4096 * backends (like quartz) do its own double buffering, so we disable
4097 * gdk double buffering there. Secondly, some subwindow could be
4098 * non-double buffered and draw directly to the window outside a
4099 * begin/end_paint pair. That will be lead to a gdk_window_flush
4100 * which immediately executes all outstanding moves and paints+removes
4101 * the implicit paint (further paints will allocate their own surfaces).
4103 * Secondly, in the case of implicit double buffering we expose all
4104 * the child windows into the implicit surface before we execute
4105 * the outstanding moves. This way we minimize the time between
4106 * doing the moves and rendering the new update area, thus minimizing
4107 * flashing. Of course, if any subwindow is non-double buffered we
4108 * well flush earlier than that.
4110 * Thirdly, after having done the outstanding moves we queue an
4111 * "antiexpose" on the area that will be drawn by the expose, which
4112 * means that any invalid region on the native window side before
4113 * the first expose drawing operation will be discarded, as it
4114 * has by then been overdrawn with valid data. This means we can
4115 * avoid doing the unnecessary repaint any outstanding expose events.
4118 cairo_region_get_extents (update_area, &clip_box);
4119 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
4120 expose_region = cairo_region_copy (update_area);
4123 /* Rendering is not double buffered by gdk, do outstanding
4124 * moves and queue antiexposure immediately. No need to do
4126 gdk_window_flush_outstanding_moves (window);
4127 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4128 save_region = impl_iface->queue_antiexpose (window, update_area);
4131 /* Render the invalid areas to the implicit paint, by sending exposes.
4132 * May flush if non-double buffered widget draw. */
4133 _gdk_windowing_window_process_updates_recurse (window, expose_region);
4137 /* Do moves right before exposes are rendered to the window */
4138 gdk_window_flush_outstanding_moves (window);
4140 /* By this time we know that any outstanding expose for this
4141 * area is invalid and we can avoid it, so queue an antiexpose.
4142 * However, it may be that due to an non-double buffered expose
4143 * we have already started drawing to the window, so it would
4144 * be to late to anti-expose now. Since this is merely an
4145 * optimization we just avoid doing it at all in that case.
4147 if (private->implicit_paint != NULL &&
4148 !private->implicit_paint->flushed)
4150 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4151 save_region = impl_iface->queue_antiexpose (window, update_area);
4154 gdk_window_end_implicit_paint (window);
4156 cairo_region_destroy (expose_region);
4159 cairo_region_destroy (update_area);
4162 if (private->outstanding_moves)
4164 /* Flush any outstanding moves, may happen if we moved a window but got
4165 no actual invalid area */
4166 gdk_window_flush_outstanding_moves (window);
4169 g_object_unref (window);
4173 flush_all_displays (void)
4175 GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4178 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
4179 gdk_display_flush (tmp_list->data);
4181 g_slist_free (displays);
4184 /* Currently it is not possible to override
4185 * gdk_window_process_all_updates in the same manner as
4186 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4187 * by implementing the GdkPaintable interface. If in the future a
4188 * backend would need this, the right solution would be to add a
4189 * method to GdkDisplay that can be optionally
4190 * NULL. gdk_window_process_all_updates can then walk the list of open
4191 * displays and call the mehod.
4195 * gdk_window_process_all_updates:
4197 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4198 * in the application.
4202 gdk_window_process_all_updates (void)
4204 GSList *old_update_windows = update_windows;
4205 GSList *tmp_list = update_windows;
4206 static gboolean in_process_all_updates = FALSE;
4207 static gboolean got_recursive_update = FALSE;
4209 if (in_process_all_updates)
4211 /* We can't do this now since that would recurse, so
4212 delay it until after the recursion is done. */
4213 got_recursive_update = TRUE;
4218 in_process_all_updates = TRUE;
4219 got_recursive_update = FALSE;
4222 g_source_remove (update_idle);
4224 update_windows = NULL;
4227 _gdk_windowing_before_process_all_updates ();
4229 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4233 GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
4235 if (!GDK_WINDOW_DESTROYED (tmp_list->data))
4237 if (private->update_freeze_count ||
4238 gdk_window_is_toplevel_frozen (tmp_list->data))
4239 gdk_window_add_update_window ((GdkWindow *) private);
4241 gdk_window_process_updates_internal (tmp_list->data);
4244 g_object_unref (tmp_list->data);
4245 tmp_list = tmp_list->next;
4248 g_slist_free (old_update_windows);
4250 flush_all_displays ();
4252 _gdk_windowing_after_process_all_updates ();
4254 in_process_all_updates = FALSE;
4256 /* If we ignored a recursive call, schedule a
4257 redraw now so that it eventually happens,
4258 otherwise we could miss an update if nothing
4259 else schedules an update. */
4260 if (got_recursive_update && !update_idle)
4262 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4263 gdk_window_update_idle,
4268 * gdk_window_process_updates:
4269 * @window: a #GdkWindow
4270 * @update_children: whether to also process updates for child windows
4272 * Sends one or more expose events to @window. The areas in each
4273 * expose event will cover the entire update area for the window (see
4274 * gdk_window_invalidate_region() for details). Normally GDK calls
4275 * gdk_window_process_all_updates() on your behalf, so there's no
4276 * need to call this function unless you want to force expose events
4277 * to be delivered immediately and synchronously (vs. the usual
4278 * case, where GDK delivers them in an idle handler). Occasionally
4279 * this is useful to produce nicer scrolling behavior, for example.
4283 gdk_window_process_updates (GdkWindow *window,
4284 gboolean update_children)
4286 GdkWindowObject *private = (GdkWindowObject *)window;
4287 GdkWindowObject *impl_window;
4289 g_return_if_fail (GDK_IS_WINDOW (window));
4291 if (GDK_WINDOW_DESTROYED (window))
4294 /* Make sure the window lives during the expose callouts */
4295 g_object_ref (window);
4297 impl_window = gdk_window_get_impl_window (private);
4298 if ((impl_window->update_area ||
4299 impl_window->outstanding_moves) &&
4300 !impl_window->update_freeze_count &&
4301 !gdk_window_is_toplevel_frozen (window) &&
4303 /* Don't recurse into process_updates_internal, we'll
4304 * do the update later when idle instead. */
4305 impl_window->implicit_paint == NULL)
4307 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4308 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4311 if (update_children)
4313 /* process updates in reverse stacking order so composition or
4314 * painting over achieves the desired effect for offscreen windows
4316 GList *node, *children;
4318 children = g_list_copy (private->children);
4319 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4321 for (node = g_list_last (children); node; node = node->prev)
4323 gdk_window_process_updates (node->data, TRUE);
4324 g_object_unref (node->data);
4327 g_list_free (children);
4330 g_object_unref (window);
4334 gdk_window_invalidate_rect_full (GdkWindow *window,
4335 const GdkRectangle *rect,
4336 gboolean invalidate_children,
4339 GdkRectangle window_rect;
4340 cairo_region_t *region;
4341 GdkWindowObject *private = (GdkWindowObject *)window;
4343 g_return_if_fail (GDK_IS_WINDOW (window));
4345 if (GDK_WINDOW_DESTROYED (window))
4348 if (private->input_only || !private->viewable)
4355 window_rect.width = private->width;
4356 window_rect.height = private->height;
4357 rect = &window_rect;
4360 region = cairo_region_create_rectangle (rect);
4361 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4362 cairo_region_destroy (region);
4366 * gdk_window_invalidate_rect:
4367 * @window: a #GdkWindow
4368 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4370 * @invalidate_children: whether to also invalidate child windows
4372 * A convenience wrapper around gdk_window_invalidate_region() which
4373 * invalidates a rectangular region. See
4374 * gdk_window_invalidate_region() for details.
4377 gdk_window_invalidate_rect (GdkWindow *window,
4378 const GdkRectangle *rect,
4379 gboolean invalidate_children)
4381 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4385 draw_ugly_color (GdkWindow *window,
4386 const cairo_region_t *region)
4390 cr = gdk_cairo_create (window);
4391 /* Draw ugly color all over the newly-invalid region */
4392 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4393 gdk_cairo_region (cr, region);
4400 impl_window_add_update_area (GdkWindowObject *impl_window,
4401 cairo_region_t *region)
4403 if (impl_window->update_area)
4404 cairo_region_union (impl_window->update_area, region);
4407 gdk_window_add_update_window ((GdkWindow *)impl_window);
4408 impl_window->update_area = cairo_region_copy (region);
4409 gdk_window_schedule_update ((GdkWindow *)impl_window);
4413 /* clear_bg controls if the region will be cleared to
4414 * the background pattern if the exposure mask is not
4415 * set for the window, whereas this might not otherwise be
4416 * done (unless necessary to emulate background settings).
4417 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4418 * need to clear the background, such as when exposing the area beneath a
4419 * hidden or moved window, but not when an app requests repaint or when the
4420 * windowing system exposes a newly visible area (because then the windowing
4421 * system has already cleared the area).
4424 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4425 const cairo_region_t *region,
4427 GdkWindowChildFunc child_func,
4430 GdkWindowObject *private = (GdkWindowObject *)window;
4431 GdkWindowObject *impl_window;
4432 cairo_region_t *visible_region;
4435 g_return_if_fail (GDK_IS_WINDOW (window));
4437 if (GDK_WINDOW_DESTROYED (window))
4440 if (private->input_only ||
4441 !private->viewable ||
4442 cairo_region_is_empty (region) ||
4443 private->window_type == GDK_WINDOW_ROOT)
4446 visible_region = gdk_drawable_get_visible_region (window);
4447 cairo_region_intersect (visible_region, region);
4449 tmp_list = private->children;
4452 GdkWindowObject *child = tmp_list->data;
4454 if (!child->input_only)
4456 cairo_region_t *child_region;
4457 GdkRectangle child_rect;
4459 child_rect.x = child->x;
4460 child_rect.y = child->y;
4461 child_rect.width = child->width;
4462 child_rect.height = child->height;
4463 child_region = cairo_region_create_rectangle (&child_rect);
4465 /* remove child area from the invalid area of the parent */
4466 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4467 !child->composited &&
4468 !gdk_window_is_offscreen (child))
4469 cairo_region_subtract (visible_region, child_region);
4471 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4473 cairo_region_t *tmp = cairo_region_copy (region);
4475 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4476 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4477 cairo_region_intersect (child_region, tmp);
4479 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4480 child_region, clear_bg, child_func, user_data);
4482 cairo_region_destroy (tmp);
4485 cairo_region_destroy (child_region);
4488 tmp_list = tmp_list->next;
4491 impl_window = gdk_window_get_impl_window (private);
4493 if (!cairo_region_is_empty (visible_region) ||
4494 /* Even if we're not exposing anything, make sure we process
4495 idles for windows with outstanding moves */
4496 (impl_window->outstanding_moves != NULL &&
4497 impl_window->update_area == NULL))
4500 draw_ugly_color (window, region);
4502 /* Convert to impl coords */
4503 cairo_region_translate (visible_region, private->abs_x, private->abs_y);
4505 /* Only invalidate area if app requested expose events or if
4506 we need to clear the area (by request or to emulate background
4507 clearing for non-native windows or native windows with no support
4508 for window backgrounds */
4509 if (private->event_mask & GDK_EXPOSURE_MASK ||
4510 clear_bg == CLEAR_BG_ALL ||
4511 clear_bg == CLEAR_BG_WINCLEARED)
4512 impl_window_add_update_area (impl_window, visible_region);
4515 cairo_region_destroy (visible_region);
4519 * gdk_window_invalidate_maybe_recurse:
4520 * @window: a #GdkWindow
4521 * @region: a #cairo_region_t
4522 * @child_func: function to use to decide if to recurse to a child,
4523 * %NULL means never recurse.
4524 * @user_data: data passed to @child_func
4526 * Adds @region to the update area for @window. The update area is the
4527 * region that needs to be redrawn, or "dirty region." The call
4528 * gdk_window_process_updates() sends one or more expose events to the
4529 * window, which together cover the entire update area. An
4530 * application would normally redraw the contents of @window in
4531 * response to those expose events.
4533 * GDK will call gdk_window_process_all_updates() on your behalf
4534 * whenever your program returns to the main loop and becomes idle, so
4535 * normally there's no need to do that manually, you just need to
4536 * invalidate regions that you know should be redrawn.
4538 * The @child_func parameter controls whether the region of
4539 * each child window that intersects @region will also be invalidated.
4540 * Only children for which @child_func returns TRUE will have the area
4544 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4545 const cairo_region_t *region,
4546 GdkWindowChildFunc child_func,
4549 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4550 child_func, user_data);
4554 true_predicate (GdkWindow *window,
4561 gdk_window_invalidate_region_full (GdkWindow *window,
4562 const cairo_region_t *region,
4563 gboolean invalidate_children,
4566 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4567 invalidate_children ?
4568 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4573 * gdk_window_invalidate_region:
4574 * @window: a #GdkWindow
4575 * @region: a #cairo_region_t
4576 * @invalidate_children: %TRUE to also invalidate child windows
4578 * Adds @region to the update area for @window. The update area is the
4579 * region that needs to be redrawn, or "dirty region." The call
4580 * gdk_window_process_updates() sends one or more expose events to the
4581 * window, which together cover the entire update area. An
4582 * application would normally redraw the contents of @window in
4583 * response to those expose events.
4585 * GDK will call gdk_window_process_all_updates() on your behalf
4586 * whenever your program returns to the main loop and becomes idle, so
4587 * normally there's no need to do that manually, you just need to
4588 * invalidate regions that you know should be redrawn.
4590 * The @invalidate_children parameter controls whether the region of
4591 * each child window that intersects @region will also be invalidated.
4592 * If %FALSE, then the update area for child windows will remain
4593 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4594 * fine grained control over which children are invalidated.
4597 gdk_window_invalidate_region (GdkWindow *window,
4598 const cairo_region_t *region,
4599 gboolean invalidate_children)
4601 gdk_window_invalidate_maybe_recurse (window, region,
4602 invalidate_children ?
4603 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4608 * _gdk_window_invalidate_for_expose:
4609 * @window: a #GdkWindow
4610 * @region: a #cairo_region_t
4612 * Adds @region to the update area for @window. The update area is the
4613 * region that needs to be redrawn, or "dirty region." The call
4614 * gdk_window_process_updates() sends one or more expose events to the
4615 * window, which together cover the entire update area. An
4616 * application would normally redraw the contents of @window in
4617 * response to those expose events.
4619 * GDK will call gdk_window_process_all_updates() on your behalf
4620 * whenever your program returns to the main loop and becomes idle, so
4621 * normally there's no need to do that manually, you just need to
4622 * invalidate regions that you know should be redrawn.
4624 * This version of invalidation is used when you recieve expose events
4625 * from the native window system. It exposes the native window, plus
4626 * any non-native child windows (but not native child windows, as those would
4627 * have gotten their own expose events).
4630 _gdk_window_invalidate_for_expose (GdkWindow *window,
4631 cairo_region_t *region)
4633 GdkWindowObject *private = (GdkWindowObject *) window;
4634 GdkWindowRegionMove *move;
4635 cairo_region_t *move_region;
4638 /* Any invalidations comming from the windowing system will
4639 be in areas that may be moved by outstanding moves,
4640 so we need to modify the expose region correspondingly,
4641 otherwise we would expose in the wrong place, as the
4642 outstanding moves will be copied before we draw the
4644 for (l = private->outstanding_moves; l != NULL; l = l->next)
4648 /* covert to move source region */
4649 move_region = cairo_region_copy (move->dest_region);
4650 cairo_region_translate (move_region, -move->dx, -move->dy);
4652 /* Move area of region that intersects with move source
4653 by dx, dy of the move*/
4654 cairo_region_intersect (move_region, region);
4655 cairo_region_subtract (region, move_region);
4656 cairo_region_translate (move_region, move->dx, move->dy);
4657 cairo_region_union (region, move_region);
4659 cairo_region_destroy (move_region);
4662 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4663 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4669 * gdk_window_get_update_area:
4670 * @window: a #GdkWindow
4672 * Transfers ownership of the update area from @window to the caller
4673 * of the function. That is, after calling this function, @window will
4674 * no longer have an invalid/dirty region; the update area is removed
4675 * from @window and handed to you. If a window has no update area,
4676 * gdk_window_get_update_area() returns %NULL. You are responsible for
4677 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4679 * Return value: the update area for @window
4682 gdk_window_get_update_area (GdkWindow *window)
4684 GdkWindowObject *private = (GdkWindowObject *)window;
4685 GdkWindowObject *impl_window;
4686 cairo_region_t *tmp_region;
4688 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4690 impl_window = gdk_window_get_impl_window (private);
4692 if (impl_window->update_area)
4694 tmp_region = cairo_region_copy (private->clip_region_with_children);
4695 /* Convert to impl coords */
4696 cairo_region_translate (tmp_region, private->abs_x, private->abs_y);
4697 cairo_region_intersect (tmp_region, impl_window->update_area);
4699 if (cairo_region_is_empty (tmp_region))
4701 cairo_region_destroy (tmp_region);
4706 cairo_region_subtract (impl_window->update_area, tmp_region);
4708 if (cairo_region_is_empty (impl_window->update_area) &&
4709 impl_window->outstanding_moves == NULL)
4711 cairo_region_destroy (impl_window->update_area);
4712 impl_window->update_area = NULL;
4714 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4717 /* Convert from impl coords */
4718 cairo_region_translate (tmp_region, -private->abs_x, -private->abs_y);
4728 * _gdk_window_clear_update_area:
4729 * @window: a #GdkWindow.
4731 * Internal function to clear the update area for a window. This
4732 * is called when the window is hidden or destroyed.
4735 _gdk_window_clear_update_area (GdkWindow *window)
4737 GdkWindowObject *private = (GdkWindowObject *)window;
4739 g_return_if_fail (GDK_IS_WINDOW (window));
4741 if (private->update_area)
4743 gdk_window_remove_update_window (window);
4745 cairo_region_destroy (private->update_area);
4746 private->update_area = NULL;
4751 * gdk_window_freeze_updates:
4752 * @window: a #GdkWindow
4754 * Temporarily freezes a window such that it won't receive expose
4755 * events. The window will begin receiving expose events again when
4756 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4757 * has been called more than once, gdk_window_thaw_updates() must be called
4758 * an equal number of times to begin processing exposes.
4761 gdk_window_freeze_updates (GdkWindow *window)
4763 GdkWindowObject *private = (GdkWindowObject *)window;
4764 GdkWindowObject *impl_window;
4766 g_return_if_fail (GDK_IS_WINDOW (window));
4768 impl_window = gdk_window_get_impl_window (private);
4769 impl_window->update_freeze_count++;
4773 * gdk_window_thaw_updates:
4774 * @window: a #GdkWindow
4776 * Thaws a window frozen with gdk_window_freeze_updates().
4779 gdk_window_thaw_updates (GdkWindow *window)
4781 GdkWindowObject *private = (GdkWindowObject *)window;
4782 GdkWindowObject *impl_window;
4784 g_return_if_fail (GDK_IS_WINDOW (window));
4786 impl_window = gdk_window_get_impl_window (private);
4788 g_return_if_fail (impl_window->update_freeze_count > 0);
4790 if (--impl_window->update_freeze_count == 0)
4791 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4795 * gdk_window_freeze_toplevel_updates_libgtk_only:
4796 * @window: a #GdkWindow
4798 * Temporarily freezes a window and all its descendants such that it won't
4799 * receive expose events. The window will begin receiving expose events
4800 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4801 * gdk_window_freeze_toplevel_updates_libgtk_only()
4802 * has been called more than once,
4803 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4804 * an equal number of times to begin processing exposes.
4806 * This function is not part of the GDK public API and is only
4810 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4812 GdkWindowObject *private = (GdkWindowObject *)window;
4814 g_return_if_fail (GDK_IS_WINDOW (window));
4815 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4817 private->update_and_descendants_freeze_count++;
4821 * gdk_window_thaw_toplevel_updates_libgtk_only:
4822 * @window: a #GdkWindow
4824 * Thaws a window frozen with
4825 * gdk_window_freeze_toplevel_updates_libgtk_only().
4827 * This function is not part of the GDK public API and is only
4831 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4833 GdkWindowObject *private = (GdkWindowObject *)window;
4835 g_return_if_fail (GDK_IS_WINDOW (window));
4836 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4837 g_return_if_fail (private->update_and_descendants_freeze_count > 0);
4839 private->update_and_descendants_freeze_count--;
4841 gdk_window_schedule_update (window);
4845 * gdk_window_set_debug_updates:
4846 * @setting: %TRUE to turn on update debugging
4848 * With update debugging enabled, calls to
4849 * gdk_window_invalidate_region() clear the invalidated region of the
4850 * screen to a noticeable color, and GDK pauses for a short time
4851 * before sending exposes to windows during
4852 * gdk_window_process_updates(). The net effect is that you can see
4853 * the invalid region for each window and watch redraws as they
4854 * occur. This allows you to diagnose inefficiencies in your application.
4856 * In essence, because the GDK rendering model prevents all flicker,
4857 * if you are redrawing the same region 400 times you may never
4858 * notice, aside from noticing a speed problem. Enabling update
4859 * debugging causes GTK to flicker slowly and noticeably, so you can
4860 * see exactly what's being redrawn when, in what order.
4862 * The --gtk-debug=updates command line option passed to GTK+ programs
4863 * enables this debug option at application startup time. That's
4864 * usually more useful than calling gdk_window_set_debug_updates()
4865 * yourself, though you might want to use this function to enable
4866 * updates sometime after application startup time.
4870 gdk_window_set_debug_updates (gboolean setting)
4872 debug_updates = setting;
4876 * gdk_window_constrain_size:
4877 * @geometry: a #GdkGeometry structure
4878 * @flags: a mask indicating what portions of @geometry are set
4879 * @width: desired width of window
4880 * @height: desired height of the window
4881 * @new_width: location to store resulting width
4882 * @new_height: location to store resulting height
4884 * Constrains a desired width and height according to a
4885 * set of geometry hints (such as minimum and maximum size).
4888 gdk_window_constrain_size (GdkGeometry *geometry,
4895 /* This routine is partially borrowed from fvwm.
4897 * Copyright 1993, Robert Nation
4898 * You may use this code for any purpose, as long as the original
4899 * copyright remains in the source code and all documentation
4901 * which in turn borrows parts of the algorithm from uwm
4904 gint min_height = 0;
4905 gint base_width = 0;
4906 gint base_height = 0;
4909 gint max_width = G_MAXINT;
4910 gint max_height = G_MAXINT;
4912 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4914 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4916 base_width = geometry->base_width;
4917 base_height = geometry->base_height;
4918 min_width = geometry->min_width;
4919 min_height = geometry->min_height;
4921 else if (flags & GDK_HINT_BASE_SIZE)
4923 base_width = geometry->base_width;
4924 base_height = geometry->base_height;
4925 min_width = geometry->base_width;
4926 min_height = geometry->base_height;
4928 else if (flags & GDK_HINT_MIN_SIZE)
4930 base_width = geometry->min_width;
4931 base_height = geometry->min_height;
4932 min_width = geometry->min_width;
4933 min_height = geometry->min_height;
4936 if (flags & GDK_HINT_MAX_SIZE)
4938 max_width = geometry->max_width ;
4939 max_height = geometry->max_height;
4942 if (flags & GDK_HINT_RESIZE_INC)
4944 xinc = MAX (xinc, geometry->width_inc);
4945 yinc = MAX (yinc, geometry->height_inc);
4948 /* clamp width and height to min and max values
4950 width = CLAMP (width, min_width, max_width);
4951 height = CLAMP (height, min_height, max_height);
4953 /* shrink to base + N * inc
4955 width = base_width + FLOOR (width - base_width, xinc);
4956 height = base_height + FLOOR (height - base_height, yinc);
4958 /* constrain aspect ratio, according to:
4961 * min_aspect <= -------- <= max_aspect
4965 if (flags & GDK_HINT_ASPECT &&
4966 geometry->min_aspect > 0 &&
4967 geometry->max_aspect > 0)
4971 if (geometry->min_aspect * height > width)
4973 delta = FLOOR (height - width / geometry->min_aspect, yinc);
4974 if (height - delta >= min_height)
4978 delta = FLOOR (height * geometry->min_aspect - width, xinc);
4979 if (width + delta <= max_width)
4984 if (geometry->max_aspect * height < width)
4986 delta = FLOOR (width - height * geometry->max_aspect, xinc);
4987 if (width - delta >= min_width)
4991 delta = FLOOR (width / geometry->max_aspect - height, yinc);
4992 if (height + delta <= max_height)
5001 *new_height = height;
5005 * gdk_window_get_pointer:
5006 * @window: a #GdkWindow
5007 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
5008 * return the X coordinate
5009 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
5010 * return the Y coordinate
5011 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
5014 * Obtains the current pointer position and modifier state.
5015 * The position is given in coordinates relative to the upper left
5016 * corner of @window.
5018 * Return value: (transfer none): the window containing the pointer (as with
5019 * gdk_window_at_pointer()), or %NULL if the window containing the
5020 * pointer isn't known to GDK
5022 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
5025 gdk_window_get_pointer (GdkWindow *window,
5028 GdkModifierType *mask)
5030 GdkDisplay *display;
5032 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5034 display = gdk_window_get_display (window);
5036 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
5040 * gdk_window_get_device_position:
5041 * @window: a #GdkWindow.
5042 * @device: #GdkDevice to query to.
5043 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
5044 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
5045 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
5047 * Obtains the current device position and modifier state.
5048 * The position is given in coordinates relative to the upper left
5049 * corner of @window.
5051 * Return value: (transfer none): The window underneath @device (as with
5052 * gdk_display_get_window_at_device_position()), or %NULL if the
5053 * window is not known to GDK.
5058 gdk_window_get_device_position (GdkWindow *window,
5062 GdkModifierType *mask)
5064 GdkDisplay *display;
5066 GdkModifierType tmp_mask;
5069 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5070 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
5072 display = gdk_window_get_display (window);
5073 child = display->device_hooks->window_get_device_position (display, device, window,
5074 &tmp_x, &tmp_y, &tmp_mask);
5083 _gdk_display_enable_motion_hints (display, device);
5089 * gdk_window_at_pointer:
5090 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
5091 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
5093 * Obtains the window underneath the mouse pointer, returning the
5094 * location of that window in @win_x, @win_y. Returns %NULL if the
5095 * window under the mouse pointer is not known to GDK (if the window
5096 * belongs to another application and a #GdkWindow hasn't been created
5097 * for it with gdk_window_foreign_new())
5099 * NOTE: For multihead-aware widgets or applications use
5100 * gdk_display_get_window_at_pointer() instead.
5102 * Return value: (transfer none): window under the mouse pointer
5104 * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
5107 gdk_window_at_pointer (gint *win_x,
5110 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
5114 * gdk_get_default_root_window:
5116 * Obtains the root window (parent all other windows are inside)
5117 * for the default display and screen.
5119 * Return value: the default root window
5122 gdk_get_default_root_window (void)
5124 return gdk_screen_get_root_window (gdk_screen_get_default ());
5128 * gdk_window_foreign_new:
5129 * @anid: a native window handle.
5131 * Wraps a native window for the default display in a #GdkWindow.
5132 * This may fail if the window has been destroyed.
5134 * For example in the X backend, a native window handle is an Xlib
5137 * Return value: the newly-created #GdkWindow wrapper for the
5138 * native window or %NULL if the window has been destroyed.
5141 gdk_window_foreign_new (GdkNativeWindow anid)
5143 return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
5147 get_all_native_children (GdkWindowObject *private,
5150 GdkWindowObject *child;
5153 for (l = private->children; l != NULL; l = l->next)
5157 if (gdk_window_has_impl (child))
5158 *native = g_list_prepend (*native, child);
5160 get_all_native_children (child, native);
5166 gdk_window_raise_internal (GdkWindow *window)
5168 GdkWindowObject *private = (GdkWindowObject *)window;
5169 GdkWindowObject *parent = private->parent;
5170 GdkWindowObject *above;
5171 GList *native_children;
5173 GdkWindowImplIface *impl_iface;
5177 parent->children = g_list_remove (parent->children, window);
5178 parent->children = g_list_prepend (parent->children, window);
5181 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5182 /* Just do native raise for toplevels */
5183 if (gdk_window_is_toplevel (private) ||
5184 /* The restack_under codepath should work correctly even if the parent
5185 is native, but it relies on the order of ->children to be correct,
5186 and some apps like SWT reorder the x windows without gdks knowledge,
5187 so we use raise directly in order to make these behave as before
5188 when using native windows */
5189 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5191 impl_iface->raise (window);
5193 else if (gdk_window_has_impl (private))
5195 above = find_native_sibling_above (parent, private);
5198 listhead.data = window;
5199 listhead.next = NULL;
5200 listhead.prev = NULL;
5201 impl_iface->restack_under ((GdkWindow *)above,
5205 impl_iface->raise (window);
5209 native_children = NULL;
5210 get_all_native_children (private, &native_children);
5211 if (native_children != NULL)
5213 above = find_native_sibling_above (parent, private);
5216 impl_iface->restack_under ((GdkWindow *)above,
5220 /* Right order, since native_children is bottom-topmost first */
5221 for (l = native_children; l != NULL; l = l->next)
5222 impl_iface->raise (l->data);
5225 g_list_free (native_children);
5231 /* Returns TRUE If the native window was mapped or unmapped */
5233 set_viewable (GdkWindowObject *w,
5236 GdkWindowObject *child;
5237 GdkWindowImplIface *impl_iface;
5240 if (w->viewable == val)
5246 recompute_visible_regions (w, FALSE, FALSE);
5248 for (l = w->children; l != NULL; l = l->next)
5252 if (GDK_WINDOW_IS_MAPPED (child) &&
5253 child->window_type != GDK_WINDOW_FOREIGN)
5254 set_viewable (child, val);
5257 if (!_gdk_native_windows &&
5258 gdk_window_has_impl (w) &&
5259 w->window_type != GDK_WINDOW_FOREIGN &&
5260 !gdk_window_is_toplevel (w))
5262 /* For most native windows we show/hide them not when they are
5263 * mapped/unmapped, because that may not produce the correct results.
5264 * For instance, if a native window have a non-native parent which is
5265 * hidden, but its native parent is viewable then showing the window
5266 * would make it viewable to X but its not viewable wrt the non-native
5267 * hierarchy. In order to handle this we track the gdk side viewability
5268 * and only map really viewable windows.
5270 * There are two exceptions though:
5272 * For foreign windows we don't want ever change the mapped state
5273 * except when explicitly done via gdk_window_show/hide, as this may
5274 * cause problems for client owning the foreign window when its window
5275 * is suddenly mapped or unmapped.
5277 * For toplevel windows embedded in a foreign window (e.g. a plug)
5278 * we sometimes synthesize a map of a window, but the native
5279 * window is really shown by the embedder, so we don't want to
5280 * do the show ourselves. We can't really tell this case from the normal
5281 * toplevel show as such toplevels are seen by gdk as parents of the
5282 * root window, so we make an exception for all toplevels.
5284 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
5285 * like this, so we just always show/hide directly.
5288 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
5290 impl_iface->show ((GdkWindow *)w, FALSE);
5292 impl_iface->hide ((GdkWindow *)w);
5300 /* Returns TRUE If the native window was mapped or unmapped */
5302 _gdk_window_update_viewable (GdkWindow *window)
5304 GdkWindowObject *priv = (GdkWindowObject *)window;
5307 if (priv->window_type == GDK_WINDOW_FOREIGN ||
5308 priv->window_type == GDK_WINDOW_ROOT)
5310 else if (gdk_window_is_toplevel (priv) ||
5311 priv->parent->viewable)
5312 viewable = GDK_WINDOW_IS_MAPPED (priv);
5316 return set_viewable (priv, viewable);
5320 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5322 GdkWindowObject *private;
5323 GdkWindowImplIface *impl_iface;
5324 gboolean was_mapped, was_viewable;
5327 g_return_if_fail (GDK_IS_WINDOW (window));
5329 private = (GdkWindowObject *) window;
5330 if (private->destroyed)
5333 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5334 was_viewable = private->viewable;
5337 /* Keep children in (reverse) stacking order */
5338 gdk_window_raise_internal (window);
5340 if (gdk_window_has_impl (private))
5343 gdk_synthesize_window_state (window,
5344 GDK_WINDOW_STATE_WITHDRAWN,
5352 did_show = _gdk_window_update_viewable (window);
5354 /* If it was already viewable the backend show op won't be called, call it
5355 again to ensure things happen right if the mapped tracking was not right
5356 for e.g. a foreign window.
5357 Dunno if this is strictly needed but its what happened pre-csw.
5358 Also show if not done by gdk_window_update_viewable. */
5359 if (gdk_window_has_impl (private) && (was_viewable || !did_show))
5361 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5362 impl_iface->show ((GdkWindow *)private,
5363 !did_show ? was_mapped : TRUE);
5366 if (!was_mapped && !gdk_window_has_impl (private))
5368 if (private->event_mask & GDK_STRUCTURE_MASK)
5369 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5371 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5372 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5375 if (!was_mapped || raise)
5377 recompute_visible_regions (private, TRUE, FALSE);
5379 /* If any decendants became visible we need to send visibility notify */
5380 gdk_window_update_visibility_recursively (private, NULL);
5382 if (gdk_window_is_viewable (window))
5384 _gdk_synthesize_crossing_events_for_geometry_change (window);
5385 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5391 * gdk_window_show_unraised:
5392 * @window: a #GdkWindow
5394 * Shows a #GdkWindow onscreen, but does not modify its stacking
5395 * order. In contrast, gdk_window_show() will raise the window
5396 * to the top of the window stack.
5398 * On the X11 platform, in Xlib terms, this function calls
5399 * XMapWindow() (it also updates some internal GDK state, which means
5400 * that you can't really use XMapWindow() directly on a GDK window).
5403 gdk_window_show_unraised (GdkWindow *window)
5405 gdk_window_show_internal (window, FALSE);
5410 * @window: a #GdkWindow
5412 * Raises @window to the top of the Z-order (stacking order), so that
5413 * other windows with the same parent window appear below @window.
5414 * This is true whether or not the windows are visible.
5416 * If @window is a toplevel, the window manager may choose to deny the
5417 * request to move the window in the Z-order, gdk_window_raise() only
5418 * requests the restack, does not guarantee it.
5421 gdk_window_raise (GdkWindow *window)
5423 GdkWindowObject *private;
5424 cairo_region_t *old_region, *new_region;
5426 g_return_if_fail (GDK_IS_WINDOW (window));
5428 private = (GdkWindowObject *) window;
5429 if (private->destroyed)
5432 gdk_window_flush_if_exposing (window);
5435 if (gdk_window_is_viewable (window) &&
5436 !private->input_only)
5437 old_region = cairo_region_copy (private->clip_region);
5439 /* Keep children in (reverse) stacking order */
5440 gdk_window_raise_internal (window);
5442 recompute_visible_regions (private, TRUE, FALSE);
5446 new_region = cairo_region_copy (private->clip_region);
5448 cairo_region_subtract (new_region, old_region);
5449 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5451 cairo_region_destroy (old_region);
5452 cairo_region_destroy (new_region);
5457 gdk_window_lower_internal (GdkWindow *window)
5459 GdkWindowObject *private = (GdkWindowObject *)window;
5460 GdkWindowObject *parent = private->parent;
5461 GdkWindowImplIface *impl_iface;
5462 GdkWindowObject *above;
5463 GList *native_children;
5468 parent->children = g_list_remove (parent->children, window);
5469 parent->children = g_list_append (parent->children, window);
5472 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5473 /* Just do native lower for toplevels */
5474 if (gdk_window_is_toplevel (private) ||
5475 /* The restack_under codepath should work correctly even if the parent
5476 is native, but it relies on the order of ->children to be correct,
5477 and some apps like SWT reorder the x windows without gdks knowledge,
5478 so we use lower directly in order to make these behave as before
5479 when using native windows */
5480 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5482 impl_iface->lower (window);
5484 else if (gdk_window_has_impl (private))
5486 above = find_native_sibling_above (parent, private);
5489 listhead.data = window;
5490 listhead.next = NULL;
5491 listhead.prev = NULL;
5492 impl_iface->restack_under ((GdkWindow *)above, &listhead);
5495 impl_iface->raise (window);
5499 native_children = NULL;
5500 get_all_native_children (private, &native_children);
5501 if (native_children != NULL)
5503 above = find_native_sibling_above (parent, private);
5506 impl_iface->restack_under ((GdkWindow *)above,
5510 /* Right order, since native_children is bottom-topmost first */
5511 for (l = native_children; l != NULL; l = l->next)
5512 impl_iface->raise (l->data);
5515 g_list_free (native_children);
5522 gdk_window_invalidate_in_parent (GdkWindowObject *private)
5524 GdkRectangle r, child;
5526 if (gdk_window_is_toplevel (private))
5529 /* get the visible rectangle of the parent */
5531 r.width = private->parent->width;
5532 r.height = private->parent->height;
5534 child.x = private->x;
5535 child.y = private->y;
5536 child.width = private->width;
5537 child.height = private->height;
5538 gdk_rectangle_intersect (&r, &child, &r);
5540 gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
5546 * @window: a #GdkWindow
5548 * Lowers @window to the bottom of the Z-order (stacking order), so that
5549 * other windows with the same parent window appear above @window.
5550 * This is true whether or not the other windows are visible.
5552 * If @window is a toplevel, the window manager may choose to deny the
5553 * request to move the window in the Z-order, gdk_window_lower() only
5554 * requests the restack, does not guarantee it.
5556 * Note that gdk_window_show() raises the window again, so don't call this
5557 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5560 gdk_window_lower (GdkWindow *window)
5562 GdkWindowObject *private;
5564 g_return_if_fail (GDK_IS_WINDOW (window));
5566 private = (GdkWindowObject *) window;
5567 if (private->destroyed)
5570 gdk_window_flush_if_exposing (window);
5572 /* Keep children in (reverse) stacking order */
5573 gdk_window_lower_internal (window);
5575 recompute_visible_regions (private, TRUE, FALSE);
5577 _gdk_synthesize_crossing_events_for_geometry_change (window);
5578 gdk_window_invalidate_in_parent (private);
5582 * gdk_window_restack:
5583 * @window: a #GdkWindow
5584 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5587 * Changes the position of @window in the Z-order (stacking order), so that
5588 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5591 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5592 * lowers the window.
5594 * If @window is a toplevel, the window manager may choose to deny the
5595 * request to move the window in the Z-order, gdk_window_restack() only
5596 * requests the restack, does not guarantee it.
5601 gdk_window_restack (GdkWindow *window,
5605 GdkWindowObject *private;
5606 GdkWindowImplIface *impl_iface;
5607 GdkWindowObject *parent;
5608 GdkWindowObject *above_native;
5609 GList *sibling_link;
5610 GList *native_children;
5613 g_return_if_fail (GDK_IS_WINDOW (window));
5614 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5616 private = (GdkWindowObject *) window;
5617 if (private->destroyed)
5620 if (sibling == NULL)
5623 gdk_window_raise (window);
5625 gdk_window_lower (window);
5629 gdk_window_flush_if_exposing (window);
5631 if (gdk_window_is_toplevel (private))
5633 g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
5634 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5635 impl_iface->restack_toplevel (window, sibling, above);
5639 parent = private->parent;
5642 sibling_link = g_list_find (parent->children, sibling);
5643 g_return_if_fail (sibling_link != NULL);
5644 if (sibling_link == NULL)
5647 parent->children = g_list_remove (parent->children, window);
5649 parent->children = g_list_insert_before (parent->children,
5653 parent->children = g_list_insert_before (parent->children,
5657 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5658 if (gdk_window_has_impl (private))
5660 above_native = find_native_sibling_above (parent, private);
5663 listhead.data = window;
5664 listhead.next = NULL;
5665 listhead.prev = NULL;
5666 impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
5669 impl_iface->raise (window);
5673 native_children = NULL;
5674 get_all_native_children (private, &native_children);
5675 if (native_children != NULL)
5677 above_native = find_native_sibling_above (parent, private);
5679 impl_iface->restack_under ((GdkWindow *)above_native,
5683 /* Right order, since native_children is bottom-topmost first */
5684 for (l = native_children; l != NULL; l = l->next)
5685 impl_iface->raise (l->data);
5688 g_list_free (native_children);
5693 recompute_visible_regions (private, TRUE, FALSE);
5695 _gdk_synthesize_crossing_events_for_geometry_change (window);
5696 gdk_window_invalidate_in_parent (private);
5702 * @window: a #GdkWindow
5704 * Like gdk_window_show_unraised(), but also raises the window to the
5705 * top of the window stack (moves the window to the front of the
5708 * This function maps a window so it's visible onscreen. Its opposite
5709 * is gdk_window_hide().
5711 * When implementing a #GtkWidget, you should call this function on the widget's
5712 * #GdkWindow as part of the "map" method.
5715 gdk_window_show (GdkWindow *window)
5717 gdk_window_show_internal (window, TRUE);
5722 * @window: a #GdkWindow
5724 * For toplevel windows, withdraws them, so they will no longer be
5725 * known to the window manager; for all windows, unmaps them, so
5726 * they won't be displayed. Normally done automatically as
5727 * part of gtk_widget_hide().
5730 gdk_window_hide (GdkWindow *window)
5732 GdkWindowObject *private;
5733 GdkWindowImplIface *impl_iface;
5734 gboolean was_mapped, did_hide;
5736 g_return_if_fail (GDK_IS_WINDOW (window));
5738 private = (GdkWindowObject *) window;
5739 if (private->destroyed)
5742 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5744 if (gdk_window_has_impl (private))
5747 if (GDK_WINDOW_IS_MAPPED (window))
5748 gdk_synthesize_window_state (window,
5750 GDK_WINDOW_STATE_WITHDRAWN);
5752 else if (was_mapped)
5754 GdkDisplay *display;
5755 GdkDeviceManager *device_manager;
5758 /* May need to break grabs on children */
5759 display = gdk_window_get_display (window);
5760 device_manager = gdk_display_get_device_manager (display);
5762 /* Get all devices */
5763 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5764 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5765 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5767 for (d = devices; d; d = d->next)
5769 GdkDevice *device = d->data;
5771 if (_gdk_display_end_device_grab (display, device,
5772 _gdk_windowing_window_get_next_serial (display),
5775 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5778 private->state = GDK_WINDOW_STATE_WITHDRAWN;
5779 g_list_free (devices);
5782 did_hide = _gdk_window_update_viewable (window);
5784 /* Hide foreign window as those are not handled by update_viewable. */
5785 if (gdk_window_has_impl (private) && (!did_hide))
5787 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5788 impl_iface->hide (window);
5791 recompute_visible_regions (private, TRUE, FALSE);
5793 /* all decendants became non-visible, we need to send visibility notify */
5794 gdk_window_update_visibility_recursively (private, NULL);
5796 if (was_mapped && !gdk_window_has_impl (private))
5798 if (private->event_mask & GDK_STRUCTURE_MASK)
5799 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5801 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5802 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5804 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5807 /* Invalidate the rect */
5809 gdk_window_invalidate_in_parent (private);
5813 * gdk_window_withdraw:
5814 * @window: a toplevel #GdkWindow
5816 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5817 * This function is not really useful as gdk_window_hide() automatically
5818 * withdraws toplevel windows before hiding them.
5821 gdk_window_withdraw (GdkWindow *window)
5823 GdkWindowObject *private;
5824 GdkWindowImplIface *impl_iface;
5825 gboolean was_mapped;
5827 g_return_if_fail (GDK_IS_WINDOW (window));
5829 private = (GdkWindowObject *) window;
5830 if (private->destroyed)
5833 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5835 if (gdk_window_has_impl (private))
5837 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5838 impl_iface->withdraw (window);
5842 if (private->event_mask & GDK_STRUCTURE_MASK)
5843 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5845 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5846 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5848 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5851 recompute_visible_regions (private, TRUE, FALSE);
5856 * gdk_window_set_events:
5857 * @window: a #GdkWindow
5858 * @event_mask: event mask for @window
5860 * The event mask for a window determines which events will be reported
5861 * for that window from all master input devices. For example, an event mask
5862 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5863 * press events. The event mask is the bitwise OR of values from the
5864 * #GdkEventMask enumeration.
5867 gdk_window_set_events (GdkWindow *window,
5868 GdkEventMask event_mask)
5870 GdkWindowObject *private;
5871 GdkWindowImplIface *impl_iface;
5872 GdkDisplay *display;
5874 g_return_if_fail (GDK_IS_WINDOW (window));
5876 private = (GdkWindowObject *) window;
5877 if (private->destroyed)
5880 /* If motion hint is disabled, enable motion events again */
5881 display = gdk_window_get_display (window);
5882 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5883 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5885 GList *devices = private->devices_inside;
5889 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5890 devices = devices->next;
5894 private->event_mask = event_mask;
5896 if (gdk_window_has_impl (private))
5898 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5899 impl_iface->set_events (window,
5900 get_native_event_mask (private));
5906 * gdk_window_get_events:
5907 * @window: a #GdkWindow
5909 * Gets the event mask for @window for all master input devices. See
5910 * gdk_window_set_events().
5912 * Return value: event mask for @window
5915 gdk_window_get_events (GdkWindow *window)
5917 GdkWindowObject *private;
5919 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5921 private = (GdkWindowObject *) window;
5922 if (private->destroyed)
5925 return private->event_mask;
5929 * gdk_window_set_device_events:
5930 * @window: a #GdkWindow
5931 * @device: #GdkDevice to enable events for.
5932 * @event_mask: event mask for @window
5934 * Sets the event mask for a given device (Normally a floating device, not
5935 * attached to any visible pointer) to @window. For example, an event mask
5936 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5937 * press events. The event mask is the bitwise OR of values from the
5938 * #GdkEventMask enumeration.
5943 gdk_window_set_device_events (GdkWindow *window,
5945 GdkEventMask event_mask)
5947 GdkEventMask device_mask;
5948 GdkWindowObject *private;
5949 GdkDisplay *display;
5952 g_return_if_fail (GDK_IS_WINDOW (window));
5953 g_return_if_fail (GDK_IS_DEVICE (device));
5955 if (GDK_WINDOW_DESTROYED (window))
5958 private = (GdkWindowObject *) window;
5960 /* If motion hint is disabled, enable motion events again */
5961 display = gdk_window_get_display (window);
5962 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5963 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5964 _gdk_display_enable_motion_hints (display, device);
5966 if (G_UNLIKELY (!private->device_events))
5967 private->device_events = g_hash_table_new (NULL, NULL);
5969 if (event_mask == 0)
5971 /* FIXME: unsetting events on a master device
5972 * would restore private->event_mask
5974 g_hash_table_remove (private->device_events, device);
5977 g_hash_table_insert (private->device_events, device,
5978 GINT_TO_POINTER (event_mask));
5980 if (_gdk_native_windows)
5983 native = gdk_window_get_toplevel (window);
5985 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
5987 native = gdk_offscreen_window_get_embedder (native);
5989 if (native == NULL ||
5990 (!_gdk_window_has_impl (native) &&
5991 !gdk_window_is_viewable (native)))
5994 native = gdk_window_get_toplevel (native);
5997 device_mask = get_native_device_event_mask (private, device);
5998 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
6002 * gdk_window_get_device_events:
6003 * @window: a #GdkWindow.
6004 * @device: a #GdkDevice.
6006 * Returns the event mask for @window corresponding to an specific device.
6008 * Returns: device event mask for @window
6013 gdk_window_get_device_events (GdkWindow *window,
6016 GdkWindowObject *private;
6019 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6020 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
6022 if (GDK_WINDOW_DESTROYED (window))
6025 private = (GdkWindowObject *) window;
6027 if (!private->device_events)
6030 mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
6032 /* FIXME: device could be controlled by private->event_mask */
6038 gdk_window_move_resize_toplevel (GdkWindow *window,
6045 GdkWindowObject *private;
6046 cairo_region_t *old_region, *new_region;
6047 GdkWindowImplIface *impl_iface;
6049 int old_x, old_y, old_abs_x, old_abs_y;
6053 private = (GdkWindowObject *) window;
6061 is_resize = (width != -1) || (height != -1);
6063 if (gdk_window_is_viewable (window) &&
6064 !private->input_only)
6067 old_region = cairo_region_copy (private->clip_region);
6070 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6071 impl_iface->move_resize (window, with_move, x, y, width, height);
6073 dx = private->x - old_x;
6074 dy = private->y - old_y;
6076 old_abs_x = private->abs_x;
6077 old_abs_y = private->abs_y;
6079 /* Avoid recomputing for pure toplevel moves, for performance reasons */
6081 recompute_visible_regions (private, TRUE, FALSE);
6085 new_region = cairo_region_copy (private->clip_region);
6087 /* This is the newly exposed area (due to any resize),
6088 * X will expose it, but lets do that without the
6091 cairo_region_subtract (new_region, old_region);
6092 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
6094 cairo_region_destroy (old_region);
6095 cairo_region_destroy (new_region);
6098 _gdk_synthesize_crossing_events_for_geometry_change (window);
6103 move_native_children (GdkWindowObject *private)
6106 GdkWindowObject *child;
6107 GdkWindowImplIface *impl_iface;
6109 for (l = private->children; l; l = l->next)
6113 if (child->impl != private->impl)
6115 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
6116 impl_iface->move_resize ((GdkWindow *)child, TRUE,
6118 child->width, child->height);
6121 move_native_children (child);
6126 collect_native_child_region_helper (GdkWindowObject *window,
6128 cairo_region_t **region,
6132 GdkWindowObject *child;
6133 cairo_region_t *tmp;
6136 for (l = window->children; l != NULL; l = l->next)
6140 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
6143 if (child->impl != impl)
6145 tmp = cairo_region_copy (child->clip_region);
6146 cairo_region_translate (tmp,
6147 x_offset + child->x,
6148 y_offset + child->y);
6149 if (*region == NULL)
6153 cairo_region_union (*region, tmp);
6154 cairo_region_destroy (tmp);
6158 collect_native_child_region_helper (child, impl, region,
6159 x_offset + child->x,
6160 y_offset + child->y);
6166 static cairo_region_t *
6167 collect_native_child_region (GdkWindowObject *window,
6168 gboolean include_this)
6170 cairo_region_t *region;
6172 if (include_this && gdk_window_has_impl (window) && window->viewable)
6173 return cairo_region_copy (window->clip_region);
6177 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6184 gdk_window_move_resize_internal (GdkWindow *window,
6191 GdkWindowObject *private;
6192 cairo_region_t *old_region, *new_region, *copy_area;
6193 cairo_region_t *old_native_child_region, *new_native_child_region;
6194 GdkWindowObject *impl_window;
6195 GdkWindowImplIface *impl_iface;
6197 int old_x, old_y, old_abs_x, old_abs_y;
6200 g_return_if_fail (GDK_IS_WINDOW (window));
6202 private = (GdkWindowObject *) window;
6203 if (private->destroyed)
6206 if (gdk_window_is_toplevel (private))
6208 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6212 /* Bail early if no change */
6213 if (private->width == width &&
6214 private->height == height &&
6220 gdk_window_flush_if_exposing (window);
6222 /* Handle child windows */
6227 impl_window = gdk_window_get_impl_window (private);
6232 old_native_child_region = NULL;
6233 if (gdk_window_is_viewable (window) &&
6234 !private->input_only)
6238 old_region = cairo_region_copy (private->clip_region);
6239 /* Adjust region to parent window coords */
6240 cairo_region_translate (old_region, private->x, private->y);
6242 old_native_child_region = collect_native_child_region (private, TRUE);
6243 if (old_native_child_region)
6245 /* Adjust region to parent window coords */
6246 cairo_region_translate (old_native_child_region, private->x, private->y);
6248 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6249 * source or destination for a delayed GdkWindowRegionMove. So, we need
6250 * to flush those here for the parent window and all overlapped subwindows
6251 * of it. And we need to do this before setting the new clips as those will be
6254 gdk_window_flush_recursive (private->parent);
6258 /* Set the new position and size */
6264 if (!(width < 0 && height < 0))
6268 private->width = width;
6271 private->height = height;
6274 dx = private->x - old_x;
6275 dy = private->y - old_y;
6277 old_abs_x = private->abs_x;
6278 old_abs_y = private->abs_y;
6280 recompute_visible_regions (private, TRUE, FALSE);
6282 new_native_child_region = NULL;
6283 if (old_native_child_region)
6285 new_native_child_region = collect_native_child_region (private, TRUE);
6286 /* Adjust region to parent window coords */
6287 cairo_region_translate (new_native_child_region, private->x, private->y);
6290 if (gdk_window_has_impl (private))
6292 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6294 /* Do the actual move after recomputing things, as this will have set the shape to
6295 the now correct one, thus avoiding copying regions that should not be copied. */
6296 impl_iface->move_resize (window, TRUE,
6297 private->x, private->y,
6298 private->width, private->height);
6300 else if (old_abs_x != private->abs_x ||
6301 old_abs_y != private->abs_y)
6302 move_native_children (private);
6306 new_region = cairo_region_copy (private->clip_region);
6307 /* Adjust region to parent window coords */
6308 cairo_region_translate (new_region, private->x, private->y);
6311 * Part of the data at the new location can be copied from the
6312 * old location, this area is the intersection of the old region
6313 * moved as the copy will move it and then intersected with
6317 * Everything in the old and new regions that is not copied must be
6318 * invalidated (including children) as this is newly exposed
6320 copy_area = cairo_region_copy (new_region);
6322 cairo_region_union (new_region, old_region);
6324 if (old_native_child_region)
6326 /* Don't copy from inside native children, as this is copied by
6327 * the native window move.
6329 cairo_region_subtract (old_region, old_native_child_region);
6331 cairo_region_translate (old_region, dx, dy);
6333 cairo_region_intersect (copy_area, old_region);
6335 if (new_native_child_region)
6337 /* Don't copy any bits that would cause a read from the moved
6338 native windows, as we can't read that data */
6339 cairo_region_translate (new_native_child_region, dx, dy);
6340 cairo_region_subtract (copy_area, new_native_child_region);
6341 cairo_region_translate (new_native_child_region, -dx, -dy);
6344 cairo_region_subtract (new_region, copy_area);
6346 /* Convert old region to impl coords */
6347 cairo_region_translate (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
6349 /* convert from parent coords to impl */
6350 cairo_region_translate (copy_area, private->abs_x - private->x, private->abs_y - private->y);
6352 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6354 /* Invalidate affected part in the parent window
6355 * (no higher window should be affected)
6356 * We also invalidate any children in that area, which could include
6357 * this window if it still overlaps that area.
6359 if (old_native_child_region)
6361 /* No need to expose the region that the native window move copies */
6362 cairo_region_translate (old_native_child_region, dx, dy);
6363 cairo_region_intersect (old_native_child_region, new_native_child_region);
6364 cairo_region_subtract (new_region, old_native_child_region);
6366 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
6368 cairo_region_destroy (old_region);
6369 cairo_region_destroy (new_region);
6372 if (old_native_child_region)
6374 cairo_region_destroy (old_native_child_region);
6375 cairo_region_destroy (new_native_child_region);
6378 _gdk_synthesize_crossing_events_for_geometry_change (window);
6385 * @window: a #GdkWindow
6386 * @x: X coordinate relative to window's parent
6387 * @y: Y coordinate relative to window's parent
6389 * Repositions a window relative to its parent window.
6390 * For toplevel windows, window managers may ignore or modify the move;
6391 * you should probably use gtk_window_move() on a #GtkWindow widget
6392 * anyway, instead of using GDK functions. For child windows,
6393 * the move will reliably succeed.
6395 * If you're also planning to resize the window, use gdk_window_move_resize()
6396 * to both move and resize simultaneously, for a nicer visual effect.
6399 gdk_window_move (GdkWindow *window,
6403 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6407 * gdk_window_resize:
6408 * @window: a #GdkWindow
6409 * @width: new width of the window
6410 * @height: new height of the window
6412 * Resizes @window; for toplevel windows, asks the window manager to resize
6413 * the window. The window manager may not allow the resize. When using GTK+,
6414 * use gtk_window_resize() instead of this low-level GDK function.
6416 * Windows may not be resized below 1x1.
6418 * If you're also planning to move the window, use gdk_window_move_resize()
6419 * to both move and resize simultaneously, for a nicer visual effect.
6422 gdk_window_resize (GdkWindow *window,
6426 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6431 * gdk_window_move_resize:
6432 * @window: a #GdkWindow
6433 * @x: new X position relative to window's parent
6434 * @y: new Y position relative to window's parent
6436 * @height: new height
6438 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6439 * except that both operations are performed at once, avoiding strange
6440 * visual effects. (i.e. the user may be able to see the window first
6441 * move, then resize, if you don't use gdk_window_move_resize().)
6444 gdk_window_move_resize (GdkWindow *window,
6450 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6455 * gdk_window_scroll:
6456 * @window: a #GdkWindow
6457 * @dx: Amount to scroll in the X direction
6458 * @dy: Amount to scroll in the Y direction
6460 * Scroll the contents of @window, both pixels and children, by the
6461 * given amount. @window itself does not move. Portions of the window
6462 * that the scroll operation brings in from offscreen areas are
6463 * invalidated. The invalidated region may be bigger than what would
6464 * strictly be necessary.
6466 * For X11, a minimum area will be invalidated if the window has no
6467 * subwindows, or if the edges of the window's parent do not extend
6468 * beyond the edges of the window. In other cases, a multi-step process
6469 * is used to scroll the window which may produce temporary visual
6470 * artifacts and unnecessary invalidations.
6473 gdk_window_scroll (GdkWindow *window,
6477 GdkWindowObject *private = (GdkWindowObject *) window;
6478 GdkWindowObject *impl_window;
6479 cairo_region_t *copy_area, *noncopy_area;
6480 cairo_region_t *old_native_child_region, *new_native_child_region;
6483 g_return_if_fail (GDK_IS_WINDOW (window));
6485 if (dx == 0 && dy == 0)
6488 if (private->destroyed)
6491 gdk_window_flush_if_exposing (window);
6493 old_native_child_region = collect_native_child_region (private, FALSE);
6494 if (old_native_child_region)
6496 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6497 * source or destination for a delayed GdkWindowRegionMove. So, we need
6498 * to flush those here for the window and all overlapped subwindows
6499 * of it. And we need to do this before setting the new clips as those will be
6502 gdk_window_flush_recursive (private);
6506 /* First move all child windows, without causing invalidation */
6508 tmp_list = private->children;
6511 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6512 GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
6514 /* Just update the positions, the bits will move with the copy */
6518 tmp_list = tmp_list->next;
6521 recompute_visible_regions (private, FALSE, TRUE);
6523 new_native_child_region = NULL;
6524 if (old_native_child_region)
6525 new_native_child_region = collect_native_child_region (private, FALSE);
6527 move_native_children (private);
6529 /* Then copy the actual bits of the window w/ child windows */
6531 impl_window = gdk_window_get_impl_window (private);
6533 /* Calculate the area that can be gotten by copying the old area */
6534 copy_area = cairo_region_copy (private->clip_region);
6535 if (old_native_child_region)
6537 /* Don't copy from inside native children, as this is copied by
6538 * the native window move.
6540 cairo_region_subtract (copy_area, old_native_child_region);
6542 /* Don't copy any bits that would cause a read from the moved
6543 native windows, as we can't read that data */
6544 cairo_region_subtract (copy_area, new_native_child_region);
6546 cairo_region_translate (copy_area, dx, dy);
6547 cairo_region_intersect (copy_area, private->clip_region);
6549 /* And the rest need to be invalidated */
6550 noncopy_area = cairo_region_copy (private->clip_region);
6551 cairo_region_subtract (noncopy_area, copy_area);
6553 /* convert from window coords to impl */
6554 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6556 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6558 /* Invalidate not copied regions */
6559 if (old_native_child_region)
6561 /* No need to expose the region that the native window move copies */
6562 cairo_region_translate (old_native_child_region, dx, dy);
6563 cairo_region_intersect (old_native_child_region, new_native_child_region);
6564 cairo_region_subtract (noncopy_area, old_native_child_region);
6566 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6568 cairo_region_destroy (noncopy_area);
6570 if (old_native_child_region)
6572 cairo_region_destroy (old_native_child_region);
6573 cairo_region_destroy (new_native_child_region);
6576 _gdk_synthesize_crossing_events_for_geometry_change (window);
6580 * gdk_window_move_region:
6581 * @window: a #GdkWindow
6582 * @region: The #cairo_region_t to move
6583 * @dx: Amount to move in the X direction
6584 * @dy: Amount to move in the Y direction
6586 * Move the part of @window indicated by @region by @dy pixels in the Y
6587 * direction and @dx pixels in the X direction. The portions of @region
6588 * that not covered by the new position of @region are invalidated.
6590 * Child windows are not moved.
6595 gdk_window_move_region (GdkWindow *window,
6596 const cairo_region_t *region,
6600 GdkWindowObject *private = (GdkWindowObject *) window;
6601 GdkWindowObject *impl_window;
6602 cairo_region_t *nocopy_area;
6603 cairo_region_t *copy_area;
6605 g_return_if_fail (GDK_IS_WINDOW (window));
6606 g_return_if_fail (region != NULL);
6608 if (dx == 0 && dy == 0)
6611 if (private->destroyed)
6614 impl_window = gdk_window_get_impl_window (private);
6616 /* compute source regions */
6617 copy_area = cairo_region_copy (region);
6618 cairo_region_intersect (copy_area, private->clip_region_with_children);
6620 /* compute destination regions */
6621 cairo_region_translate (copy_area, dx, dy);
6622 cairo_region_intersect (copy_area, private->clip_region_with_children);
6624 /* Invalidate parts of the region (source and dest) not covered
6626 nocopy_area = cairo_region_copy (region);
6627 cairo_region_translate (nocopy_area, dx, dy);
6628 cairo_region_union (nocopy_area, region);
6629 cairo_region_subtract (nocopy_area, copy_area);
6631 /* convert from window coords to impl */
6632 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6633 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6635 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6636 cairo_region_destroy (nocopy_area);
6640 * gdk_window_set_background:
6641 * @window: a #GdkWindow
6642 * @color: a #GdkColor
6644 * Sets the background color of @window. (However, when using GTK+,
6645 * set the background of a widget with gtk_widget_modify_bg() - if
6646 * you're an application - or gtk_style_set_background() - if you're
6647 * implementing a custom widget.)
6649 * See also gdk_window_set_background_pattern().
6652 gdk_window_set_background (GdkWindow *window,
6653 const GdkColor *color)
6655 cairo_pattern_t *pattern;
6657 g_return_if_fail (GDK_IS_WINDOW (window));
6659 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6660 color->green / 65535.,
6661 color->blue / 65535.);
6663 gdk_window_set_background_pattern (window, pattern);
6665 cairo_pattern_destroy (pattern);
6669 * gdk_window_set_background_pattern:
6670 * @window: a #GdkWindow
6671 * @pattern: (allow-none): a pattern to use, or %NULL
6673 * Sets the background of @window.
6675 * A background of %NULL means that the window will inherit its
6676 * background form its parent window.
6678 * The windowing system will normally fill a window with its background
6679 * when the window is obscured then exposed.
6682 gdk_window_set_background_pattern (GdkWindow *window,
6683 cairo_pattern_t *pattern)
6685 GdkWindowObject *private;
6687 g_return_if_fail (GDK_IS_WINDOW (window));
6689 private = (GdkWindowObject *) window;
6692 cairo_pattern_reference (pattern);
6693 if (private->background)
6694 cairo_pattern_destroy (private->background);
6695 private->background = pattern;
6697 if (gdk_window_has_impl (private) &&
6698 !private->input_only)
6700 GdkWindowImplIface *impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6701 impl_iface->set_background (window, pattern);
6706 * gdk_window_get_background_pattern:
6709 * Gets the pattern used to clear the background on @window. If @window
6710 * does not have its own background and reuses the parent's, %NULL is
6711 * returned and you'll have to query it yourself.
6713 * Returns: The pattern to use for the background or %NULL to use the
6714 * parent's background.
6719 gdk_window_get_background_pattern (GdkWindow *window)
6721 GdkWindowObject *private = (GdkWindowObject *) window;
6723 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6725 return private->background;
6729 update_cursor_foreach (GdkDisplay *display,
6731 GdkPointerWindowInfo *pointer_info,
6734 GdkWindow *window = user_data;
6735 GdkWindowObject *private = (GdkWindowObject *) window;
6737 if (_gdk_native_windows ||
6738 private->window_type == GDK_WINDOW_ROOT ||
6739 private->window_type == GDK_WINDOW_FOREIGN)
6740 GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_device_cursor (window, device, private->cursor);
6741 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6742 update_cursor (display, device);
6746 * gdk_window_get_cursor:
6747 * @window: a #GdkWindow
6749 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6750 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6751 * there is no custom cursor set on the specified window, and it is
6752 * using the cursor for its parent window.
6754 * Return value: a #GdkCursor, or %NULL. The returned object is owned
6755 * by the #GdkWindow and should not be unreferenced directly. Use
6756 * gdk_window_set_cursor() to unset the cursor of the window
6761 gdk_window_get_cursor (GdkWindow *window)
6763 GdkWindowObject *private;
6765 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6767 private = (GdkWindowObject *) window;
6769 return private->cursor;
6773 * gdk_window_set_cursor:
6774 * @window: a #GdkWindow
6775 * @cursor: (allow-none): a cursor
6777 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6778 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6779 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6780 * to gdk_window_set_cursor() means that @window will use the cursor of its
6781 * parent window. Most windows should use this default.
6784 gdk_window_set_cursor (GdkWindow *window,
6787 GdkWindowObject *private;
6788 GdkDisplay *display;
6790 g_return_if_fail (GDK_IS_WINDOW (window));
6792 private = (GdkWindowObject *) window;
6793 display = gdk_window_get_display (window);
6795 if (private->cursor)
6797 gdk_cursor_unref (private->cursor);
6798 private->cursor = NULL;
6801 if (!GDK_WINDOW_DESTROYED (window))
6804 private->cursor = gdk_cursor_ref (cursor);
6806 _gdk_display_pointer_info_foreach (display,
6807 update_cursor_foreach,
6810 g_object_notify (G_OBJECT (window), "cursor");
6815 * gdk_window_get_device_cursor:
6816 * @window: a #GdkWindow.
6817 * @device: a #GdkDevice.
6819 * Retrieves a #GdkCursor pointer for the @device currently set on the
6820 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6821 * there is no custom cursor set on the specified window, and it is
6822 * using the cursor for its parent window.
6824 * Returns: a #GdkCursor, or %NULL. The returned object is owned
6825 * by the #GdkWindow and should not be unreferenced directly. Use
6826 * gdk_window_set_cursor() to unset the cursor of the window
6831 gdk_window_get_device_cursor (GdkWindow *window,
6834 GdkWindowObject *private;
6836 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6837 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6839 private = (GdkWindowObject *) window;
6841 return g_hash_table_lookup (private->device_cursor, device);
6845 * gdk_window_set_device_cursor:
6846 * @window: a #Gdkwindow
6847 * @device: a #GdkDevice
6848 * @cursor: a #GdkCursor
6850 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6851 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6852 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6853 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6854 * @window will use the cursor of its parent window. Most windows should
6860 gdk_window_set_device_cursor (GdkWindow *window,
6864 GdkWindowObject *private;
6865 GdkDisplay *display;
6867 g_return_if_fail (GDK_IS_WINDOW (window));
6868 g_return_if_fail (GDK_IS_DEVICE (device));
6870 private = (GdkWindowObject *) window;
6871 display = gdk_window_get_display (window);
6874 g_hash_table_remove (private->device_cursor, device);
6876 g_hash_table_replace (private->device_cursor, device, gdk_cursor_ref (cursor));
6878 if (!GDK_WINDOW_DESTROYED (window))
6880 GdkPointerWindowInfo *pointer_info;
6882 pointer_info = _gdk_display_get_pointer_info (display, device);
6884 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6885 update_cursor (display, device);
6890 * gdk_window_get_geometry:
6891 * @window: a #GdkWindow
6892 * @x: return location for X coordinate of window (relative to its parent)
6893 * @y: return location for Y coordinate of window (relative to its parent)
6894 * @width: return location for width of window
6895 * @height: return location for height of window
6896 * @depth: return location for bit depth of window
6898 * Any of the return location arguments to this function may be %NULL,
6899 * if you aren't interested in getting the value of that field.
6901 * The X and Y coordinates returned are relative to the parent window
6902 * of @window, which for toplevels usually means relative to the
6903 * window decorations (titlebar, etc.) rather than relative to the
6904 * root window (screen-size background window).
6906 * On the X11 platform, the geometry is obtained from the X server,
6907 * so reflects the latest position of @window; this may be out-of-sync
6908 * with the position of @window delivered in the most-recently-processed
6909 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6910 * position from the most recent configure event.
6913 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6914 * to call gdk_window_get_position(), gdk_window_get_width() and
6915 * gdk_window_get_height() instead, because it avoids the roundtrip to
6916 * the X server and because these functions support the full 32-bit
6917 * coordinate space, whereas gdk_window_get_geometry() is restricted to
6918 * the 16-bit coordinates of X11.
6922 gdk_window_get_geometry (GdkWindow *window,
6929 GdkWindowObject *private, *parent;
6930 GdkWindowImplIface *impl_iface;
6934 GDK_NOTE (MULTIHEAD,
6935 g_message ("gdk_window_get_geometry(): Window needs "
6936 "to be non-NULL to be multi head safe"));
6937 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
6940 g_return_if_fail (GDK_IS_WINDOW (window));
6942 private = (GdkWindowObject *) window;
6944 if (!GDK_WINDOW_DESTROYED (window))
6946 if (gdk_window_has_impl (private))
6948 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6949 impl_iface->get_geometry (window, x, y,
6952 /* This reports the position wrt to the native parent, we need to convert
6953 it to be relative to the client side parent */
6954 parent = private->parent;
6955 if (parent && !gdk_window_has_impl (parent))
6958 *x -= parent->abs_x;
6960 *y -= parent->abs_y;
6970 *width = private->width;
6972 *height = private->height;
6974 *depth = private->depth;
6980 * gdk_window_get_width:
6981 * @window: a #GdkWindow
6983 * Returns the width of the given @window.
6985 * On the X11 platform the returned size is the size reported in the
6986 * most-recently-processed configure event, rather than the current
6987 * size on the X server.
6989 * Returns: The width of @window
6994 gdk_window_get_width (GdkWindow *window)
6996 GdkWindowObject *private;
6998 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7000 private = (GdkWindowObject *) window;
7002 return private->width;
7006 * gdk_window_get_height:
7007 * @window: a #GdkWindow
7009 * Returns the height of the given @window.
7011 * On the X11 platform the returned size is the size reported in the
7012 * most-recently-processed configure event, rather than the current
7013 * size on the X server.
7015 * Returns: The height of @window
7020 gdk_window_get_height (GdkWindow *window)
7022 GdkWindowObject *private;
7024 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7026 private = (GdkWindowObject *) window;
7028 return private->height;
7032 * gdk_window_get_origin:
7033 * @window: a #GdkWindow
7034 * @x: return location for X coordinate
7035 * @y: return location for Y coordinate
7037 * Obtains the position of a window in root window coordinates.
7038 * (Compare with gdk_window_get_position() and
7039 * gdk_window_get_geometry() which return the position of a window
7040 * relative to its parent window.)
7042 * Return value: not meaningful, ignore
7045 gdk_window_get_origin (GdkWindow *window,
7049 GdkWindowObject *private;
7050 GdkWindowImplIface *impl_iface;
7052 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7054 if (GDK_WINDOW_DESTROYED (window))
7063 private = (GdkWindowObject *) window;
7065 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7066 impl_iface->get_root_coords (window,
7075 * gdk_window_get_root_coords:
7076 * @window: a #GdkWindow
7077 * @x: X coordinate in window
7078 * @y: Y coordinate in window
7079 * @root_x: return location for X coordinate
7080 * @root_y: return location for Y coordinate
7082 * Obtains the position of a window position in root
7083 * window coordinates. This is similar to
7084 * gdk_window_get_origin() but allows you go pass
7085 * in any position in the window, not just the origin.
7090 gdk_window_get_root_coords (GdkWindow *window,
7096 GdkWindowObject *private;
7097 GdkWindowImplIface *impl_iface;
7099 g_return_if_fail (GDK_IS_WINDOW (window));
7101 private = (GdkWindowObject *) window;
7103 if (GDK_WINDOW_DESTROYED (window))
7112 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7113 impl_iface->get_root_coords (window,
7120 * gdk_window_coords_to_parent:
7121 * @window: a child window
7122 * @x: X coordinate in child's coordinate system
7123 * @y: Y coordinate in child's coordinate system
7124 * @parent_x: (out) (allow-none): return location for X coordinate
7125 * in parent's coordinate system, or %NULL
7126 * @parent_y: (out) (allow-none): return location for Y coordinate
7127 * in parent's coordinate system, or %NULL
7129 * Transforms window coordinates from a child window to its parent
7130 * window, where the parent window is the normal parent as returned by
7131 * gdk_window_get_parent() for normal windows, and the window's
7132 * embedder as returned by gdk_offscreen_window_get_embedder() for
7133 * offscreen windows.
7135 * For normal windows, calling this function is equivalent to adding
7136 * the return values of gdk_window_get_position() to the child coordinates.
7137 * For offscreen windows however (which can be arbitrarily transformed),
7138 * this function calls the GdkWindow::to-embedder: signal to translate
7141 * You should always use this function when writing generic code that
7142 * walks up a window hierarchy.
7144 * See also: gdk_window_coords_from_parent()
7149 gdk_window_coords_to_parent (GdkWindow *window,
7155 GdkWindowObject *obj;
7157 g_return_if_fail (GDK_IS_WINDOW (window));
7159 obj = (GdkWindowObject *) window;
7161 if (gdk_window_is_offscreen (obj))
7165 to_embedder (obj, x, y, &px, &py);
7176 *parent_x = x + obj->x;
7179 *parent_y = y + obj->y;
7184 * gdk_window_coords_from_parent:
7185 * @window: a child window
7186 * @parent_x: X coordinate in parent's coordinate system
7187 * @parent_y: Y coordinate in parent's coordinate system
7188 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7189 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7191 * Transforms window coordinates from a parent window to a child
7192 * window, where the parent window is the normal parent as returned by
7193 * gdk_window_get_parent() for normal windows, and the window's
7194 * embedder as returned by gdk_offscreen_window_get_embedder() for
7195 * offscreen windows.
7197 * For normal windows, calling this function is equivalent to subtracting
7198 * the return values of gdk_window_get_position() from the parent coordinates.
7199 * For offscreen windows however (which can be arbitrarily transformed),
7200 * this function calls the GdkWindow::from-embedder: signal to translate
7203 * You should always use this function when writing generic code that
7204 * walks down a window hierarchy.
7206 * See also: gdk_window_coords_to_parent()
7211 gdk_window_coords_from_parent (GdkWindow *window,
7217 GdkWindowObject *obj;
7219 g_return_if_fail (GDK_IS_WINDOW (window));
7221 obj = (GdkWindowObject *) window;
7223 if (gdk_window_is_offscreen (obj))
7227 from_embedder (obj, parent_x, parent_y, &cx, &cy);
7238 *x = parent_x - obj->x;
7241 *y = parent_y - obj->y;
7246 * gdk_window_shape_combine_region:
7247 * @window: a #GdkWindow
7248 * @shape_region: region of window to be non-transparent
7249 * @offset_x: X position of @shape_region in @window coordinates
7250 * @offset_y: Y position of @shape_region in @window coordinates
7252 * Makes pixels in @window outside @shape_region be transparent,
7253 * so that the window may be nonrectangular.
7255 * If @shape_region is %NULL, the shape will be unset, so the whole
7256 * window will be opaque again. @offset_x and @offset_y are ignored
7257 * if @shape_region is %NULL.
7259 * On the X11 platform, this uses an X server extension which is
7260 * widely available on most common platforms, but not available on
7261 * very old X servers, and occasionally the implementation will be
7262 * buggy. On servers without the shape extension, this function
7265 * This function works on both toplevel and child windows.
7268 gdk_window_shape_combine_region (GdkWindow *window,
7269 const cairo_region_t *shape_region,
7273 GdkWindowObject *private;
7274 cairo_region_t *old_region, *new_region, *diff;
7276 g_return_if_fail (GDK_IS_WINDOW (window));
7278 private = (GdkWindowObject *) window;
7280 if (GDK_WINDOW_DESTROYED (window))
7283 private->shaped = (shape_region != NULL);
7286 cairo_region_destroy (private->shape);
7289 if (GDK_WINDOW_IS_MAPPED (window))
7290 old_region = cairo_region_copy (private->clip_region);
7294 private->shape = cairo_region_copy (shape_region);
7295 cairo_region_translate (private->shape, offset_x, offset_y);
7298 private->shape = NULL;
7300 recompute_visible_regions (private, TRUE, FALSE);
7302 if (gdk_window_has_impl (private) &&
7303 !should_apply_clip_as_shape (private))
7304 apply_shape (private, private->shape);
7308 new_region = cairo_region_copy (private->clip_region);
7310 /* New area in the window, needs invalidation */
7311 diff = cairo_region_copy (new_region);
7312 cairo_region_subtract (diff, old_region);
7314 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7316 cairo_region_destroy (diff);
7318 if (!gdk_window_is_toplevel (private))
7320 /* New area in the non-root parent window, needs invalidation */
7321 diff = cairo_region_copy (old_region);
7322 cairo_region_subtract (diff, new_region);
7324 /* Adjust region to parent window coords */
7325 cairo_region_translate (diff, private->x, private->y);
7327 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
7329 cairo_region_destroy (diff);
7332 cairo_region_destroy (new_region);
7333 cairo_region_destroy (old_region);
7338 do_child_shapes (GdkWindow *window,
7341 GdkWindowObject *private;
7343 cairo_region_t *region;
7345 private = (GdkWindowObject *) window;
7349 r.width = private->width;
7350 r.height = private->height;
7352 region = cairo_region_create_rectangle (&r);
7353 remove_child_area (private, NULL, FALSE, region);
7355 if (merge && private->shape)
7356 cairo_region_subtract (region, private->shape);
7358 gdk_window_shape_combine_region (window, region, 0, 0);
7362 * gdk_window_set_child_shapes:
7363 * @window: a #GdkWindow
7365 * Sets the shape mask of @window to the union of shape masks
7366 * for all children of @window, ignoring the shape mask of @window
7367 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7368 * the shape mask of @window in the masks to be merged.
7371 gdk_window_set_child_shapes (GdkWindow *window)
7373 g_return_if_fail (GDK_IS_WINDOW (window));
7375 do_child_shapes (window, FALSE);
7379 * gdk_window_merge_child_shapes:
7380 * @window: a #GdkWindow
7382 * Merges the shape masks for any child windows into the
7383 * shape mask for @window. i.e. the union of all masks
7384 * for @window and its children will become the new mask
7385 * for @window. See gdk_window_shape_combine_region().
7387 * This function is distinct from gdk_window_set_child_shapes()
7388 * because it includes @window's shape mask in the set of shapes to
7392 gdk_window_merge_child_shapes (GdkWindow *window)
7394 g_return_if_fail (GDK_IS_WINDOW (window));
7396 do_child_shapes (window, TRUE);
7400 * gdk_window_input_shape_combine_region:
7401 * @window: a #GdkWindow
7402 * @shape_region: region of window to be non-transparent
7403 * @offset_x: X position of @shape_region in @window coordinates
7404 * @offset_y: Y position of @shape_region in @window coordinates
7406 * Like gdk_window_shape_combine_region(), but the shape applies
7407 * only to event handling. Mouse events which happen while
7408 * the pointer position corresponds to an unset bit in the
7409 * mask will be passed on the window below @window.
7411 * An input shape is typically used with RGBA windows.
7412 * The alpha channel of the window defines which pixels are
7413 * invisible and allows for nicely antialiased borders,
7414 * and the input shape controls where the window is
7417 * On the X11 platform, this requires version 1.1 of the
7420 * On the Win32 platform, this functionality is not present and the
7421 * function does nothing.
7426 gdk_window_input_shape_combine_region (GdkWindow *window,
7427 const cairo_region_t *shape_region,
7431 GdkWindowObject *private;
7432 GdkWindowImplIface *impl_iface;
7434 g_return_if_fail (GDK_IS_WINDOW (window));
7436 private = (GdkWindowObject *) window;
7438 if (GDK_WINDOW_DESTROYED (window))
7441 if (private->input_shape)
7442 cairo_region_destroy (private->input_shape);
7446 private->input_shape = cairo_region_copy (shape_region);
7447 cairo_region_translate (private->input_shape, offset_x, offset_y);
7450 private->input_shape = NULL;
7452 if (gdk_window_has_impl (private))
7454 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7455 impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
7458 /* Pointer may have e.g. moved outside window due to the input mask change */
7459 _gdk_synthesize_crossing_events_for_geometry_change (window);
7463 do_child_input_shapes (GdkWindow *window,
7466 GdkWindowObject *private;
7468 cairo_region_t *region;
7470 private = (GdkWindowObject *) window;
7474 r.width = private->width;
7475 r.height = private->height;
7477 region = cairo_region_create_rectangle (&r);
7478 remove_child_area (private, NULL, TRUE, region);
7480 if (merge && private->shape)
7481 cairo_region_subtract (region, private->shape);
7482 if (merge && private->input_shape)
7483 cairo_region_subtract (region, private->input_shape);
7485 gdk_window_input_shape_combine_region (window, region, 0, 0);
7490 * gdk_window_set_child_input_shapes:
7491 * @window: a #GdkWindow
7493 * Sets the input shape mask of @window to the union of input shape masks
7494 * for all children of @window, ignoring the input shape mask of @window
7495 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7496 * the input shape mask of @window in the masks to be merged.
7501 gdk_window_set_child_input_shapes (GdkWindow *window)
7503 g_return_if_fail (GDK_IS_WINDOW (window));
7505 do_child_input_shapes (window, FALSE);
7509 * gdk_window_merge_child_input_shapes:
7510 * @window: a #GdkWindow
7512 * Merges the input shape masks for any child windows into the
7513 * input shape mask for @window. i.e. the union of all input masks
7514 * for @window and its children will become the new input mask
7515 * for @window. See gdk_window_input_shape_combine_region().
7517 * This function is distinct from gdk_window_set_child_input_shapes()
7518 * because it includes @window's input shape mask in the set of
7519 * shapes to be merged.
7524 gdk_window_merge_child_input_shapes (GdkWindow *window)
7526 g_return_if_fail (GDK_IS_WINDOW (window));
7528 do_child_input_shapes (window, TRUE);
7533 * gdk_window_set_static_gravities:
7534 * @window: a #GdkWindow
7535 * @use_static: %TRUE to turn on static gravity
7537 * Set the bit gravity of the given window to static, and flag it so
7538 * all children get static subwindow gravity. This is used if you are
7539 * implementing scary features that involve deep knowledge of the
7540 * windowing system. Don't worry about it unless you have to.
7542 * Return value: %TRUE if the server supports static gravity
7545 gdk_window_set_static_gravities (GdkWindow *window,
7546 gboolean use_static)
7548 GdkWindowObject *private;
7549 GdkWindowImplIface *impl_iface;
7551 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7553 private = (GdkWindowObject *) window;
7555 if (gdk_window_has_impl (private))
7557 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7558 return impl_iface->set_static_gravities (window, use_static);
7565 * gdk_window_get_composited:
7566 * @window: a #GdkWindow
7568 * Determines whether @window is composited.
7570 * See gdk_window_set_composited().
7572 * Returns: %TRUE if the window is composited.
7577 gdk_window_get_composited (GdkWindow *window)
7579 GdkWindowObject *private;
7581 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7583 private = (GdkWindowObject *)window;
7585 return private->composited;
7589 * gdk_window_set_composited:
7590 * @window: a #GdkWindow
7591 * @composited: %TRUE to set the window as composited
7593 * Sets a #GdkWindow as composited, or unsets it. Composited
7594 * windows do not automatically have their contents drawn to
7595 * the screen. Drawing is redirected to an offscreen buffer
7596 * and an expose event is emitted on the parent of the composited
7597 * window. It is the responsibility of the parent's expose handler
7598 * to manually merge the off-screen content onto the screen in
7599 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7602 * It only makes sense for child windows to be composited; see
7603 * gdk_window_set_opacity() if you need translucent toplevel
7606 * An additional effect of this call is that the area of this
7607 * window is no longer clipped from regions marked for
7608 * invalidation on its parent. Draws done on the parent
7609 * window are also no longer clipped by the child.
7611 * This call is only supported on some systems (currently,
7612 * only X11 with new enough Xcomposite and Xdamage extensions).
7613 * You must call gdk_display_supports_composite() to check if
7614 * setting a window as composited is supported before
7615 * attempting to do so.
7620 gdk_window_set_composited (GdkWindow *window,
7621 gboolean composited)
7623 GdkWindowObject *private = (GdkWindowObject *)window;
7624 GdkDisplay *display;
7626 g_return_if_fail (GDK_IS_WINDOW (window));
7628 composited = composited != FALSE;
7630 if (private->composited == composited)
7634 gdk_window_ensure_native (window);
7636 display = gdk_window_get_display (window);
7638 if (!gdk_display_supports_composite (display) && composited)
7640 g_warning ("gdk_window_set_composited called but "
7641 "compositing is not supported");
7645 _gdk_windowing_window_set_composited (window, composited);
7647 recompute_visible_regions (private, TRUE, FALSE);
7649 if (GDK_WINDOW_IS_MAPPED (window))
7650 gdk_window_invalidate_in_parent (private);
7652 private->composited = composited;
7656 * gdk_window_get_modal_hint:
7657 * @window: A toplevel #GdkWindow.
7659 * Determines whether or not the window manager is hinted that @window
7660 * has modal behaviour.
7662 * Return value: whether or not the window has the modal hint set.
7667 gdk_window_get_modal_hint (GdkWindow *window)
7669 GdkWindowObject *private;
7671 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7673 private = (GdkWindowObject*) window;
7675 return private->modal_hint;
7679 * gdk_window_get_accept_focus:
7680 * @window: a toplevel #GdkWindow.
7682 * Determines whether or not the desktop environment shuld be hinted that
7683 * the window does not want to receive input focus.
7685 * Return value: whether or not the window should receive input focus.
7690 gdk_window_get_accept_focus (GdkWindow *window)
7692 GdkWindowObject *private;
7694 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7696 private = (GdkWindowObject *)window;
7698 return private->accept_focus;
7702 * gdk_window_get_focus_on_map:
7703 * @window: a toplevel #GdkWindow.
7705 * Determines whether or not the desktop environment should be hinted that the
7706 * window does not want to receive input focus when it is mapped.
7708 * Return value: whether or not the window wants to receive input focus when
7714 gdk_window_get_focus_on_map (GdkWindow *window)
7716 GdkWindowObject *private;
7718 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7720 private = (GdkWindowObject *)window;
7722 return private->focus_on_map;
7726 * gdk_window_is_input_only:
7727 * @window: a toplevel #GdkWindow
7729 * Determines whether or not the window is an input only window.
7731 * Return value: %TRUE if @window is input only
7736 gdk_window_is_input_only (GdkWindow *window)
7738 GdkWindowObject *private;
7740 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7742 private = (GdkWindowObject *)window;
7744 return private->input_only;
7748 * gdk_window_is_shaped:
7749 * @window: a toplevel #GdkWindow
7751 * Determines whether or not the window is shaped.
7753 * Return value: %TRUE if @window is shaped
7758 gdk_window_is_shaped (GdkWindow *window)
7760 GdkWindowObject *private;
7762 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7764 private = (GdkWindowObject *)window;
7766 return private->shaped;
7770 window_get_size_rectangle (GdkWindow *window,
7773 GdkWindowObject *private = (GdkWindowObject *) window;
7775 rect->x = rect->y = 0;
7776 rect->width = private->width;
7777 rect->height = private->height;
7780 /* Calculates the real clipping region for a window, in window coordinates,
7781 * taking into account other windows, gc clip region and gc clip mask.
7784 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7785 GdkWindow *base_window,
7786 gboolean do_children,
7787 gint *base_x_offset,
7788 gint *base_y_offset)
7790 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
7791 GdkRectangle visible_rect;
7792 cairo_region_t *real_clip_region;
7793 gint x_offset, y_offset;
7794 GdkWindowObject *parentwin, *lastwin;
7801 if (!private->viewable || private->input_only)
7802 return cairo_region_create ();
7804 window_get_size_rectangle (window, &visible_rect);
7806 /* real_clip_region is in window coordinates */
7807 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7809 x_offset = y_offset = 0;
7813 parentwin = lastwin;
7815 parentwin = lastwin->parent;
7817 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7818 for (; parentwin != NULL &&
7819 (parentwin == private || lastwin != (GdkWindowObject*) base_window);
7820 lastwin = parentwin, parentwin = lastwin->parent)
7823 GdkRectangle real_clip_rect;
7825 if (parentwin != private)
7827 x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
7828 y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
7831 /* children is ordered in reverse stack order */
7832 for (cur = parentwin->children;
7833 cur && cur->data != lastwin;
7836 GdkWindow *child = cur->data;
7837 GdkWindowObject *child_private = (GdkWindowObject *)child;
7839 if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
7842 /* Ignore offscreen children, as they don't draw in their parent and
7843 * don't take part in the clipping */
7844 if (gdk_window_is_offscreen (child_private))
7847 window_get_size_rectangle (child, &visible_rect);
7849 /* Convert rect to "window" coords */
7850 visible_rect.x += child_private->x - x_offset;
7851 visible_rect.y += child_private->y - y_offset;
7853 /* This shortcut is really necessary for performance when there are a lot of windows */
7854 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7855 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7856 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7857 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7858 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7861 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7864 /* Clip to the parent */
7865 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7866 /* Convert rect to "window" coords */
7867 visible_rect.x += - x_offset;
7868 visible_rect.y += - y_offset;
7870 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7874 *base_x_offset = x_offset;
7876 *base_y_offset = y_offset;
7878 return real_clip_region;
7882 _gdk_window_add_damage (GdkWindow *toplevel,
7883 cairo_region_t *damaged_region)
7885 GdkDisplay *display;
7886 GdkEvent event = { 0, };
7887 event.expose.type = GDK_DAMAGE;
7888 event.expose.window = toplevel;
7889 event.expose.send_event = FALSE;
7890 event.expose.region = damaged_region;
7891 cairo_region_get_extents (event.expose.region, &event.expose.area);
7892 display = gdk_window_get_display (event.expose.window);
7893 _gdk_event_queue_append (display, gdk_event_copy (&event));
7896 /* Gets the toplevel for a window as used for events,
7897 i.e. including offscreen parents */
7898 static GdkWindowObject *
7899 get_event_parent (GdkWindowObject *window)
7901 if (gdk_window_is_offscreen (window))
7902 return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7904 return window->parent;
7907 /* Gets the toplevel for a window as used for events,
7908 i.e. including offscreen parents going up to the native
7911 get_event_toplevel (GdkWindow *w)
7913 GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
7914 GdkWindowObject *parent;
7916 while ((parent = get_event_parent (private)) != NULL &&
7917 (parent->window_type != GDK_WINDOW_ROOT))
7920 return GDK_WINDOW (private);
7924 _gdk_window_event_parent_of (GdkWindow *parent,
7935 w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
7942 update_cursor (GdkDisplay *display,
7945 GdkWindowObject *cursor_window, *parent, *toplevel;
7946 GdkWindow *pointer_window;
7947 GdkWindowImplIface *impl_iface;
7948 GdkPointerWindowInfo *pointer_info;
7949 GdkDeviceGrabInfo *grab;
7952 pointer_info = _gdk_display_get_pointer_info (display, device);
7953 pointer_window = pointer_info->window_under_pointer;
7955 /* We ignore the serials here and just pick the last grab
7956 we've sent, as that would shortly be used anyway. */
7957 grab = _gdk_display_get_last_device_grab (display, device);
7960 /* the pointer is not in a descendant of the grab window */
7961 !_gdk_window_event_parent_of (grab->window, pointer_window))
7963 /* use the cursor from the grab window */
7964 cursor_window = (GdkWindowObject *) grab->window;
7968 /* otherwise use the cursor from the pointer window */
7969 cursor_window = (GdkWindowObject *) pointer_window;
7972 /* Find the first window with the cursor actually set, as
7973 the cursor is inherited from the parent */
7974 while (cursor_window->cursor == NULL &&
7975 (parent = get_event_parent (cursor_window)) != NULL &&
7976 parent->window_type != GDK_WINDOW_ROOT)
7977 cursor_window = parent;
7979 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
7982 cursor = cursor_window->cursor;
7984 /* Set all cursors on toplevel, otherwise its tricky to keep track of
7985 * which native window has what cursor set. */
7986 toplevel = (GdkWindowObject *) get_event_toplevel (pointer_window);
7987 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
7988 impl_iface->set_device_cursor ((GdkWindow *) toplevel, device, cursor);
7992 point_in_window (GdkWindowObject *window,
7997 x >= 0 && x < window->width &&
7998 y >= 0 && y < window->height &&
7999 (window->shape == NULL ||
8000 cairo_region_contains_point (window->shape,
8002 (window->input_shape == NULL ||
8003 cairo_region_contains_point (window->input_shape,
8008 convert_native_coords_to_toplevel (GdkWindow *window,
8011 gdouble *toplevel_x,
8012 gdouble *toplevel_y)
8014 GdkWindowObject *private = (GdkWindowObject *)window;
8020 while (!gdk_window_is_toplevel (private))
8024 private = private->parent;
8030 return (GdkWindow *)private;
8034 convert_toplevel_coords_to_window (GdkWindow *window,
8040 GdkWindowObject *private;
8041 GdkWindowObject *parent;
8043 GList *children, *l;
8045 private = GDK_WINDOW_OBJECT (window);
8051 while ((parent = get_event_parent (private)) != NULL &&
8052 (parent->window_type != GDK_WINDOW_ROOT))
8054 children = g_list_prepend (children, private);
8058 for (l = children; l != NULL; l = l->next)
8059 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
8061 g_list_free (children);
8067 static GdkWindowObject *
8068 pick_embedded_child (GdkWindowObject *window,
8072 GdkWindowObject *res;
8075 g_signal_emit (window,
8076 signals[PICK_EMBEDDED_CHILD], 0,
8083 _gdk_window_find_child_at (GdkWindow *window,
8087 GdkWindowObject *private, *sub;
8088 double child_x, child_y;
8091 private = (GdkWindowObject *)window;
8093 if (point_in_window (private, x, y))
8095 /* Children is ordered in reverse stack order, i.e. first is topmost */
8096 for (l = private->children; l != NULL; l = l->next)
8100 if (!GDK_WINDOW_IS_MAPPED (sub))
8103 gdk_window_coords_from_parent ((GdkWindow *)sub,
8105 &child_x, &child_y);
8106 if (point_in_window (sub, child_x, child_y))
8107 return (GdkWindow *)sub;
8110 if (private->num_offscreen_children > 0)
8112 sub = pick_embedded_child (private,
8115 return (GdkWindow *)sub;
8123 _gdk_window_find_descendant_at (GdkWindow *toplevel,
8129 GdkWindowObject *private, *sub;
8130 gdouble child_x, child_y;
8134 private = (GdkWindowObject *)toplevel;
8136 if (point_in_window (private, x, y))
8141 /* Children is ordered in reverse stack order, i.e. first is topmost */
8142 for (l = private->children; l != NULL; l = l->next)
8146 if (!GDK_WINDOW_IS_MAPPED (sub))
8149 gdk_window_coords_from_parent ((GdkWindow *)sub,
8151 &child_x, &child_y);
8152 if (point_in_window (sub, child_x, child_y))
8162 private->num_offscreen_children > 0)
8164 sub = pick_embedded_child (private,
8170 from_embedder (sub, x, y, &x, &y);
8178 /* Not in window at all */
8187 return (GdkWindow *)private;
8192 * @window: a toplevel #GdkWindow
8194 * Emits a short beep associated to @window in the appropriate
8195 * display, if supported. Otherwise, emits a short beep on
8196 * the display just as gdk_display_beep().
8201 gdk_window_beep (GdkWindow *window)
8203 GdkDisplay *display;
8204 GdkWindow *toplevel;
8206 g_return_if_fail (GDK_IS_WINDOW (window));
8208 if (GDK_WINDOW_DESTROYED (window))
8211 toplevel = get_event_toplevel (window);
8212 display = gdk_window_get_display (window);
8214 if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
8215 _gdk_windowing_window_beep (toplevel);
8217 gdk_display_beep (display);
8221 * gdk_window_set_support_multidevice:
8222 * @window: a #GdkWindow.
8223 * @support_multidevice: %TRUE to enable multidevice support in @window.
8225 * This function will enable multidevice features in @window.
8227 * Multidevice aware windows will need to handle properly multiple,
8228 * per device enter/leave events, device grabs and grab ownerships.
8233 gdk_window_set_support_multidevice (GdkWindow *window,
8234 gboolean support_multidevice)
8236 GdkWindowObject *private = (GdkWindowObject *) window;
8238 g_return_if_fail (GDK_IS_WINDOW (window));
8240 if (GDK_WINDOW_DESTROYED (window))
8243 if (private->support_multidevice == support_multidevice)
8246 private->support_multidevice = support_multidevice;
8248 /* FIXME: What to do if called when some pointers are inside the window ? */
8252 * gdk_window_get_support_multidevice:
8253 * @window: a #GdkWindow.
8255 * Returns %TRUE if the window is aware of the existence of multiple
8258 * Returns: %TRUE if the window handles multidevice features.
8263 gdk_window_get_support_multidevice (GdkWindow *window)
8265 GdkWindowObject *private = (GdkWindowObject *) window;
8267 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8269 if (GDK_WINDOW_DESTROYED (window))
8272 return private->support_multidevice;
8275 static const guint type_masks[] = {
8276 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8277 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8278 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8279 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8280 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8281 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8282 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8283 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8284 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8285 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8286 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8287 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8288 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8289 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8290 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8291 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8292 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8293 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8294 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8295 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8296 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8297 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8298 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8299 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8300 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8301 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8302 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8303 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8304 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8305 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8306 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8307 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8308 0, /* GDK_WINDOW_STATE = 32 */
8309 0, /* GDK_SETTING = 33 */
8310 0, /* GDK_OWNER_CHANGE = 34 */
8311 0, /* GDK_GRAB_BROKEN = 35 */
8312 0, /* GDK_DAMAGE = 36 */
8314 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8316 /* send motion events if the right buttons are down */
8318 update_evmask_for_button_motion (guint evmask,
8319 GdkModifierType mask)
8321 if (evmask & GDK_BUTTON_MOTION_MASK &&
8322 mask & (GDK_BUTTON1_MASK |
8327 evmask |= GDK_POINTER_MOTION_MASK;
8329 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8330 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8331 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8332 evmask |= GDK_POINTER_MOTION_MASK;
8338 is_button_type (GdkEventType type)
8340 return type == GDK_BUTTON_PRESS ||
8341 type == GDK_2BUTTON_PRESS ||
8342 type == GDK_3BUTTON_PRESS ||
8343 type == GDK_BUTTON_RELEASE ||
8348 is_motion_type (GdkEventType type)
8350 return type == GDK_MOTION_NOTIFY ||
8351 type == GDK_ENTER_NOTIFY ||
8352 type == GDK_LEAVE_NOTIFY;
8355 static GdkWindowObject *
8356 find_common_ancestor (GdkWindowObject *win1,
8357 GdkWindowObject *win2)
8359 GdkWindowObject *tmp;
8360 GList *path1 = NULL, *path2 = NULL;
8361 GList *list1, *list2;
8364 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8366 path1 = g_list_prepend (path1, tmp);
8367 tmp = get_event_parent (tmp);
8371 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8373 path2 = g_list_prepend (path2, tmp);
8374 tmp = get_event_parent (tmp);
8380 while (list1 && list2 && (list1->data == list2->data))
8382 tmp = (GdkWindowObject *)list1->data;
8383 list1 = g_list_next (list1);
8384 list2 = g_list_next (list2);
8386 g_list_free (path1);
8387 g_list_free (path2);
8393 _gdk_make_event (GdkWindow *window,
8395 GdkEvent *event_in_queue,
8396 gboolean before_event)
8398 GdkEvent *event = gdk_event_new (type);
8400 GdkModifierType the_state;
8402 the_time = gdk_event_get_time (event_in_queue);
8403 gdk_event_get_state (event_in_queue, &the_state);
8405 event->any.window = g_object_ref (window);
8406 event->any.send_event = FALSE;
8407 if (event_in_queue && event_in_queue->any.send_event)
8408 event->any.send_event = TRUE;
8412 case GDK_MOTION_NOTIFY:
8413 event->motion.time = the_time;
8414 event->motion.axes = NULL;
8415 event->motion.state = the_state;
8418 case GDK_BUTTON_PRESS:
8419 case GDK_2BUTTON_PRESS:
8420 case GDK_3BUTTON_PRESS:
8421 case GDK_BUTTON_RELEASE:
8422 event->button.time = the_time;
8423 event->button.axes = NULL;
8424 event->button.state = the_state;
8428 event->scroll.time = the_time;
8429 event->scroll.state = the_state;
8433 case GDK_KEY_RELEASE:
8434 event->key.time = the_time;
8435 event->key.state = the_state;
8438 case GDK_ENTER_NOTIFY:
8439 case GDK_LEAVE_NOTIFY:
8440 event->crossing.time = the_time;
8441 event->crossing.state = the_state;
8444 case GDK_PROPERTY_NOTIFY:
8445 event->property.time = the_time;
8446 event->property.state = the_state;
8449 case GDK_SELECTION_CLEAR:
8450 case GDK_SELECTION_REQUEST:
8451 case GDK_SELECTION_NOTIFY:
8452 event->selection.time = the_time;
8455 case GDK_PROXIMITY_IN:
8456 case GDK_PROXIMITY_OUT:
8457 event->proximity.time = the_time;
8460 case GDK_DRAG_ENTER:
8461 case GDK_DRAG_LEAVE:
8462 case GDK_DRAG_MOTION:
8463 case GDK_DRAG_STATUS:
8464 case GDK_DROP_START:
8465 case GDK_DROP_FINISHED:
8466 event->dnd.time = the_time;
8469 case GDK_FOCUS_CHANGE:
8473 case GDK_CLIENT_EVENT:
8474 case GDK_VISIBILITY_NOTIFY:
8486 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8488 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8491 _gdk_event_queue_append (gdk_window_get_display (window), event);
8497 send_crossing_event (GdkDisplay *display,
8498 GdkWindowObject *toplevel,
8499 GdkWindowObject *window,
8501 GdkCrossingMode mode,
8502 GdkNotifyType notify_type,
8503 GdkWindow *subwindow,
8507 GdkModifierType mask,
8509 GdkEvent *event_in_queue,
8513 guint32 window_event_mask, type_event_mask;
8514 GdkDeviceGrabInfo *grab;
8515 gboolean block_event = FALSE;
8517 grab = _gdk_display_has_device_grab (display, device, serial);
8520 !grab->owner_events)
8522 /* !owner_event => only report events wrt grab window, ignore rest */
8523 if ((GdkWindow *)window != grab->window)
8525 window_event_mask = grab->event_mask;
8528 window_event_mask = window->event_mask;
8530 if (type == GDK_LEAVE_NOTIFY)
8532 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8533 window->devices_inside = g_list_remove (window->devices_inside, device);
8535 if (!window->support_multidevice && window->devices_inside)
8537 /* Block leave events unless it's the last pointer */
8543 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8545 if (!window->support_multidevice && window->devices_inside)
8547 /* Only emit enter events for the first device */
8551 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8552 device->mode != GDK_MODE_DISABLED &&
8553 !g_list_find (window->devices_inside, device))
8554 window->devices_inside = g_list_prepend (window->devices_inside, device);
8560 if (window_event_mask & type_event_mask)
8562 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8563 gdk_event_set_device (event, device);
8564 event->crossing.time = time_;
8565 event->crossing.subwindow = subwindow;
8567 g_object_ref (subwindow);
8568 convert_toplevel_coords_to_window ((GdkWindow *)window,
8569 toplevel_x, toplevel_y,
8570 &event->crossing.x, &event->crossing.y);
8571 event->crossing.x_root = toplevel_x + toplevel->x;
8572 event->crossing.y_root = toplevel_y + toplevel->y;
8573 event->crossing.mode = mode;
8574 event->crossing.detail = notify_type;
8575 event->crossing.focus = FALSE;
8576 event->crossing.state = mask;
8581 /* The coordinates are in the toplevel window that src/dest are in.
8582 * src and dest are always (if != NULL) in the same toplevel, as
8583 * we get a leave-notify and set the window_under_pointer to null
8584 * before crossing to another toplevel.
8587 _gdk_synthesize_crossing_events (GdkDisplay *display,
8591 GdkCrossingMode mode,
8594 GdkModifierType mask,
8596 GdkEvent *event_in_queue,
8598 gboolean non_linear)
8601 GdkWindowObject *win, *last, *next;
8605 GdkWindowObject *toplevel;
8606 GdkNotifyType notify_type;
8608 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8610 a = (GdkWindowObject *)src;
8611 b = (GdkWindowObject *)dest;
8613 return; /* No crossings generated between src and dest */
8615 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8617 if (a && gdk_window_get_device_events (src, device) == 0)
8620 if (b && gdk_window_get_device_events (dest, device) == 0)
8627 c = find_common_ancestor (a, b);
8629 non_linear |= (c != a) && (c != b);
8631 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8633 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
8635 /* Traverse up from a to (excluding) c sending leave events */
8637 notify_type = GDK_NOTIFY_NONLINEAR;
8639 notify_type = GDK_NOTIFY_INFERIOR;
8641 notify_type = GDK_NOTIFY_ANCESTOR;
8642 send_crossing_event (display, toplevel,
8643 a, GDK_LEAVE_NOTIFY,
8647 toplevel_x, toplevel_y,
8655 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8657 notify_type = GDK_NOTIFY_VIRTUAL;
8660 win = get_event_parent (a);
8661 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8663 send_crossing_event (display, toplevel,
8664 win, GDK_LEAVE_NOTIFY,
8669 toplevel_x, toplevel_y,
8675 win = get_event_parent (win);
8680 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8682 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
8684 /* Traverse down from c to b */
8688 win = get_event_parent (b);
8689 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8691 path = g_list_prepend (path, win);
8692 win = get_event_parent (win);
8696 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8698 notify_type = GDK_NOTIFY_VIRTUAL;
8703 win = (GdkWindowObject *)list->data;
8704 list = g_list_next (list);
8706 next = (GdkWindowObject *)list->data;
8710 send_crossing_event (display, toplevel,
8711 win, GDK_ENTER_NOTIFY,
8716 toplevel_x, toplevel_y,
8726 notify_type = GDK_NOTIFY_NONLINEAR;
8728 notify_type = GDK_NOTIFY_ANCESTOR;
8730 notify_type = GDK_NOTIFY_INFERIOR;
8732 send_crossing_event (display, toplevel,
8733 b, GDK_ENTER_NOTIFY,
8738 toplevel_x, toplevel_y,
8745 /* Returns the window inside the event window with the pointer in it
8746 * at the specified coordinates, or NULL if its not in any child of
8747 * the toplevel. It also takes into account !owner_events grabs.
8750 get_pointer_window (GdkDisplay *display,
8751 GdkWindow *event_window,
8757 GdkWindow *pointer_window;
8758 GdkDeviceGrabInfo *grab;
8759 GdkPointerWindowInfo *pointer_info;
8761 pointer_info = _gdk_display_get_pointer_info (display, device);
8763 if (event_window == pointer_info->toplevel_under_pointer)
8765 _gdk_window_find_descendant_at (event_window,
8766 toplevel_x, toplevel_y,
8769 pointer_window = NULL;
8771 grab = _gdk_display_has_device_grab (display, device, serial);
8773 !grab->owner_events &&
8774 pointer_window != grab->window)
8775 pointer_window = NULL;
8777 return pointer_window;
8781 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8785 GdkPointerWindowInfo *device_info;
8787 /* We don't track this if all native, and it can cause issues
8788 with the update_cursor call below */
8789 if (_gdk_native_windows)
8792 device_info = _gdk_display_get_pointer_info (display, device);
8794 if (device_info->window_under_pointer)
8795 g_object_unref (device_info->window_under_pointer);
8796 device_info->window_under_pointer = window;
8800 g_object_ref (window);
8801 update_cursor (display, device);
8804 _gdk_display_enable_motion_hints (display, device);
8809 * @window: the #GdkWindow which will own the grab (the grab window).
8810 * @owner_events: if %FALSE then all pointer events are reported with respect to
8811 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8812 * events for this application are reported as normal, but pointer events outside
8813 * this application are reported with respect to @window and only if selected by
8814 * @event_mask. In either mode, unreported events are discarded.
8815 * @event_mask: specifies the event mask, which is used in accordance with
8816 * @owner_events. Note that only pointer events (i.e. button and motion events)
8818 * @confine_to: If non-%NULL, the pointer will be confined to this
8819 * window during the grab. If the pointer is outside @confine_to, it will
8820 * automatically be moved to the closest edge of @confine_to and enter
8821 * and leave events will be generated as necessary.
8822 * @cursor: the cursor to display while the grab is active. If this is %NULL then
8823 * the normal cursors are used for @window and its descendants, and the cursor
8824 * for @window is used for all other windows.
8825 * @time_: the timestamp of the event which led to this pointer grab. This usually
8826 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8827 * the time isn't known.
8829 * Grabs the pointer (usually a mouse) so that all events are passed to this
8830 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8831 * the grab window becomes unviewable.
8832 * This overrides any previous pointer grab by this client.
8834 * Pointer grabs are used for operations which need complete control over mouse
8835 * events, even if the mouse leaves the application.
8836 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8837 * the #GtkHPaned and #GtkVPaned widgets, and for resizing columns in #GtkCList
8840 * Note that if the event mask of an X window has selected both button press and
8841 * button release events, then a button press event will cause an automatic
8842 * pointer grab until the button is released.
8843 * X does this automatically since most applications expect to receive button
8844 * press and release events in pairs.
8845 * It is equivalent to a pointer grab on the window with @owner_events set to
8848 * If you set up anything at the time you take the grab that needs to be cleaned
8849 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8850 * are emitted when the grab ends unvoluntarily.
8852 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8854 * Deprecated: 3.0: Use gdk_device_grab() instead.
8857 gdk_pointer_grab (GdkWindow * window,
8858 gboolean owner_events,
8859 GdkEventMask event_mask,
8860 GdkWindow * confine_to,
8865 GdkDisplay *display;
8866 GdkDeviceManager *device_manager;
8868 GdkGrabStatus res = 0;
8870 GList *devices, *dev;
8872 g_return_val_if_fail (window != NULL, 0);
8873 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8874 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8876 /* We need a native window for confine to to work, ensure we have one */
8879 if (!gdk_window_ensure_native (confine_to))
8881 g_warning ("Can't confine to grabbed window, not native");
8886 /* Non-viewable client side window => fail */
8887 if (!_gdk_window_has_impl (window) &&
8888 !gdk_window_is_viewable (window))
8889 return GDK_GRAB_NOT_VIEWABLE;
8891 if (_gdk_native_windows)
8894 native = gdk_window_get_toplevel (window);
8895 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
8897 native = gdk_offscreen_window_get_embedder (native);
8899 if (native == NULL ||
8900 (!_gdk_window_has_impl (native) &&
8901 !gdk_window_is_viewable (native)))
8902 return GDK_GRAB_NOT_VIEWABLE;
8904 native = gdk_window_get_toplevel (native);
8907 display = gdk_window_get_display (window);
8909 serial = _gdk_windowing_window_get_next_serial (display);
8910 device_manager = gdk_display_get_device_manager (display);
8911 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8913 /* FIXME: Should this be generic to all backends? */
8914 /* FIXME: What happens with extended devices? */
8915 for (dev = devices; dev; dev = dev->next)
8919 if (device->source != GDK_SOURCE_MOUSE)
8922 res = _gdk_windowing_device_grab (device,
8926 get_native_grab_event_mask (event_mask),
8931 if (res == GDK_GRAB_SUCCESS)
8932 _gdk_display_add_device_grab (display,
8944 /* FIXME: handle errors when grabbing */
8946 g_list_free (devices);
8952 * gdk_keyboard_grab:
8953 * @window: the #GdkWindow which will own the grab (the grab window).
8954 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8955 * @window. If %TRUE then keyboard events for this application are
8956 * reported as normal, but keyboard events outside this application
8957 * are reported with respect to @window. Both key press and key
8958 * release events are always reported, independant of the event mask
8959 * set by the application.
8960 * @time: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8963 * Grabs the keyboard so that all events are passed to this
8964 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8965 * This overrides any previous keyboard grab by this client.
8967 * If you set up anything at the time you take the grab that needs to be cleaned
8968 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8969 * are emitted when the grab ends unvoluntarily.
8971 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8973 * Deprecated: 3.0: Use gdk_device_grab() instead.
8976 gdk_keyboard_grab (GdkWindow *window,
8977 gboolean owner_events,
8981 GdkDisplay *display;
8982 GdkDeviceManager *device_manager;
8984 GdkGrabStatus res = 0;
8986 GList *devices, *dev;
8988 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8990 /* Non-viewable client side window => fail */
8991 if (!_gdk_window_has_impl (window) &&
8992 !gdk_window_is_viewable (window))
8993 return GDK_GRAB_NOT_VIEWABLE;
8995 if (_gdk_native_windows)
8998 native = gdk_window_get_toplevel (window);
9000 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
9002 native = gdk_offscreen_window_get_embedder (native);
9004 if (native == NULL ||
9005 (!_gdk_window_has_impl (native) &&
9006 !gdk_window_is_viewable (native)))
9007 return GDK_GRAB_NOT_VIEWABLE;
9009 native = gdk_window_get_toplevel (native);
9012 display = gdk_window_get_display (window);
9014 serial = _gdk_windowing_window_get_next_serial (display);
9015 device_manager = gdk_display_get_device_manager (display);
9016 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
9018 /* FIXME: Should this be generic to all backends? */
9019 /* FIXME: What happens with extended devices? */
9020 for (dev = devices; dev; dev = dev->next)
9024 if (device->source != GDK_SOURCE_KEYBOARD)
9027 res = _gdk_windowing_device_grab (device,
9031 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
9036 if (res == GDK_GRAB_SUCCESS)
9037 _gdk_display_add_device_grab (display,
9048 /* FIXME: handle errors when grabbing */
9050 g_list_free (devices);
9056 * gdk_window_geometry_changed:
9057 * @window: an embedded offscreen #GdkWindow
9059 * This function informs GDK that the geometry of an embedded
9060 * offscreen window has changed. This is necessary for GDK to keep
9061 * track of which offscreen window the pointer is in.
9066 gdk_window_geometry_changed (GdkWindow *window)
9068 _gdk_synthesize_crossing_events_for_geometry_change (window);
9072 do_synthesize_crossing_event (gpointer data)
9074 GdkDisplay *display;
9075 GdkWindow *changed_toplevel;
9076 GdkWindowObject *changed_toplevel_priv;
9077 GHashTableIter iter;
9078 gpointer key, value;
9081 changed_toplevel = data;
9082 changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
9084 changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
9086 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9089 display = gdk_window_get_display (changed_toplevel);
9090 serial = _gdk_windowing_window_get_next_serial (display);
9091 g_hash_table_iter_init (&iter, display->pointers_info);
9093 while (g_hash_table_iter_next (&iter, &key, &value))
9095 GdkWindow *new_window_under_pointer;
9096 GdkPointerWindowInfo *pointer_info = value;
9097 GdkDevice *device = key;
9099 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9101 new_window_under_pointer =
9102 get_pointer_window (display, changed_toplevel,
9104 pointer_info->toplevel_x,
9105 pointer_info->toplevel_y,
9107 if (new_window_under_pointer != pointer_info->window_under_pointer)
9109 _gdk_synthesize_crossing_events (display,
9110 pointer_info->window_under_pointer,
9111 new_window_under_pointer,
9113 GDK_CROSSING_NORMAL,
9114 pointer_info->toplevel_x,
9115 pointer_info->toplevel_y,
9116 pointer_info->state,
9121 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9130 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9132 GdkDisplay *display;
9133 GdkWindow *toplevel;
9134 GdkWindowObject *toplevel_priv;
9136 if (_gdk_native_windows)
9137 return; /* We use the native crossing events if all native */
9139 display = gdk_window_get_display (changed_window);
9141 toplevel = get_event_toplevel (changed_window);
9142 toplevel_priv = (GdkWindowObject *) toplevel;
9144 if (!toplevel_priv->synthesize_crossing_event_queued)
9146 toplevel_priv->synthesize_crossing_event_queued = TRUE;
9148 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9149 do_synthesize_crossing_event,
9150 g_object_ref (toplevel),
9155 /* Don't use for crossing events */
9157 get_event_window (GdkDisplay *display,
9159 GdkWindow *pointer_window,
9161 GdkModifierType mask,
9166 GdkWindow *grab_window;
9168 GdkDeviceGrabInfo *grab;
9170 grab = _gdk_display_has_device_grab (display, device, serial);
9172 if (grab != NULL && !grab->owner_events)
9174 evmask = grab->event_mask;
9175 evmask = update_evmask_for_button_motion (evmask, mask);
9177 grab_window = grab->window;
9179 if (evmask & type_masks[type])
9182 *evmask_out = evmask;
9189 w = (GdkWindowObject *)pointer_window;
9192 evmask = w->event_mask;
9193 evmask = update_evmask_for_button_motion (evmask, mask);
9195 if (evmask & type_masks[type])
9198 *evmask_out = evmask;
9199 return (GdkWindow *)w;
9202 w = get_event_parent (w);
9208 evmask = grab->event_mask;
9209 evmask = update_evmask_for_button_motion (evmask, mask);
9211 if (evmask & type_masks[type])
9214 *evmask_out = evmask;
9215 return grab->window;
9225 proxy_pointer_event (GdkDisplay *display,
9226 GdkEvent *source_event,
9229 GdkWindow *toplevel_window, *event_window;
9230 GdkWindow *pointer_window;
9231 GdkPointerWindowInfo *pointer_info;
9235 gdouble toplevel_x, toplevel_y;
9237 gboolean non_linear;
9239 event_window = source_event->any.window;
9240 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9241 gdk_event_get_state (source_event, &state);
9242 time_ = gdk_event_get_time (source_event);
9243 device = gdk_event_get_device (source_event);
9244 pointer_info = _gdk_display_get_pointer_info (display, device);
9245 toplevel_window = convert_native_coords_to_toplevel (event_window,
9246 toplevel_x, toplevel_y,
9247 &toplevel_x, &toplevel_y);
9250 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9251 source_event->type == GDK_ENTER_NOTIFY) &&
9252 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9253 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9256 /* If we get crossing events with subwindow unexpectedly being NULL
9257 that means there is a native subwindow that gdk doesn't know about.
9258 We track these and forward them, with the correct virtual window
9260 This is important to get right, as metacity uses gdk for the frame
9261 windows, but gdk doesn't know about the client windows reparented
9263 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9264 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9265 (source_event->type == GDK_ENTER_NOTIFY &&
9266 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9267 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9268 source_event->crossing.subwindow == NULL)
9270 /* Left for an unknown (to gdk) subwindow */
9272 /* Send leave events from window under pointer to event window
9273 that will get the subwindow == NULL window */
9274 _gdk_synthesize_crossing_events (display,
9275 pointer_info->window_under_pointer,
9278 source_event->crossing.mode,
9279 toplevel_x, toplevel_y,
9285 /* Send subwindow == NULL event */
9286 send_crossing_event (display,
9287 (GdkWindowObject *)toplevel_window,
9288 (GdkWindowObject *)event_window,
9290 source_event->crossing.mode,
9291 source_event->crossing.detail,
9294 toplevel_x, toplevel_y,
9299 _gdk_display_set_window_under_pointer (display, device, NULL);
9303 pointer_window = get_pointer_window (display, toplevel_window, device,
9304 toplevel_x, toplevel_y, serial);
9306 if (((source_event->type == GDK_ENTER_NOTIFY &&
9307 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9308 (source_event->type == GDK_LEAVE_NOTIFY &&
9309 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9310 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9311 source_event->crossing.subwindow == NULL)
9313 /* Entered from an unknown (to gdk) subwindow */
9315 /* Send subwindow == NULL event */
9316 send_crossing_event (display,
9317 (GdkWindowObject *)toplevel_window,
9318 (GdkWindowObject *)event_window,
9320 source_event->crossing.mode,
9321 source_event->crossing.detail,
9324 toplevel_x, toplevel_y,
9329 /* Send enter events from event window to pointer_window */
9330 _gdk_synthesize_crossing_events (display,
9334 source_event->crossing.mode,
9335 toplevel_x, toplevel_y,
9338 serial, non_linear);
9339 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9343 if (pointer_info->window_under_pointer != pointer_window)
9345 /* Either a toplevel crossing notify that ended up inside a child window,
9346 or a motion notify that got into another child window */
9348 /* Different than last time, send crossing events */
9349 _gdk_synthesize_crossing_events (display,
9350 pointer_info->window_under_pointer,
9353 GDK_CROSSING_NORMAL,
9354 toplevel_x, toplevel_y,
9357 serial, non_linear);
9358 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9360 else if (source_event->type == GDK_MOTION_NOTIFY)
9362 GdkWindow *event_win;
9366 event_win = get_event_window (display,
9375 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9376 gdk_window_get_device_events (event_win, device) == 0)
9382 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9384 gulong *device_serial;
9386 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9388 if (!device_serial ||
9389 (*device_serial != 0 &&
9390 serial < *device_serial))
9391 event_win = NULL; /* Ignore event */
9395 *device_serial = G_MAXULONG;
9399 if (event_win && !display->ignore_core_events)
9401 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9402 event->motion.time = time_;
9403 convert_toplevel_coords_to_window (event_win,
9404 toplevel_x, toplevel_y,
9405 &event->motion.x, &event->motion.y);
9406 event->motion.x_root = source_event->motion.x_root;
9407 event->motion.y_root = source_event->motion.y_root;
9408 event->motion.state = state;
9409 event->motion.is_hint = is_hint;
9410 event->motion.device = source_event->motion.device;
9411 event->motion.axes = g_memdup (source_event->motion.axes,
9412 sizeof (gdouble) * source_event->motion.device->num_axes);
9416 /* unlink all move events from queue.
9417 We handle our own, including our emulated masks. */
9421 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9422 GDK_BUTTON2_MASK | \
9423 GDK_BUTTON3_MASK | \
9424 GDK_BUTTON4_MASK | \
9428 proxy_button_event (GdkEvent *source_event,
9431 GdkWindow *toplevel_window, *event_window;
9432 GdkWindow *event_win;
9433 GdkWindow *pointer_window;
9434 GdkWindowObject *parent;
9439 gdouble toplevel_x, toplevel_y;
9440 GdkDisplay *display;
9444 type = source_event->any.type;
9445 event_window = source_event->any.window;
9446 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9447 gdk_event_get_state (source_event, &state);
9448 time_ = gdk_event_get_time (source_event);
9449 device = gdk_event_get_device (source_event);
9450 display = gdk_window_get_display (source_event->any.window);
9451 toplevel_window = convert_native_coords_to_toplevel (event_window,
9452 toplevel_x, toplevel_y,
9453 &toplevel_x, &toplevel_y);
9455 if (type == GDK_BUTTON_PRESS &&
9456 !source_event->any.send_event &&
9457 _gdk_display_has_device_grab (display, device, serial) == NULL)
9460 _gdk_window_find_descendant_at (toplevel_window,
9461 toplevel_x, toplevel_y,
9464 /* Find the event window, that gets the grab */
9465 w = (GdkWindowObject *)pointer_window;
9467 (parent = get_event_parent (w)) != NULL &&
9468 parent->window_type != GDK_WINDOW_ROOT)
9470 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9474 pointer_window = (GdkWindow *)w;
9476 _gdk_display_add_device_grab (display,
9482 gdk_window_get_events (pointer_window),
9486 _gdk_display_device_grab_update (display, device, serial);
9489 pointer_window = get_pointer_window (display, toplevel_window, device,
9490 toplevel_x, toplevel_y,
9493 event_win = get_event_window (display,
9499 if (event_win == NULL || display->ignore_core_events)
9502 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9503 gdk_window_get_device_events (event_win, device) == 0)
9506 event = _gdk_make_event (event_win, type, source_event, FALSE);
9510 case GDK_BUTTON_PRESS:
9511 case GDK_BUTTON_RELEASE:
9512 event->button.button = source_event->button.button;
9513 convert_toplevel_coords_to_window (event_win,
9514 toplevel_x, toplevel_y,
9515 &event->button.x, &event->button.y);
9516 event->button.x_root = source_event->button.x_root;
9517 event->button.y_root = source_event->button.y_root;
9518 event->button.state = state;
9519 event->button.device = source_event->button.device;
9520 event->button.axes = g_memdup (source_event->button.axes,
9521 sizeof (gdouble) * source_event->button.device->num_axes);
9523 if (type == GDK_BUTTON_PRESS)
9524 _gdk_event_button_generate (display, event);
9528 event->scroll.direction = source_event->scroll.direction;
9529 convert_toplevel_coords_to_window (event_win,
9530 toplevel_x, toplevel_y,
9531 &event->scroll.x, &event->scroll.y);
9532 event->scroll.x_root = source_event->scroll.x_root;
9533 event->scroll.y_root = source_event->scroll.y_root;
9534 event->scroll.state = state;
9535 event->scroll.device = source_event->scroll.device;
9542 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9545 #ifdef DEBUG_WINDOW_PRINTING
9547 gdk_window_print (GdkWindowObject *window,
9551 const char *window_types[] = {
9561 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9562 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9563 window->x, window->y,
9564 window->width, window->height
9567 if (gdk_window_has_impl (window))
9569 #ifdef GDK_WINDOWING_X11
9570 g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
9574 if (window->window_type != GDK_WINDOW_CHILD)
9575 g_print (" %s", window_types[window->window_type]);
9577 if (window->input_only)
9578 g_print (" input-only");
9581 g_print (" shaped");
9583 if (!gdk_window_is_visible ((GdkWindow *)window))
9584 g_print (" hidden");
9586 g_print (" abs[%d,%d]",
9587 window->abs_x, window->abs_y);
9589 cairo_region_get_extents (window->clip_region, &r);
9590 if (cairo_region_is_empty (window->clip_region))
9591 g_print (" clipbox[empty]");
9593 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9600 gdk_window_print_tree (GdkWindow *window,
9602 gboolean include_input_only)
9604 GdkWindowObject *private;
9607 private = (GdkWindowObject *)window;
9609 if (private->input_only && !include_input_only)
9612 gdk_window_print (private, indent);
9614 for (l = private->children; l != NULL; l = l->next)
9615 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9618 #endif /* DEBUG_WINDOW_PRINTING */
9621 _gdk_windowing_got_event (GdkDisplay *display,
9626 GdkWindow *event_window;
9627 GdkWindowObject *event_private;
9629 gboolean unlink_event;
9630 guint old_state, old_button;
9631 GdkDeviceGrabInfo *button_release_grab;
9632 GdkPointerWindowInfo *pointer_info;
9634 gboolean is_toplevel;
9636 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9637 display->last_event_time = gdk_event_get_time (event);
9639 device = gdk_event_get_device (event);
9645 g_object_get (device, "input-mode", &mode, NULL);
9646 _gdk_display_device_grab_update (display, device, serial);
9648 if (mode == GDK_MODE_DISABLED ||
9649 !_gdk_display_check_grab_ownership (display, device, serial))
9651 /* Device events are blocked by another
9652 * device grab, or the device is disabled
9654 unlink_event = TRUE;
9659 event_window = event->any.window;
9663 pointer_info = _gdk_display_get_pointer_info (display, device);
9664 event_private = GDK_WINDOW_OBJECT (event_window);
9666 #ifdef DEBUG_WINDOW_PRINTING
9667 if (event->type == GDK_KEY_PRESS &&
9668 (event->key.keyval == 0xa7 ||
9669 event->key.keyval == 0xbd))
9671 gdk_window_print_tree (event_window, 0,
9672 event->key.keyval == 0xbd);
9676 if (_gdk_native_windows)
9678 if (event->type == GDK_BUTTON_PRESS &&
9679 !event->any.send_event &&
9680 _gdk_display_has_device_grab (display, device, serial) == NULL)
9682 _gdk_display_add_device_grab (display,
9688 gdk_window_get_events (event_window),
9690 gdk_event_get_time (event),
9692 _gdk_display_device_grab_update (display, device, serial);
9694 if (event->type == GDK_BUTTON_RELEASE &&
9695 !event->any.send_event)
9697 button_release_grab =
9698 _gdk_display_has_device_grab (display, device, serial);
9699 if (button_release_grab &&
9700 button_release_grab->implicit &&
9701 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9703 button_release_grab->serial_end = serial;
9704 button_release_grab->implicit_ungrab = FALSE;
9705 _gdk_display_device_grab_update (display, device, serial);
9709 if (event->type == GDK_BUTTON_PRESS)
9710 _gdk_event_button_generate (display, event);
9715 if (event->type == GDK_VISIBILITY_NOTIFY)
9717 event_private->native_visibility = event->visibility.state;
9718 gdk_window_update_visibility_recursively (event_private,
9723 if (!(is_button_type (event->type) ||
9724 is_motion_type (event->type)) ||
9725 event_private->window_type == GDK_WINDOW_ROOT)
9728 is_toplevel = gdk_window_is_toplevel (event_private);
9730 if ((event->type == GDK_ENTER_NOTIFY ||
9731 event->type == GDK_LEAVE_NOTIFY) &&
9732 (event->crossing.mode == GDK_CROSSING_GRAB ||
9733 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9734 (_gdk_display_has_device_grab (display, device, serial) ||
9735 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9737 /* We synthesize all crossing events due to grabs ourselves,
9738 * so we ignore the native ones caused by our native pointer_grab
9739 * calls. Otherwise we would proxy these crossing event and cause
9740 * multiple copies of crossing events for grabs.
9742 * We do want to handle grabs from other clients though, as for
9743 * instance alt-tab in metacity causes grabs like these and
9744 * we want to handle those. Thus the has_pointer_grab check.
9746 * Implicit grabs on child windows create some grabbing events
9747 * that are sent before the button press. This means we can't
9748 * detect these with the has_pointer_grab check (as the implicit
9749 * grab is only noticed when we get button press event), so we
9750 * detect these events by checking for INFERIOR enter or leave
9751 * events. These should never be a problem to filter out.
9754 /* We ended up in this window after some (perhaps other clients)
9755 grab, so update the toplevel_under_window state */
9757 event->type == GDK_ENTER_NOTIFY &&
9758 event->crossing.mode == GDK_CROSSING_UNGRAB)
9760 if (pointer_info->toplevel_under_pointer)
9761 g_object_unref (pointer_info->toplevel_under_pointer);
9762 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9765 unlink_event = TRUE;
9769 /* Track toplevel_under_pointer */
9772 if (event->type == GDK_ENTER_NOTIFY &&
9773 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9775 if (pointer_info->toplevel_under_pointer)
9776 g_object_unref (pointer_info->toplevel_under_pointer);
9777 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9779 else if (event->type == GDK_LEAVE_NOTIFY &&
9780 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9781 pointer_info->toplevel_under_pointer == event_window)
9783 if (pointer_info->toplevel_under_pointer)
9784 g_object_unref (pointer_info->toplevel_under_pointer);
9785 pointer_info->toplevel_under_pointer = NULL;
9789 /* Store last pointer window and position/state */
9790 old_state = pointer_info->state;
9791 old_button = pointer_info->button;
9793 gdk_event_get_coords (event, &x, &y);
9794 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9795 pointer_info->toplevel_x = x;
9796 pointer_info->toplevel_y = y;
9797 gdk_event_get_state (event, &pointer_info->state);
9798 if (event->type == GDK_BUTTON_PRESS ||
9799 event->type == GDK_BUTTON_RELEASE)
9800 pointer_info->button = event->button.button;
9803 (pointer_info->state != old_state ||
9804 pointer_info->button != old_button))
9805 _gdk_display_enable_motion_hints (display, device);
9807 unlink_event = FALSE;
9808 if (is_motion_type (event->type))
9809 unlink_event = proxy_pointer_event (display,
9812 else if (is_button_type (event->type))
9813 unlink_event = proxy_button_event (event,
9816 if (event->type == GDK_BUTTON_RELEASE &&
9817 !event->any.send_event)
9819 button_release_grab =
9820 _gdk_display_has_device_grab (display, device, serial);
9821 if (button_release_grab &&
9822 button_release_grab->implicit &&
9823 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9825 button_release_grab->serial_end = serial;
9826 button_release_grab->implicit_ungrab = FALSE;
9827 _gdk_display_device_grab_update (display, device, serial);
9834 _gdk_event_queue_remove_link (display, event_link);
9835 g_list_free_1 (event_link);
9836 gdk_event_free (event);
9842 get_extension_event_window (GdkDisplay *display,
9843 GdkWindow *pointer_window,
9848 GdkWindow *grab_window;
9850 GdkDeviceGrabInfo *grab;
9852 /* FIXME: which device? */
9853 grab = _gdk_display_has_device_grab (display, display->core_pointer, serial);
9855 if (grab != NULL && !grab->owner_events)
9857 evmask = grab->event_mask;
9859 grab_window = grab->window;
9861 if (evmask & type_masks[type])
9867 w = (GdkWindowObject *)pointer_window;
9870 evmask = w->extension_events;
9872 if (evmask & type_masks[type])
9873 return (GdkWindow *)w;
9875 w = get_event_parent (w);
9881 evmask = grab->event_mask;
9883 if (evmask & type_masks[type])
9884 return grab->window;
9894 _gdk_window_get_input_window_for_event (GdkWindow *native_window,
9895 GdkEventType event_type,
9899 GdkDisplay *display;
9900 GdkWindow *toplevel_window;
9901 GdkWindow *pointer_window;
9902 GdkWindow *event_win;
9903 gdouble toplevel_x, toplevel_y;
9908 display = gdk_window_get_display (native_window);
9909 toplevel_window = convert_native_coords_to_toplevel (native_window,
9910 toplevel_x, toplevel_y,
9911 &toplevel_x, &toplevel_y);
9912 /* FIXME: which device? */
9913 pointer_window = get_pointer_window (display, toplevel_window, NULL,
9914 toplevel_x, toplevel_y, serial);
9915 event_win = get_extension_event_window (display,
9924 * gdk_window_create_similar_surface:
9925 * @window: window to make new surface similar to
9926 * @content: the content for the new surface
9927 * @width: width of the new surface
9928 * @height: height of the new surface
9930 * Create a new surface that is as compatible as possible with the
9931 * given @window. For example the new surface will have the same
9932 * fallback resolution and font options as @window. Generally, the new
9933 * surface will also use the same backend as @window, unless that is
9934 * not possible for some reason. The type of the returned surface may
9935 * be examined with cairo_surface_get_type().
9937 * Initially the surface contents are all 0 (transparent if contents
9938 * have transparency, black otherwise.)
9940 * Returns: a pointer to the newly allocated surface. The caller
9941 * owns the surface and should call cairo_surface_destroy() when done
9944 * This function always returns a valid pointer, but it will return a
9945 * pointer to a "nil" surface if @other is already in an error state
9946 * or any other error occurs.
9951 gdk_window_create_similar_surface (GdkWindow * window,
9952 cairo_content_t content,
9956 cairo_surface_t *window_surface, *surface;
9958 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9960 window_surface = _gdk_drawable_ref_cairo_surface (window);
9962 surface = cairo_surface_create_similar (window_surface,
9966 cairo_surface_destroy (window_surface);