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 "gdkwindow.h"
32 #ifdef GDK_WINDOWING_X11
33 #include "x11/gdkx.h" /* For workaround */
37 #include "gdk.h" /* For gdk_rectangle_union() */
38 #include "gdkinternals.h"
40 #include "gdkscreen.h"
41 #include "gdkdeviceprivate.h"
42 #include "gdkdrawable.h"
43 #include "gdkmarshalers.h"
44 #include "gdkscreen.h"
45 #include "gdkwindowimpl.h"
47 #undef DEBUG_WINDOW_PRINTING
52 * @Short_description: Onscreen display areas in the target window system
55 * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
56 * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
57 * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
58 * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
59 * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
62 * <refsect2 id="COMPOSITED-WINDOWS">
63 * <title>Composited Windows</title>
65 * Normally, the windowing system takes care of rendering the contents of a
66 * child window onto its parent window. This mechanism can be intercepted by
67 * calling gdk_window_set_composited() on the child window. For a
68 * <firstterm>composited</firstterm> window it is the responsibility of the
69 * application to render the window contents at the right spot.
71 * <example id="composited-window-example">
72 * <title>Composited windows</title>
74 * <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>
75 * </programlisting></example>
77 * In the example <xref linkend="composited-window-example"/>, a button is
78 * placed inside of an event box inside of a window. The event box is set as
79 * composited and therefore is no longer automatically drawn to the screen.
81 * When the contents of the event box change, an expose event is generated on
82 * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
83 * The expose handler for this widget is responsible for merging the changes
84 * back on the screen in the way that it wishes.
86 * In our case, we merge the contents with a 50% transparency. We also set the
87 * background colour of the window to red. The effect is that the background
88 * shows through the button.
91 * <refsect2 id="OFFSCREEN-WINDOWS">
92 * <title>Offscreen Windows</title>
94 * Offscreen windows are more general than composited windows, since they allow
95 * not only to modify the rendering of the child window onto its parent, but
96 * also to apply coordinate transformations.
98 * To integrate an offscreen window into a window hierarchy, one has to call
99 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
100 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
101 * select an offscreen child at given coordinates, and the
102 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
103 * offscreen window are used to translate coordinates between the embedder and
104 * the offscreen window.
106 * For rendering an offscreen window onto its embedder, the contents of the
107 * offscreen window are available as a surface, via
108 * gdk_offscreen_window_get_surface().
114 /* Historically a GdkWindow always matches a platform native window,
115 * be it a toplevel window or a child window. In this setup the
116 * GdkWindow (and other GdkDrawables) were platform independent classes,
117 * and the actual platform specific implementation was in a delegate
118 * object availible as "impl" in the window object.
120 * With the addition of client side windows and offscreen windows this
121 * changes a bit. The application-visible GdkWindow object behaves as
122 * it did before, but not all such windows now have a corresponding native
123 * window. Instead windows that are "client side" are emulated by the gdk
124 * code such that clipping, drawing, moving, events etc work as expected.
126 * For GdkWindows that have a native window the "impl" object is the
127 * same as before. However, for all client side windows the impl object
128 * is shared with its parent (i.e. all client windows descendants of one
129 * native window has the same impl.
131 * Additionally there is a new type of platform independent impl object,
132 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
133 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
134 * windows). Such windows work by allocating a #cairo_surface_t as the backing
135 * store for drawing operations, which is resized with the window.
137 * GdkWindows have a pointer to the "impl window" they are in, i.e.
138 * the topmost GdkWindow which have the same "impl" value. This is stored
139 * in impl_window, which is different from the window itself only for client
141 * All GdkWindows (native or not) track the position of the window in the parent
142 * (x, y), the size of the window (width, height), the position of the window
143 * with respect to the impl window (abs_x, abs_y). We also track the clip
144 * region of the window wrt parent windows and siblings, in window-relative
145 * coordinates with and without child windows included (clip_region,
146 * clip_region_with_children).
148 * All toplevel windows are native windows, but also child windows can be
149 * native (although not children of offscreens). We always listen to
150 * a basic set of events (see get_native_event_mask) for these windows
151 * so that we can emulate events for any client side children.
153 * For native windows we apply the calculated clip region as a window shape
154 * so that eg. client side siblings that overlap the native child properly
155 * draws over the native child window.
157 * In order to minimize flicker and for performance we use a couple of cacheing
158 * tricks. First of all, every time we do a window to window copy area, for instance
159 * when moving a client side window or when scrolling/moving a region in a window
160 * we store this in outstanding_moves instead of applying immediately. We then
161 * delay this move until we really need it (because something depends on being
162 * able to read it), or until we're handing a redraw from an expose/invalidation
163 * (actually we delay it past redraw, but before blitting the double buffer
164 * to the window). This gives us two advantages. First of all it minimizes the time
165 * from the window is moved to the exposes related to that move, secondly it allows
166 * us to be smart about how to do the copy. We combine multiple moves into one (when
167 * possible) and we don't actually do copies to anything that is or will be
168 * invalidated and exposed anyway.
170 * Secondly, we use something called a "implicit paint" during repaint handling.
171 * An implicit paint is similar to a regular paint for the paint stack, but it is
172 * not put on the stack. Instead, it is set on the impl window, and later when
173 * regular gdk_window_begin_paint_region() happen on a window of this impl window
174 * we reuse the surface from the implicit paint. During repaint we create and at the
175 * end flush an implicit paint, which means we can collect all the paints on
176 * multiple client side windows in the same backing store.
179 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
181 /* This adds a local value to the GdkVisibilityState enum */
182 #define GDK_VISIBILITY_NOT_VIEWABLE 3
185 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
198 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
202 struct _GdkWindowPaint
204 cairo_region_t *region;
205 cairo_surface_t *surface;
206 guint uses_implicit : 1;
212 cairo_region_t *dest_region; /* The destination region */
213 int dx, dy; /* The amount that the source was moved to reach dest_region */
214 } GdkWindowRegionMove;
218 static cairo_surface_t *gdk_window_ref_cairo_surface (GdkDrawable *drawable);
219 static cairo_surface_t *gdk_window_create_cairo_surface (GdkDrawable *drawable,
222 static void gdk_window_drop_cairo_surface (GdkWindowObject *private);
223 static void gdk_window_set_cairo_clip (GdkDrawable *drawable,
226 static void gdk_window_real_get_size (GdkDrawable *drawable,
230 static cairo_region_t* gdk_window_get_clip_region (GdkDrawable *drawable);
231 static cairo_region_t* gdk_window_get_visible_region (GdkDrawable *drawable);
233 static void gdk_window_free_paint_stack (GdkWindow *window);
235 static void gdk_window_init (GdkWindowObject *window);
236 static void gdk_window_class_init (GdkWindowObjectClass *klass);
237 static void gdk_window_finalize (GObject *object);
239 static void gdk_window_set_property (GObject *object,
243 static void gdk_window_get_property (GObject *object,
248 static void gdk_window_clear_backing_region (GdkWindow *window,
249 cairo_region_t *region);
251 static void recompute_visible_regions (GdkWindowObject *private,
252 gboolean recalculate_siblings,
253 gboolean recalculate_children);
254 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
255 static void gdk_window_flush_recursive (GdkWindowObject *window);
256 static void do_move_region_bits_on_impl (GdkWindowObject *private,
257 cairo_region_t *region, /* In impl window coords */
259 static void gdk_window_invalidate_in_parent (GdkWindowObject *private);
260 static void move_native_children (GdkWindowObject *private);
261 static void update_cursor (GdkDisplay *display,
263 static void impl_window_add_update_area (GdkWindowObject *impl_window,
264 cairo_region_t *region);
265 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
266 static void gdk_window_invalidate_region_full (GdkWindow *window,
267 const cairo_region_t *region,
268 gboolean invalidate_children,
270 static void gdk_window_invalidate_rect_full (GdkWindow *window,
271 const GdkRectangle *rect,
272 gboolean invalidate_children,
275 static guint signals[LAST_SIGNAL] = { 0 };
277 static gpointer parent_class = NULL;
279 static const cairo_user_data_key_t gdk_window_cairo_key;
282 new_region_tag (void)
284 static guint32 tag = 0;
290 gdk_window_object_get_type (void)
292 static GType object_type = 0;
295 object_type = g_type_register_static_simple (GDK_TYPE_DRAWABLE,
297 sizeof (GdkWindowObjectClass),
298 (GClassInitFunc) gdk_window_class_init,
299 sizeof (GdkWindowObject),
300 (GInstanceInitFunc) gdk_window_init,
307 _gdk_paintable_get_type (void)
309 static GType paintable_type = 0;
313 const GTypeInfo paintable_info =
315 sizeof (GdkPaintableIface), /* class_size */
316 NULL, /* base_init */
317 NULL, /* base_finalize */
320 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
321 g_intern_static_string ("GdkPaintable"),
324 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
327 return paintable_type;
331 gdk_window_init (GdkWindowObject *window)
333 /* 0-initialization is good for all other fields. */
335 window->window_type = GDK_WINDOW_CHILD;
337 window->state = GDK_WINDOW_STATE_WITHDRAWN;
340 window->toplevel_window_type = -1;
342 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
343 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
344 /* Default to unobscured since some backends don't send visibility events */
345 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
348 /* Stop and return on the first non-NULL parent */
350 accumulate_get_window (GSignalInvocationHint *ihint,
352 const GValue *handler_return,
355 g_value_copy (handler_return, return_accu);
356 /* Continue while returning NULL */
357 return g_value_get_object (handler_return) == NULL;
360 static GQuark quark_pointer_window = 0;
363 gdk_window_class_init (GdkWindowObjectClass *klass)
365 GObjectClass *object_class = G_OBJECT_CLASS (klass);
366 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
368 parent_class = g_type_class_peek_parent (klass);
370 object_class->finalize = gdk_window_finalize;
371 object_class->set_property = gdk_window_set_property;
372 object_class->get_property = gdk_window_get_property;
374 drawable_class->get_size = gdk_window_real_get_size;
375 drawable_class->ref_cairo_surface = gdk_window_ref_cairo_surface;
376 drawable_class->create_cairo_surface = gdk_window_create_cairo_surface;
377 drawable_class->set_cairo_clip = gdk_window_set_cairo_clip;
378 drawable_class->get_clip_region = gdk_window_get_clip_region;
379 drawable_class->get_visible_region = gdk_window_get_visible_region;
381 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
389 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
390 * gdk_window_get_cursor() for details.
394 g_object_class_install_property (object_class,
396 g_param_spec_boxed ("cursor",
403 * GdkWindow::pick-embedded-child:
404 * @window: the window on which the signal is emitted
405 * @x: x coordinate in the window
406 * @y: y coordinate in the window
408 * The ::pick-embedded-child signal is emitted to find an embedded
409 * child at the given position.
411 * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
415 signals[PICK_EMBEDDED_CHILD] =
416 g_signal_new (g_intern_static_string ("pick-embedded-child"),
417 G_OBJECT_CLASS_TYPE (object_class),
420 accumulate_get_window, NULL,
421 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
428 * GdkWindow::to-embedder:
429 * @window: the offscreen window on which the signal is emitted
430 * @offscreen-x: x coordinate in the offscreen window
431 * @offscreen-y: y coordinate in the offscreen window
432 * @embedder-x: return location for the x coordinate in the embedder window
433 * @embedder-y: return location for the y coordinate in the embedder window
435 * The ::to-embedder signal is emitted to translate coordinates
436 * in an offscreen window to its embedder.
438 * See also #GtkWindow::from-embedder.
442 signals[TO_EMBEDDER] =
443 g_signal_new (g_intern_static_string ("to-embedder"),
444 G_OBJECT_CLASS_TYPE (object_class),
448 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
457 * GdkWindow::from-embedder:
458 * @window: the offscreen window on which the signal is emitted
459 * @embedder-x: x coordinate in the embedder window
460 * @embedder-y: y coordinate in the embedder window
461 * @offscreen-x: return location for the x coordinate in the offscreen window
462 * @offscreen-y: return location for the y coordinate in the offscreen window
464 * The ::from-embedder signal is emitted to translate coordinates
465 * in the embedder of an offscreen window to the offscreen window.
467 * See also #GtkWindow::to-embedder.
471 signals[FROM_EMBEDDER] =
472 g_signal_new (g_intern_static_string ("from-embedder"),
473 G_OBJECT_CLASS_TYPE (object_class),
477 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
487 device_removed_cb (GdkDeviceManager *device_manager,
491 GdkWindowObject *private;
493 private = (GdkWindowObject *) window;
495 private->devices_inside = g_list_remove (private->devices_inside, device);
496 g_hash_table_remove (private->device_cursor, device);
498 if (private->device_events)
499 g_hash_table_remove (private->device_events, device);
503 gdk_window_finalize (GObject *object)
505 GdkWindow *window = GDK_WINDOW (object);
506 GdkWindowObject *obj = (GdkWindowObject *) object;
507 GdkDeviceManager *device_manager;
509 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
510 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
512 if (!GDK_WINDOW_DESTROYED (window))
514 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
516 g_warning ("losing last reference to undestroyed window\n");
517 _gdk_window_destroy (window, FALSE);
520 /* We use TRUE here, to keep us from actually calling
521 * XDestroyWindow() on the window
523 _gdk_window_destroy (window, TRUE);
526 gdk_window_drop_cairo_surface (obj);
530 g_object_unref (obj->impl);
534 if (obj->impl_window != obj)
536 g_object_unref (obj->impl_window);
537 obj->impl_window = NULL;
541 cairo_region_destroy (obj->shape);
543 if (obj->input_shape)
544 cairo_region_destroy (obj->input_shape);
547 gdk_cursor_unref (obj->cursor);
549 if (obj->device_cursor)
550 g_hash_table_destroy (obj->device_cursor);
552 if (obj->device_events)
553 g_hash_table_destroy (obj->device_events);
555 if (obj->devices_inside)
556 g_list_free (obj->devices_inside);
558 G_OBJECT_CLASS (parent_class)->finalize (object);
562 gdk_window_set_property (GObject *object,
567 GdkWindow *window = (GdkWindow *)object;
572 gdk_window_set_cursor (window, g_value_get_boxed (value));
576 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
582 gdk_window_get_property (GObject *object,
587 GdkWindow *window = (GdkWindow *) object;
592 g_value_set_boxed (value, gdk_window_get_cursor (window));
596 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
602 gdk_window_is_offscreen (GdkWindowObject *window)
604 return window->window_type == GDK_WINDOW_OFFSCREEN;
607 static GdkWindowObject *
608 gdk_window_get_impl_window (GdkWindowObject *window)
610 return window->impl_window;
614 _gdk_window_get_impl_window (GdkWindow *window)
616 return (GdkWindow *)gdk_window_get_impl_window ((GdkWindowObject *)window);
620 gdk_window_has_impl (GdkWindowObject *window)
622 return window->impl_window == window;
626 gdk_window_is_toplevel (GdkWindowObject *window)
629 window->parent == NULL ||
630 window->parent->window_type == GDK_WINDOW_ROOT;
634 _gdk_window_has_impl (GdkWindow *window)
636 return gdk_window_has_impl ((GdkWindowObject *)window);
640 gdk_window_has_no_impl (GdkWindowObject *window)
642 return window->impl_window != window;
646 remove_child_area (GdkWindowObject *private,
647 GdkWindowObject *until,
649 cairo_region_t *region)
651 GdkWindowObject *child;
652 cairo_region_t *child_region;
655 cairo_region_t *shape;
657 for (l = private->children; l; l = l->next)
664 /* If region is empty already, no need to do
665 anything potentially costly */
666 if (cairo_region_is_empty (region))
669 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
672 /* Ignore offscreen children, as they don't draw in their parent and
673 * don't take part in the clipping */
674 if (gdk_window_is_offscreen (child))
679 r.width = child->width;
680 r.height = child->height;
682 /* Bail early if child totally outside region */
683 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
686 child_region = cairo_region_create_rectangle (&r);
690 /* Adjust shape region to parent window coords */
691 cairo_region_translate (child->shape, child->x, child->y);
692 cairo_region_intersect (child_region, child->shape);
693 cairo_region_translate (child->shape, -child->x, -child->y);
695 else if (private->window_type == GDK_WINDOW_FOREIGN)
697 shape = _gdk_windowing_window_get_shape ((GdkWindow *)child);
700 cairo_region_intersect (child_region, shape);
701 cairo_region_destroy (shape);
707 if (child->input_shape)
708 cairo_region_intersect (child_region, child->input_shape);
709 else if (private->window_type == GDK_WINDOW_FOREIGN)
711 shape = _gdk_windowing_window_get_input_shape ((GdkWindow *)child);
714 cairo_region_intersect (child_region, shape);
715 cairo_region_destroy (shape);
720 cairo_region_subtract (region, child_region);
721 cairo_region_destroy (child_region);
726 static GdkVisibilityState
727 effective_visibility (GdkWindowObject *private)
729 GdkVisibilityState native;
731 if (!gdk_window_is_viewable ((GdkWindow *)private))
732 return GDK_VISIBILITY_NOT_VIEWABLE;
734 native = private->impl_window->native_visibility;
736 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
737 private->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
738 return GDK_VISIBILITY_FULLY_OBSCURED;
739 else if (native == GDK_VISIBILITY_UNOBSCURED)
740 return private->visibility;
741 else /* native PARTIAL, private partial or unobscured */
742 return GDK_VISIBILITY_PARTIAL;
746 gdk_window_update_visibility (GdkWindowObject *private)
748 GdkVisibilityState new_visibility;
751 new_visibility = effective_visibility (private);
753 if (new_visibility != private->effective_visibility)
755 private->effective_visibility = new_visibility;
757 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
758 private->event_mask & GDK_VISIBILITY_NOTIFY)
760 event = _gdk_make_event ((GdkWindow *)private, GDK_VISIBILITY_NOTIFY,
762 event->visibility.state = new_visibility;
768 gdk_window_update_visibility_recursively (GdkWindowObject *private,
769 GdkWindowObject *only_for_impl)
771 GdkWindowObject *child;
774 gdk_window_update_visibility (private);
775 for (l = private->children; l != NULL; l = l->next)
778 if ((only_for_impl == NULL) ||
779 (only_for_impl == child->impl_window))
780 gdk_window_update_visibility_recursively (child, only_for_impl);
785 should_apply_clip_as_shape (GdkWindowObject *private)
788 gdk_window_has_impl (private) &&
789 /* Not for offscreens */
790 !gdk_window_is_offscreen (private) &&
791 /* or for toplevels */
792 !gdk_window_is_toplevel (private) &&
793 /* or for foreign windows */
794 private->window_type != GDK_WINDOW_FOREIGN &&
795 /* or for the root window */
796 private->window_type != GDK_WINDOW_ROOT;
800 apply_shape (GdkWindowObject *private,
801 cairo_region_t *region)
803 GdkWindowImplIface *impl_iface;
805 /* We trash whether we applied a shape so that
806 we can avoid unsetting it many times, which
807 could happen in e.g. apply_clip_as_shape as
808 windows get resized */
809 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
811 impl_iface->shape_combine_region ((GdkWindow *)private,
813 else if (private->applied_shape)
814 impl_iface->shape_combine_region ((GdkWindow *)private,
817 private->applied_shape = region != NULL;
821 region_rect_equal (const cairo_region_t *region,
822 const GdkRectangle *rect)
824 GdkRectangle extents;
826 if (cairo_region_num_rectangles (region) != 1)
829 cairo_region_get_extents (region, &extents);
831 return extents.x == rect->x &&
832 extents.y == rect->y &&
833 extents.width == rect->width &&
834 extents.height == rect->height;
838 apply_clip_as_shape (GdkWindowObject *private)
843 r.width = private->width;
844 r.height = private->height;
846 /* We only apply the clip region if would differ
847 from the actual clip region implied by the size
848 of the window. This is to avoid unneccessarily
849 adding meaningless shapes to all native subwindows */
850 if (!region_rect_equal (private->clip_region, &r))
851 apply_shape (private, private->clip_region);
853 apply_shape (private, NULL);
857 recompute_visible_regions_internal (GdkWindowObject *private,
858 gboolean recalculate_clip,
859 gboolean recalculate_siblings,
860 gboolean recalculate_children)
864 GdkWindowObject *child;
865 cairo_region_t *new_clip, *old_clip_region_with_children;
866 gboolean clip_region_changed;
867 gboolean abs_pos_changed;
868 int old_abs_x, old_abs_y;
870 old_abs_x = private->abs_x;
871 old_abs_y = private->abs_y;
873 /* Update absolute position */
874 if (gdk_window_has_impl (private))
876 /* Native window starts here */
882 private->abs_x = private->parent->abs_x + private->x;
883 private->abs_y = private->parent->abs_y + private->y;
887 private->abs_x != old_abs_x ||
888 private->abs_y != old_abs_y;
890 /* Update clip region based on:
893 * siblings in parents above window
895 clip_region_changed = FALSE;
896 if (recalculate_clip)
898 if (private->viewable)
900 /* Calculate visible region (sans children) in parent window coords */
903 r.width = private->width;
904 r.height = private->height;
905 new_clip = cairo_region_create_rectangle (&r);
907 if (!gdk_window_is_toplevel (private))
909 cairo_region_intersect (new_clip, private->parent->clip_region);
911 /* Remove all overlapping children from parent.
912 * Unless we're all native, because then we don't need to take
913 * siblings into account since X does that clipping for us.
914 * This makes things like SWT that modify the raw X stacking
915 * order without GDKs knowledge work.
917 if (!_gdk_native_windows)
918 remove_child_area (private->parent, private, FALSE, new_clip);
921 /* Convert from parent coords to window coords */
922 cairo_region_translate (new_clip, -private->x, -private->y);
925 cairo_region_intersect (new_clip, private->shape);
928 new_clip = cairo_region_create ();
930 if (private->clip_region == NULL ||
931 !cairo_region_equal (private->clip_region, new_clip))
932 clip_region_changed = TRUE;
934 if (private->clip_region)
935 cairo_region_destroy (private->clip_region);
936 private->clip_region = new_clip;
938 old_clip_region_with_children = private->clip_region_with_children;
939 private->clip_region_with_children = cairo_region_copy (private->clip_region);
940 if (private->window_type != GDK_WINDOW_ROOT)
941 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
943 if (clip_region_changed ||
944 !cairo_region_equal (private->clip_region_with_children, old_clip_region_with_children))
945 private->clip_tag = new_region_tag ();
947 if (old_clip_region_with_children)
948 cairo_region_destroy (old_clip_region_with_children);
951 if (clip_region_changed)
953 GdkVisibilityState visibility;
954 gboolean fully_visible;
956 if (cairo_region_is_empty (private->clip_region))
957 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
962 fully_visible = cairo_region_equal (private->clip_region,
969 r.width = private->width;
970 r.height = private->height;
971 fully_visible = region_rect_equal (private->clip_region, &r);
975 visibility = GDK_VISIBILITY_UNOBSCURED;
977 visibility = GDK_VISIBILITY_PARTIAL;
980 if (private->visibility != visibility)
982 private->visibility = visibility;
983 gdk_window_update_visibility (private);
987 /* Update all children, recursively (except for root, where children are not exact). */
988 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
989 private->window_type != GDK_WINDOW_ROOT)
991 for (l = private->children; l; l = l->next)
994 /* Only recalculate clip if the the clip region changed, otherwise
995 * there is no way the child clip region could change (its has not e.g. moved)
996 * Except if recalculate_children is set to force child updates
998 recompute_visible_regions_internal (child,
999 recalculate_clip && (clip_region_changed || recalculate_children),
1004 if (clip_region_changed &&
1005 should_apply_clip_as_shape (private))
1006 apply_clip_as_shape (private);
1008 if (recalculate_siblings &&
1009 !gdk_window_is_toplevel (private))
1011 /* If we moved a child window in parent or changed the stacking order, then we
1012 * need to recompute the visible area of all the other children in the parent
1014 for (l = private->parent->children; l; l = l->next)
1018 if (child != private)
1019 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1022 /* We also need to recompute the _with_children clip for the parent */
1023 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1026 if (private->cairo_surface &&
1027 (!gdk_window_has_impl (private) ||
1028 !_gdk_windowing_set_cairo_surface_size (private->cairo_surface,
1032 gdk_window_drop_cairo_surface (private);
1036 /* Call this when private has changed in one or more of these ways:
1040 * stacking order of window changed
1043 * It will recalculate abs_x/y and the clip regions
1045 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1046 * for recalculate_siblings. (Mostly used internally for the recursion)
1048 * If a child window was removed (and you can't use that child for
1049 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1052 recompute_visible_regions (GdkWindowObject *private,
1053 gboolean recalculate_siblings,
1054 gboolean recalculate_children)
1056 recompute_visible_regions_internal (private,
1058 recalculate_siblings,
1059 recalculate_children);
1063 _gdk_window_update_size (GdkWindow *window)
1065 recompute_visible_regions ((GdkWindowObject *)window, TRUE, FALSE);
1068 /* Find the native window that would be just above "child"
1069 * in the native stacking order if "child" was a native window
1070 * (it doesn't have to be native). If there is no such native
1071 * window inside this native parent then NULL is returned.
1072 * If child is NULL, find lowest native window in parent.
1074 static GdkWindowObject *
1075 find_native_sibling_above_helper (GdkWindowObject *parent,
1076 GdkWindowObject *child)
1083 l = g_list_find (parent->children, child);
1084 g_assert (l != NULL); /* Better be a child of its parent... */
1085 l = l->prev; /* Start looking at the one above the child */
1088 l = g_list_last (parent->children);
1090 for (; l != NULL; l = l->prev)
1094 if (gdk_window_has_impl (w))
1097 g_assert (parent != w);
1098 w = find_native_sibling_above_helper (w, NULL);
1107 static GdkWindowObject *
1108 find_native_sibling_above (GdkWindowObject *parent,
1109 GdkWindowObject *child)
1113 w = find_native_sibling_above_helper (parent, child);
1117 if (gdk_window_has_impl (parent))
1120 return find_native_sibling_above (parent->parent, parent);
1124 get_native_device_event_mask (GdkWindowObject *private,
1127 GdkEventMask event_mask;
1130 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1132 event_mask = private->event_mask;
1134 if (_gdk_native_windows ||
1135 private->window_type == GDK_WINDOW_ROOT ||
1136 private->window_type == GDK_WINDOW_FOREIGN)
1142 /* Do whatever the app asks to, since the app
1143 * may be asking for weird things for native windows,
1144 * but don't use motion hints as that may affect non-native
1145 * child windows that don't want it. Also, we need to
1146 * set all the app-specified masks since they will be picked
1147 * up by any implicit grabs (i.e. if they were not set as
1148 * native we would not get the events we need). */
1149 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1151 /* We need thse for all native windows so we can
1152 emulate events on children: */
1155 GDK_VISIBILITY_NOTIFY_MASK |
1156 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1158 /* Additionally we select for pointer and button events
1159 * for toplevels as we need to get these to emulate
1160 * them for non-native subwindows. Even though we don't
1161 * select on them for all native windows we will get them
1162 * as the events are propagated out to the first window
1163 * that select for them.
1164 * Not selecting for button press on all windows is an
1165 * important thing, because in X only one client can do
1166 * so, and we don't want to unexpectedly prevent another
1167 * client from doing it.
1169 * We also need to do the same if the app selects for button presses
1170 * because then we will get implicit grabs for this window, and the
1171 * event mask used for that grab is based on the rest of the mask
1172 * for the window, but we might need more events than this window
1173 * lists due to some non-native child window.
1175 if (gdk_window_is_toplevel (private) ||
1176 mask & GDK_BUTTON_PRESS_MASK)
1178 GDK_POINTER_MOTION_MASK |
1179 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1187 get_native_grab_event_mask (GdkEventMask grab_mask)
1189 /* Similar to the above but for pointer events only */
1191 GDK_POINTER_MOTION_MASK |
1192 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1193 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1196 ~GDK_POINTER_MOTION_HINT_MASK);
1200 get_native_event_mask (GdkWindowObject *private)
1202 return get_native_device_event_mask (private, NULL);
1205 /* Puts the native window in the right order wrt the other native windows
1206 * in the hierarchy, given the position it has in the client side data.
1207 * This is useful if some operation changed the stacking order.
1208 * This calls assumes the native window is now topmost in its native parent.
1211 sync_native_window_stack_position (GdkWindow *window)
1213 GdkWindowObject *above;
1214 GdkWindowObject *private;
1215 GdkWindowImplIface *impl_iface;
1216 GList listhead = {0};
1218 private = (GdkWindowObject *) window;
1219 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1221 above = find_native_sibling_above (private->parent, private);
1224 listhead.data = window;
1225 impl_iface->restack_under ((GdkWindow *)above,
1232 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1233 * the default root window for the default display.
1234 * @attributes: attributes of the new window
1235 * @attributes_mask: mask indicating which fields in @attributes are valid
1237 * Creates a new #GdkWindow using the attributes from
1238 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1239 * more details. Note: to use this on displays other than the default
1240 * display, @parent must be specified.
1242 * Return value: (transfer none): the new #GdkWindow
1245 gdk_window_new (GdkWindow *parent,
1246 GdkWindowAttr *attributes,
1247 gint attributes_mask)
1250 GdkWindowObject *private;
1254 GdkEventMask event_mask;
1255 GdkWindow *real_parent;
1256 GdkDeviceManager *device_manager;
1258 g_return_val_if_fail (attributes != NULL, NULL);
1262 GDK_NOTE (MULTIHEAD,
1263 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1265 screen = gdk_screen_get_default ();
1266 parent = gdk_screen_get_root_window (screen);
1269 screen = gdk_window_get_screen (parent);
1271 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1273 if (GDK_WINDOW_DESTROYED (parent))
1275 g_warning ("gdk_window_new(): parent is destroyed\n");
1279 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1280 _gdk_native_windows)
1282 g_warning ("Offscreen windows not supported with native-windows gdk");
1286 window = g_object_new (GDK_TYPE_WINDOW, NULL);
1287 private = (GdkWindowObject *) window;
1289 /* Windows with a foreign parent are treated as if they are children
1290 * of the root window, except for actual creation.
1292 real_parent = parent;
1293 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1294 parent = gdk_screen_get_root_window (screen);
1296 private->parent = (GdkWindowObject *)parent;
1298 private->accept_focus = TRUE;
1299 private->focus_on_map = TRUE;
1301 if (attributes_mask & GDK_WA_X)
1306 if (attributes_mask & GDK_WA_Y)
1313 private->width = (attributes->width > 1) ? (attributes->width) : (1);
1314 private->height = (attributes->height > 1) ? (attributes->height) : (1);
1316 #ifdef GDK_WINDOWING_X11
1317 /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1318 * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1320 if (attributes->wclass == GDK_INPUT_ONLY &&
1321 private->parent->window_type == GDK_WINDOW_ROOT &&
1322 !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1324 g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1325 attributes->wclass = GDK_INPUT_OUTPUT;
1329 if (attributes->wclass == GDK_INPUT_ONLY)
1331 /* Backwards compatiblity - we've always ignored
1332 * attributes->window_type for input-only windows
1335 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1336 private->window_type = GDK_WINDOW_TEMP;
1338 private->window_type = GDK_WINDOW_CHILD;
1341 private->window_type = attributes->window_type;
1344 switch (private->window_type)
1346 case GDK_WINDOW_TOPLEVEL:
1347 case GDK_WINDOW_TEMP:
1348 case GDK_WINDOW_OFFSCREEN:
1349 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1350 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1351 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1352 case GDK_WINDOW_CHILD:
1356 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
1360 if (attributes_mask & GDK_WA_VISUAL)
1361 private->visual = attributes->visual;
1363 private->visual = gdk_screen_get_system_visual (screen);
1365 private->event_mask = attributes->event_mask;
1367 if (attributes->wclass == GDK_INPUT_OUTPUT)
1369 private->input_only = FALSE;
1370 private->depth = private->visual->depth;
1372 /* XXX: Cache this somehow? */
1373 private->background = cairo_pattern_create_rgb (0, 0, 0);
1378 private->input_only = TRUE;
1381 if (private->parent)
1382 private->parent->children = g_list_prepend (private->parent->children, window);
1384 native = _gdk_native_windows; /* Default */
1385 if (private->parent->window_type == GDK_WINDOW_ROOT)
1386 native = TRUE; /* Always use native windows for toplevels */
1387 else if (!private->input_only &&
1388 (attributes_mask & GDK_WA_VISUAL &&
1389 attributes->visual != gdk_window_get_visual (GDK_WINDOW (private->parent))))
1390 native = TRUE; /* InputOutput window with different visual than parent, needs native window */
1392 if (gdk_window_is_offscreen (private))
1394 _gdk_offscreen_window_new (window, screen, attributes, attributes_mask);
1395 private->impl_window = private;
1399 event_mask = get_native_event_mask (private);
1401 /* Create the impl */
1402 _gdk_window_impl_new (window, real_parent, screen, event_mask, attributes, attributes_mask);
1403 private->impl_window = private;
1405 /* This will put the native window topmost in the native parent, which may
1406 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1407 if (!_gdk_window_has_impl (real_parent))
1408 sync_native_window_stack_position (window);
1412 private->impl_window = g_object_ref (private->parent->impl_window);
1413 private->impl = g_object_ref (private->impl_window->impl);
1416 recompute_visible_regions (private, TRUE, FALSE);
1418 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1419 (attributes->cursor) :
1422 private->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1423 (GDestroyNotify) gdk_cursor_unref);
1425 device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent));
1426 g_signal_connect (device_manager, "device-removed",
1427 G_CALLBACK (device_removed_cb), window);
1433 is_parent_of (GdkWindow *parent,
1444 w = gdk_window_get_parent (w);
1451 change_impl (GdkWindowObject *private,
1452 GdkWindowObject *impl_window,
1456 GdkWindowObject *child;
1457 GdkDrawable *old_impl;
1458 GdkWindowObject *old_impl_window;
1460 old_impl = private->impl;
1461 old_impl_window = private->impl_window;
1462 if (private != impl_window)
1463 private->impl_window = g_object_ref (impl_window);
1465 private->impl_window = private;
1466 private->impl = g_object_ref (new);
1467 if (old_impl_window != private)
1468 g_object_unref (old_impl_window);
1469 g_object_unref (old_impl);
1471 for (l = private->children; l != NULL; l = l->next)
1475 if (child->impl == old_impl)
1476 change_impl (child, impl_window, new);
1481 reparent_to_impl (GdkWindowObject *private)
1484 GdkWindowObject *child;
1486 GdkWindowImplIface *impl_iface;
1488 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1490 /* Enumerate in reverse order so we get the right order for the native
1491 windows (first in childrens list is topmost, and reparent places on top) */
1492 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1496 if (child->impl == private->impl)
1497 reparent_to_impl (child);
1500 show = impl_iface->reparent ((GdkWindow *)child,
1501 (GdkWindow *)private,
1502 child->x, child->y);
1504 gdk_window_show_unraised ((GdkWindow *)child);
1511 * gdk_window_reparent:
1512 * @window: a #GdkWindow
1513 * @new_parent: new parent to move @window into
1514 * @x: X location inside the new parent
1515 * @y: Y location inside the new parent
1517 * Reparents @window into the given @new_parent. The window being
1518 * reparented will be unmapped as a side effect.
1522 gdk_window_reparent (GdkWindow *window,
1523 GdkWindow *new_parent,
1527 GdkWindowObject *private;
1528 GdkWindowObject *new_parent_private;
1529 GdkWindowObject *old_parent;
1531 gboolean show, was_mapped, applied_clip_as_shape;
1532 gboolean do_reparent_to_impl;
1533 GdkEventMask old_native_event_mask;
1534 GdkWindowImplIface *impl_iface;
1536 g_return_if_fail (GDK_IS_WINDOW (window));
1537 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1538 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1540 if (GDK_WINDOW_DESTROYED (window) ||
1541 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1544 screen = gdk_window_get_screen (window);
1546 new_parent = gdk_screen_get_root_window (screen);
1548 private = (GdkWindowObject *) window;
1549 new_parent_private = (GdkWindowObject *)new_parent;
1551 /* No input-output children of input-only windows */
1552 if (new_parent_private->input_only && !private->input_only)
1555 /* Don't create loops in hierarchy */
1556 if (is_parent_of (window, new_parent))
1559 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1560 To make sure we're ok, just wipe it. */
1561 gdk_window_drop_cairo_surface (private);
1563 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1564 old_parent = private->parent;
1566 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1569 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1570 if (new_parent_private->window_type == GDK_WINDOW_ROOT ||
1571 new_parent_private->window_type == GDK_WINDOW_FOREIGN)
1572 gdk_window_ensure_native (window);
1574 applied_clip_as_shape = should_apply_clip_as_shape (private);
1576 old_native_event_mask = 0;
1577 do_reparent_to_impl = FALSE;
1578 if (gdk_window_has_impl (private))
1580 old_native_event_mask = get_native_event_mask (private);
1582 show = impl_iface->reparent (window, new_parent, x, y);
1586 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1587 g_assert (new_parent_private->window_type != GDK_WINDOW_ROOT &&
1588 new_parent_private->window_type != GDK_WINDOW_FOREIGN);
1591 gdk_window_hide (window);
1593 do_reparent_to_impl = TRUE;
1594 change_impl (private,
1595 new_parent_private->impl_window,
1596 new_parent_private->impl);
1599 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1602 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1604 new_parent = gdk_screen_get_root_window (screen);
1605 new_parent_private = (GdkWindowObject *)new_parent;
1609 old_parent->children = g_list_remove (old_parent->children, window);
1611 private->parent = new_parent_private;
1615 new_parent_private->children = g_list_prepend (new_parent_private->children, window);
1617 /* Switch the window type as appropriate */
1619 switch (GDK_WINDOW_TYPE (new_parent))
1621 case GDK_WINDOW_ROOT:
1622 case GDK_WINDOW_FOREIGN:
1623 if (private->toplevel_window_type != -1)
1624 GDK_WINDOW_TYPE (window) = private->toplevel_window_type;
1625 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1626 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1628 case GDK_WINDOW_OFFSCREEN:
1629 case GDK_WINDOW_TOPLEVEL:
1630 case GDK_WINDOW_CHILD:
1631 case GDK_WINDOW_TEMP:
1632 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1633 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1635 /* Save the original window type so we can restore it if the
1636 * window is reparented back to be a toplevel
1638 private->toplevel_window_type = GDK_WINDOW_TYPE (window);
1639 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1643 /* We might have changed window type for a native windows, so we
1644 need to change the event mask too. */
1645 if (gdk_window_has_impl (private))
1647 GdkEventMask native_event_mask = get_native_event_mask (private);
1649 if (native_event_mask != old_native_event_mask)
1650 impl_iface->set_events (window, native_event_mask);
1653 _gdk_window_update_viewable (window);
1655 recompute_visible_regions (private, TRUE, FALSE);
1656 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1657 recompute_visible_regions (old_parent, FALSE, TRUE);
1659 /* We used to apply the clip as the shape, but no more.
1660 Reset this to the real shape */
1661 if (gdk_window_has_impl (private) &&
1662 applied_clip_as_shape &&
1663 !should_apply_clip_as_shape (private))
1664 apply_shape (private, private->shape);
1666 if (do_reparent_to_impl)
1667 reparent_to_impl (private);
1670 /* The reparent will have put the native window topmost in the native parent,
1671 * which may be wrong wrt other native windows in the non-native hierarchy,
1673 if (!gdk_window_has_impl (new_parent_private))
1674 sync_native_window_stack_position (window);
1678 gdk_window_show_unraised (window);
1680 _gdk_synthesize_crossing_events_for_geometry_change (window);
1684 temporary_disable_extension_events (GdkWindowObject *window)
1686 GdkWindowObject *child;
1690 if (window->extension_events != 0)
1692 g_object_set_data (G_OBJECT (window),
1693 "gdk-window-extension-events",
1694 GINT_TO_POINTER (window->extension_events));
1695 gdk_input_set_extension_events ((GdkWindow *)window, 0,
1696 GDK_EXTENSION_EVENTS_NONE);
1701 for (l = window->children; l != NULL; l = l->next)
1705 if (window->impl_window == child->impl_window)
1706 res |= temporary_disable_extension_events (child);
1713 reenable_extension_events (GdkWindowObject *window)
1715 GdkWindowObject *child;
1719 mask = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (window),
1720 "gdk-window-extension-events"));
1724 /* We don't have the mode here, so we pass in cursor.
1725 This works with the current code since mode is not
1726 stored except as part of the mask, and cursor doesn't
1728 gdk_input_set_extension_events ((GdkWindow *)window, mask,
1729 GDK_EXTENSION_EVENTS_CURSOR);
1730 g_object_set_data (G_OBJECT (window),
1731 "gdk-window-extension-events",
1735 for (l = window->children; l != NULL; l = l->next)
1739 if (window->impl_window == child->impl_window)
1740 reenable_extension_events (window);
1745 * gdk_window_ensure_native:
1746 * @window: a #GdkWindow
1748 * Tries to ensure that there is a window-system native window for this
1749 * GdkWindow. This may fail in some situations, returning %FALSE.
1751 * Offscreen window and children of them can never have native windows.
1753 * Some backends may not support native child windows.
1755 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1760 gdk_window_ensure_native (GdkWindow *window)
1762 GdkWindowObject *private;
1763 GdkWindowObject *impl_window;
1764 GdkDrawable *new_impl, *old_impl;
1766 GdkWindowObject *above;
1768 GdkWindowImplIface *impl_iface;
1769 gboolean disabled_extension_events;
1771 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1773 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1774 GDK_WINDOW_DESTROYED (window))
1777 private = (GdkWindowObject *) window;
1779 impl_window = gdk_window_get_impl_window (private);
1781 if (gdk_window_is_offscreen (impl_window))
1782 return FALSE; /* native in offscreens not supported */
1784 if (impl_window == private)
1785 /* Already has an impl, and its not offscreen . */
1788 /* Need to create a native window */
1790 /* First we disable any extension events on the window or its
1791 descendants to handle the native input window moving */
1792 disabled_extension_events = FALSE;
1793 if (impl_window->input_window)
1794 disabled_extension_events = temporary_disable_extension_events (private);
1796 gdk_window_drop_cairo_surface (private);
1798 screen = gdk_window_get_screen (window);
1800 old_impl = private->impl;
1801 _gdk_window_impl_new (window, (GdkWindow *)private->parent,
1803 get_native_event_mask (private),
1805 new_impl = private->impl;
1807 private->impl = old_impl;
1808 change_impl (private, private, new_impl);
1810 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
1812 /* Native window creation will put the native window topmost in the
1813 * native parent, which may be wrong wrt the position of the previous
1814 * non-native window wrt to the other non-native children, so correct this.
1816 above = find_native_sibling_above (private->parent, private);
1819 listhead.data = window;
1820 listhead.prev = NULL;
1821 listhead.next = NULL;
1822 impl_iface->restack_under ((GdkWindow *)above, &listhead);
1825 recompute_visible_regions (private, FALSE, FALSE);
1827 /* The shape may not have been set, as the clip region doesn't actually
1828 change, so do it here manually */
1829 if (should_apply_clip_as_shape (private))
1830 apply_clip_as_shape (private);
1832 reparent_to_impl (private);
1834 if (!private->input_only)
1836 impl_iface->set_background (window, private->background);
1839 impl_iface->input_shape_combine_region (window,
1840 private->input_shape,
1843 if (gdk_window_is_viewable (window))
1844 impl_iface->show (window, FALSE);
1846 if (disabled_extension_events)
1847 reenable_extension_events (private);
1853 window_remove_filters (GdkWindow *window)
1855 GdkWindowObject *obj = (GdkWindowObject*) window;
1861 for (tmp_list = obj->filters; tmp_list; tmp_list = tmp_list->next)
1862 g_free (tmp_list->data);
1864 g_list_free (obj->filters);
1865 obj->filters = NULL;
1870 update_pointer_info_foreach (GdkDisplay *display,
1872 GdkPointerWindowInfo *pointer_info,
1875 GdkWindow *window = user_data;
1877 if (pointer_info->toplevel_under_pointer == window)
1879 g_object_unref (pointer_info->toplevel_under_pointer);
1880 pointer_info->toplevel_under_pointer = NULL;
1885 window_remove_from_pointer_info (GdkWindow *window,
1886 GdkDisplay *display)
1888 _gdk_display_pointer_info_foreach (display,
1889 update_pointer_info_foreach,
1894 * _gdk_window_destroy_hierarchy:
1895 * @window: a #GdkWindow
1896 * @recursing: If TRUE, then this is being called because a parent
1898 * @recursing_native: If TRUE, then this is being called because a native parent
1899 * was destroyed. This generally means that the call to the
1900 * windowing system to destroy the window can be omitted, since
1901 * it will be destroyed as a result of the parent being destroyed.
1902 * Unless @foreign_destroy.
1903 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1904 * external agency. The window has already been destroyed and no
1905 * windowing system calls should be made. (This may never happen
1906 * for some windowing systems.)
1908 * Internal function to destroy a window. Like gdk_window_destroy(),
1909 * but does not drop the reference count created by gdk_window_new().
1912 _gdk_window_destroy_hierarchy (GdkWindow *window,
1914 gboolean recursing_native,
1915 gboolean foreign_destroy)
1917 GdkWindowObject *private;
1918 GdkWindowObject *temp_private;
1919 GdkWindowImplIface *impl_iface;
1920 GdkWindow *temp_window;
1922 GdkDisplay *display;
1926 g_return_if_fail (GDK_IS_WINDOW (window));
1928 private = (GdkWindowObject*) window;
1930 if (GDK_WINDOW_DESTROYED (window))
1933 display = gdk_window_get_display (window);
1934 screen = gdk_window_get_screen (window);
1935 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1936 if (temp_window == window)
1937 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1940 switch (private->window_type)
1942 case GDK_WINDOW_ROOT:
1943 if (!screen->closed)
1945 g_error ("attempted to destroy root window");
1948 /* else fall thru */
1949 case GDK_WINDOW_TOPLEVEL:
1950 case GDK_WINDOW_CHILD:
1951 case GDK_WINDOW_TEMP:
1952 case GDK_WINDOW_FOREIGN:
1953 case GDK_WINDOW_OFFSCREEN:
1954 if (private->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
1956 /* Logically, it probably makes more sense to send
1957 * a "destroy yourself" message to the foreign window
1958 * whether or not it's in our hierarchy; but for historical
1959 * reasons, we only send "destroy yourself" messages to
1960 * foreign windows in our hierarchy.
1962 if (private->parent)
1963 _gdk_windowing_window_destroy_foreign (window);
1965 /* Also for historical reasons, we remove any filters
1966 * on a foreign window when it or a parent is destroyed;
1967 * this likely causes problems if two separate portions
1968 * of code are maintaining filter lists on a foreign window.
1970 window_remove_filters (window);
1974 if (private->parent)
1976 GdkWindowObject *parent_private = (GdkWindowObject *)private->parent;
1978 if (parent_private->children)
1979 parent_private->children = g_list_remove (parent_private->children, window);
1982 GDK_WINDOW_IS_MAPPED (window))
1984 recompute_visible_regions (private, TRUE, FALSE);
1985 gdk_window_invalidate_in_parent (private);
1989 gdk_window_free_paint_stack (window);
1991 gdk_window_set_background_pattern (window, NULL);
1993 if (private->background)
1995 cairo_pattern_destroy (private->background);
1996 private->background = NULL;
1999 if (private->window_type == GDK_WINDOW_FOREIGN)
2000 g_assert (private->children == NULL);
2003 children = tmp = private->children;
2004 private->children = NULL;
2008 temp_window = tmp->data;
2011 temp_private = (GdkWindowObject*) temp_window;
2013 _gdk_window_destroy_hierarchy (temp_window,
2015 recursing_native || gdk_window_has_impl (private),
2019 g_list_free (children);
2022 _gdk_window_clear_update_area (window);
2024 gdk_window_drop_cairo_surface (private);
2026 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
2028 if (gdk_window_has_impl (private))
2029 impl_iface->destroy (window, recursing_native,
2033 /* hide to make sure we repaint and break grabs */
2034 gdk_window_hide (window);
2037 private->state |= GDK_WINDOW_STATE_WITHDRAWN;
2038 private->parent = NULL;
2039 private->destroyed = TRUE;
2041 window_remove_filters (window);
2043 window_remove_from_pointer_info (window, display);
2045 if (private->clip_region)
2047 cairo_region_destroy (private->clip_region);
2048 private->clip_region = NULL;
2051 if (private->clip_region_with_children)
2053 cairo_region_destroy (private->clip_region_with_children);
2054 private->clip_region_with_children = NULL;
2057 if (private->outstanding_moves)
2059 g_list_foreach (private->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2060 g_list_free (private->outstanding_moves);
2061 private->outstanding_moves = NULL;
2069 * _gdk_window_destroy:
2070 * @window: a #GdkWindow
2071 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2072 * external agency. The window has already been destroyed and no
2073 * windowing system calls should be made. (This may never happen
2074 * for some windowing systems.)
2076 * Internal function to destroy a window. Like gdk_window_destroy(),
2077 * but does not drop the reference count created by gdk_window_new().
2080 _gdk_window_destroy (GdkWindow *window,
2081 gboolean foreign_destroy)
2083 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2087 * gdk_window_destroy:
2088 * @window: a #GdkWindow
2090 * Destroys the window system resources associated with @window and decrements @window's
2091 * reference count. The window system resources for all children of @window are also
2092 * destroyed, but the children's reference counts are not decremented.
2094 * Note that a window will not be destroyed automatically when its reference count
2095 * reaches zero. You must call this function yourself before that happens.
2099 gdk_window_destroy (GdkWindow *window)
2101 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2102 g_object_unref (window);
2106 * gdk_window_set_user_data:
2107 * @window: a #GdkWindow
2108 * @user_data: user data
2110 * For most purposes this function is deprecated in favor of
2111 * g_object_set_data(). However, for historical reasons GTK+ stores
2112 * the #GtkWidget that owns a #GdkWindow as user data on the
2113 * #GdkWindow. So, custom widget implementations should use
2114 * this function for that. If GTK+ receives an event for a #GdkWindow,
2115 * and the user data for the window is non-%NULL, GTK+ will assume the
2116 * user data is a #GtkWidget, and forward the event to that widget.
2120 gdk_window_set_user_data (GdkWindow *window,
2123 g_return_if_fail (GDK_IS_WINDOW (window));
2125 ((GdkWindowObject*)window)->user_data = user_data;
2129 * gdk_window_get_user_data:
2130 * @window: a #GdkWindow
2131 * @data: return location for user data
2133 * Retrieves the user data for @window, which is normally the widget
2134 * that @window belongs to. See gdk_window_set_user_data().
2138 gdk_window_get_user_data (GdkWindow *window,
2141 g_return_if_fail (GDK_IS_WINDOW (window));
2143 *data = ((GdkWindowObject*)window)->user_data;
2147 * gdk_window_get_window_type:
2148 * @window: a #GdkWindow
2150 * Gets the type of the window. See #GdkWindowType.
2152 * Return value: type of window
2155 gdk_window_get_window_type (GdkWindow *window)
2157 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2159 return GDK_WINDOW_TYPE (window);
2163 * gdk_window_get_visual:
2164 * @window: a #GdkWindow
2166 * Gets the #GdkVisual describing the pixel format of @window.
2168 * Return value: a #GdkVisual
2171 gdk_window_get_visual (GdkWindow *window)
2173 GdkWindowObject *private;
2175 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2177 private = (GdkWindowObject *) window;
2179 return private->visual;
2183 * gdk_window_get_screen:
2184 * @window: a #GdkWindow
2186 * Gets the #GdkScreen associated with a #GdkWindow.
2188 * Return value: the #GdkScreen associated with @window
2191 gdk_window_get_screen (GdkWindow *window)
2193 GdkWindowObject *private;
2195 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2197 private = (GdkWindowObject *) window;
2199 return gdk_visual_get_screen (private->visual);
2203 * gdk_window_get_display:
2204 * @window: a #GdkWindow
2206 * Gets the #GdkDisplay associated with a #GdkWindow.
2208 * Return value: the #GdkDisplay associated with @window
2211 gdk_window_get_display (GdkWindow *window)
2213 GdkWindowObject *private;
2215 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2217 private = (GdkWindowObject *) window;
2219 return gdk_screen_get_display (gdk_visual_get_screen (private->visual));
2222 * gdk_window_is_destroyed:
2223 * @window: a #GdkWindow
2225 * Check to see if a window is destroyed..
2227 * Return value: %TRUE if the window is destroyed
2232 gdk_window_is_destroyed (GdkWindow *window)
2234 return GDK_WINDOW_DESTROYED (window);
2238 to_embedder (GdkWindowObject *window,
2239 gdouble offscreen_x,
2240 gdouble offscreen_y,
2241 gdouble *embedder_x,
2242 gdouble *embedder_y)
2244 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2245 offscreen_x, offscreen_y,
2246 embedder_x, embedder_y);
2250 from_embedder (GdkWindowObject *window,
2253 gdouble *offscreen_x,
2254 gdouble *offscreen_y)
2256 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2257 embedder_x, embedder_y,
2258 offscreen_x, offscreen_y);
2262 * gdk_window_has_native:
2263 * @window: a #GdkWindow
2265 * Checks whether the window has a native window or not. Note that
2266 * you can use gdk_window_ensure_native() if a native window is needed.
2268 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2273 gdk_window_has_native (GdkWindow *window)
2277 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2279 w = GDK_WINDOW_OBJECT (window);
2281 return w->parent == NULL || w->parent->impl != w->impl;
2285 * gdk_window_get_position:
2286 * @window: a #GdkWindow
2287 * @x: X coordinate of window
2288 * @y: Y coordinate of window
2290 * Obtains the position of the window as reported in the
2291 * most-recently-processed #GdkEventConfigure. Contrast with
2292 * gdk_window_get_geometry() which queries the X server for the
2293 * current window position, regardless of which events have been
2294 * received or processed.
2296 * The position coordinates are relative to the window's parent window.
2300 gdk_window_get_position (GdkWindow *window,
2304 GdkWindowObject *obj;
2306 g_return_if_fail (GDK_IS_WINDOW (window));
2308 obj = (GdkWindowObject*) window;
2317 * gdk_window_get_parent:
2318 * @window: a #GdkWindow
2320 * Obtains the parent of @window, as known to GDK. Does not query the
2321 * X server; thus this returns the parent as passed to gdk_window_new(),
2322 * not the actual parent. This should never matter unless you're using
2323 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2324 * matter for toplevel windows, because the window manager may choose
2327 * Note that you should use gdk_window_get_effective_parent() when
2328 * writing generic code that walks up a window hierarchy, because
2329 * gdk_window_get_parent() will most likely not do what you expect if
2330 * there are offscreen windows in the hierarchy.
2332 * Return value: (transfer none): parent of @window
2335 gdk_window_get_parent (GdkWindow *window)
2337 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2339 return (GdkWindow*) ((GdkWindowObject*) window)->parent;
2343 * gdk_window_get_effective_parent:
2344 * @window: a #GdkWindow
2346 * Obtains the parent of @window, as known to GDK. Works like
2347 * gdk_window_get_parent() for normal windows, but returns the
2348 * window's embedder for offscreen windows.
2350 * See also: gdk_offscreen_window_get_embedder()
2352 * Return value: (transfer none): effective parent of @window
2357 gdk_window_get_effective_parent (GdkWindow *window)
2359 GdkWindowObject *obj;
2361 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2363 obj = (GdkWindowObject *)window;
2365 if (gdk_window_is_offscreen (obj))
2366 return gdk_offscreen_window_get_embedder (window);
2368 return (GdkWindow *) obj->parent;
2372 * gdk_window_get_toplevel:
2373 * @window: a #GdkWindow
2375 * Gets the toplevel window that's an ancestor of @window.
2377 * Any window type but %GDK_WINDOW_CHILD is considered a
2378 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2379 * has a root window as parent.
2381 * Note that you should use gdk_window_get_effective_toplevel() when
2382 * you want to get to a window's toplevel as seen on screen, because
2383 * gdk_window_get_toplevel() will most likely not do what you expect
2384 * if there are offscreen windows in the hierarchy.
2386 * Return value: (transfer none): the toplevel window containing @window
2389 gdk_window_get_toplevel (GdkWindow *window)
2391 GdkWindowObject *obj;
2393 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2395 obj = (GdkWindowObject *)window;
2397 while (obj->window_type == GDK_WINDOW_CHILD)
2399 if (gdk_window_is_toplevel (obj))
2404 return GDK_WINDOW (obj);
2408 * gdk_window_get_effective_toplevel:
2409 * @window: a #GdkWindow
2411 * Gets the toplevel window that's an ancestor of @window.
2413 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2414 * embedder as its parent, using gdk_window_get_effective_parent().
2416 * See also: gdk_offscreen_window_get_embedder()
2418 * Return value: (transfer none): the effective toplevel window containing @window
2423 gdk_window_get_effective_toplevel (GdkWindow *window)
2427 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2429 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2430 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2437 * gdk_window_get_children:
2438 * @window: a #GdkWindow
2440 * Gets the list of children of @window known to GDK.
2441 * This function only returns children created via GDK,
2442 * so for example it's useless when used with the root window;
2443 * it only returns windows an application created itself.
2445 * The returned list must be freed, but the elements in the
2448 * Return value: (transfer container) (element-type GdkWindow):
2449 * list of child windows inside @window
2452 gdk_window_get_children (GdkWindow *window)
2454 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2456 if (GDK_WINDOW_DESTROYED (window))
2459 return g_list_copy (GDK_WINDOW_OBJECT (window)->children);
2463 * gdk_window_peek_children:
2464 * @window: a #GdkWindow
2466 * Like gdk_window_get_children(), but does not copy the list of
2467 * children, so the list does not need to be freed.
2469 * Return value: (transfer none) (element-type GdkWindow):
2470 * a reference to the list of child windows in @window
2473 gdk_window_peek_children (GdkWindow *window)
2475 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2477 if (GDK_WINDOW_DESTROYED (window))
2480 return GDK_WINDOW_OBJECT (window)->children;
2484 * gdk_window_add_filter:
2485 * @window: a #GdkWindow
2486 * @function: filter callback
2487 * @data: data to pass to filter callback
2489 * Adds an event filter to @window, allowing you to intercept events
2490 * before they reach GDK. This is a low-level operation and makes it
2491 * easy to break GDK and/or GTK+, so you have to know what you're
2492 * doing. Pass %NULL for @window to get all events for all windows,
2493 * instead of events for a specific window.
2495 * See gdk_display_add_client_message_filter() if you are interested
2496 * in X ClientMessage events.
2499 gdk_window_add_filter (GdkWindow *window,
2500 GdkFilterFunc function,
2503 GdkWindowObject *private;
2505 GdkEventFilter *filter;
2507 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2509 private = (GdkWindowObject*) window;
2510 if (private && GDK_WINDOW_DESTROYED (window))
2513 /* Filters are for the native events on the native window, so
2514 ensure there is a native window. */
2516 gdk_window_ensure_native (window);
2519 tmp_list = private->filters;
2521 tmp_list = _gdk_default_filters;
2525 filter = (GdkEventFilter *)tmp_list->data;
2526 if ((filter->function == function) && (filter->data == data))
2528 tmp_list = tmp_list->next;
2531 filter = g_new (GdkEventFilter, 1);
2532 filter->function = function;
2533 filter->data = data;
2536 private->filters = g_list_append (private->filters, filter);
2538 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2542 * gdk_window_remove_filter:
2543 * @window: a #GdkWindow
2544 * @function: previously-added filter function
2545 * @data: user data for previously-added filter function
2547 * Remove a filter previously added with gdk_window_add_filter().
2551 gdk_window_remove_filter (GdkWindow *window,
2552 GdkFilterFunc function,
2555 GdkWindowObject *private;
2556 GList *tmp_list, *node;
2557 GdkEventFilter *filter;
2559 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2561 private = (GdkWindowObject*) window;
2564 tmp_list = private->filters;
2566 tmp_list = _gdk_default_filters;
2570 filter = (GdkEventFilter *)tmp_list->data;
2572 tmp_list = tmp_list->next;
2574 if ((filter->function == function) && (filter->data == data))
2577 private->filters = g_list_remove_link (private->filters, node);
2579 _gdk_default_filters = g_list_remove_link (_gdk_default_filters, node);
2580 g_list_free_1 (node);
2589 * gdk_screen_get_toplevel_windows:
2590 * @screen: The #GdkScreen where the toplevels are located.
2592 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2593 * A toplevel window is a child of the root window (see
2594 * gdk_get_default_root_window()).
2596 * The returned list should be freed with g_list_free(), but
2597 * its elements need not be freed.
2599 * Return value: (transfer container) (element-type GdkWindow):
2600 * list of toplevel windows, free with g_list_free()
2605 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2607 GdkWindow * root_window;
2608 GList *new_list = NULL;
2611 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2613 root_window = gdk_screen_get_root_window (screen);
2615 tmp_list = ((GdkWindowObject *)root_window)->children;
2618 GdkWindowObject *w = tmp_list->data;
2620 if (w->window_type != GDK_WINDOW_FOREIGN)
2621 new_list = g_list_prepend (new_list, w);
2622 tmp_list = tmp_list->next;
2629 * gdk_window_is_visible:
2630 * @window: a #GdkWindow
2632 * Checks whether the window has been mapped (with gdk_window_show() or
2633 * gdk_window_show_unraised()).
2635 * Return value: %TRUE if the window is mapped
2638 gdk_window_is_visible (GdkWindow *window)
2640 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2642 return GDK_WINDOW_IS_MAPPED (window);
2646 * gdk_window_is_viewable:
2647 * @window: a #GdkWindow
2649 * Check if the window and all ancestors of the window are
2650 * mapped. (This is not necessarily "viewable" in the X sense, since
2651 * we only check as far as we have GDK window parents, not to the root
2654 * Return value: %TRUE if the window is viewable
2657 gdk_window_is_viewable (GdkWindow *window)
2659 GdkWindowObject *private = (GdkWindowObject *)window;
2661 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2663 if (private->destroyed)
2666 return private->viewable;
2670 * gdk_window_get_state:
2671 * @window: a #GdkWindow
2673 * Gets the bitwise OR of the currently active window state flags,
2674 * from the #GdkWindowState enumeration.
2676 * Return value: window state bitfield
2679 gdk_window_get_state (GdkWindow *window)
2681 GdkWindowObject *private = (GdkWindowObject *)window;
2683 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2685 return private->state;
2688 static cairo_content_t
2689 gdk_window_get_content (GdkWindow *window)
2691 cairo_surface_t *surface;
2692 cairo_content_t content;
2694 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2696 surface = _gdk_drawable_ref_cairo_surface (window);
2697 content = cairo_surface_get_content (surface);
2698 cairo_surface_destroy (surface);
2703 /* This creates an empty "implicit" paint region for the impl window.
2704 * By itself this does nothing, but real paints to this window
2705 * or children of it can use this surface as backing to avoid allocating
2706 * multiple surfaces for subwindow rendering. When doing so they
2707 * add to the region of the implicit paint region, which will be
2708 * pushed to the window when the implicit paint region is ended.
2709 * Such paints should not copy anything to the window on paint end, but
2710 * should rely on the implicit paint end.
2711 * The implicit paint will be automatically ended if someone draws
2712 * directly to the window or a child window.
2715 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2717 GdkWindowObject *private = (GdkWindowObject *)window;
2718 GdkWindowPaint *paint;
2720 g_assert (gdk_window_has_impl (private));
2722 if (_gdk_native_windows)
2723 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2725 if (GDK_IS_PAINTABLE (private->impl))
2726 return FALSE; /* Implementation does double buffering */
2728 if (private->paint_stack != NULL ||
2729 private->implicit_paint != NULL)
2730 return FALSE; /* Don't stack implicit paints */
2732 if (private->outstanding_surfaces != 0)
2733 return FALSE; /* May conflict with direct drawing to cairo surface */
2735 /* Never do implicit paints for foreign windows, they don't need
2736 * double buffer combination since they have no client side children,
2737 * and creating surfaces for them is risky since they could disappear
2740 if (private->window_type == GDK_WINDOW_FOREIGN)
2743 paint = g_new (GdkWindowPaint, 1);
2744 paint->region = cairo_region_create (); /* Empty */
2745 paint->uses_implicit = FALSE;
2746 paint->flushed = FALSE;
2747 paint->surface = gdk_window_create_similar_surface (window,
2748 gdk_window_get_content (window),
2749 MAX (rect->width, 1),
2750 MAX (rect->height, 1));
2751 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2753 private->implicit_paint = paint;
2758 /* Ensure that all content related to this (sub)window is pushed to the
2759 native region. If there is an active paint then that area is not
2760 pushed, in order to not show partially finished double buffers. */
2762 gdk_window_flush_implicit_paint (GdkWindow *window)
2764 GdkWindowObject *private = (GdkWindowObject *)window;
2765 GdkWindowObject *impl_window;
2766 GdkWindowPaint *paint;
2767 cairo_region_t *region;
2770 impl_window = gdk_window_get_impl_window (private);
2771 if (impl_window->implicit_paint == NULL)
2774 paint = impl_window->implicit_paint;
2775 paint->flushed = TRUE;
2776 region = cairo_region_copy (private->clip_region_with_children);
2778 /* Don't flush active double buffers, as that may show partially done
2780 for (list = private->paint_stack; list != NULL; list = list->next)
2782 GdkWindowPaint *tmp_paint = list->data;
2784 cairo_region_subtract (region, tmp_paint->region);
2787 cairo_region_translate (region, -private->abs_x, -private->abs_y);
2788 cairo_region_intersect (region, paint->region);
2790 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2794 /* Remove flushed region from the implicit paint */
2795 cairo_region_subtract (paint->region, region);
2797 /* Some regions are valid, push these to window now */
2798 cr = gdk_cairo_create (private->impl);
2799 gdk_cairo_region (cr, region);
2801 cairo_set_source_surface (cr, paint->surface, 0, 0);
2802 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2807 cairo_region_destroy (region);
2810 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2812 gdk_window_end_implicit_paint (GdkWindow *window)
2814 GdkWindowObject *private = (GdkWindowObject *)window;
2815 GdkWindowPaint *paint;
2817 g_assert (gdk_window_has_impl (private));
2819 g_assert (private->implicit_paint != NULL);
2821 paint = private->implicit_paint;
2823 private->implicit_paint = NULL;
2825 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2829 /* Some regions are valid, push these to window now */
2830 cr = gdk_cairo_create (private->impl);
2831 gdk_cairo_region (cr, paint->region);
2833 cairo_set_source_surface (cr, paint->surface, 0, 0);
2834 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2839 cairo_region_destroy (paint->region);
2841 cairo_surface_destroy (paint->surface);
2846 * gdk_window_begin_paint_rect:
2847 * @window: a #GdkWindow
2848 * @rectangle: rectangle you intend to draw to
2850 * A convenience wrapper around gdk_window_begin_paint_region() which
2851 * creates a rectangular region for you. See
2852 * gdk_window_begin_paint_region() for details.
2856 gdk_window_begin_paint_rect (GdkWindow *window,
2857 const GdkRectangle *rectangle)
2859 cairo_region_t *region;
2861 g_return_if_fail (GDK_IS_WINDOW (window));
2863 region = cairo_region_create_rectangle (rectangle);
2864 gdk_window_begin_paint_region (window, region);
2865 cairo_region_destroy (region);
2869 * gdk_window_begin_paint_region:
2870 * @window: a #GdkWindow
2871 * @region: region you intend to draw to
2873 * Indicates that you are beginning the process of redrawing @region.
2874 * A backing store (offscreen buffer) large enough to contain @region
2875 * will be created. The backing store will be initialized with the
2876 * background color or background surface for @window. Then, all
2877 * drawing operations performed on @window will be diverted to the
2878 * backing store. When you call gdk_window_end_paint(), the backing
2879 * store will be copied to @window, making it visible onscreen. Only
2880 * the part of @window contained in @region will be modified; that is,
2881 * drawing operations are clipped to @region.
2883 * The net result of all this is to remove flicker, because the user
2884 * sees the finished product appear all at once when you call
2885 * gdk_window_end_paint(). If you draw to @window directly without
2886 * calling gdk_window_begin_paint_region(), the user may see flicker
2887 * as individual drawing operations are performed in sequence. The
2888 * clipping and background-initializing features of
2889 * gdk_window_begin_paint_region() are conveniences for the
2890 * programmer, so you can avoid doing that work yourself.
2892 * When using GTK+, the widget system automatically places calls to
2893 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2894 * emissions of the expose_event signal. That is, if you're writing an
2895 * expose event handler, you can assume that the exposed area in
2896 * #GdkEventExpose has already been cleared to the window background,
2897 * is already set as the clip region, and already has a backing store.
2898 * Therefore in most cases, application code need not call
2899 * gdk_window_begin_paint_region(). (You can disable the automatic
2900 * calls around expose events on a widget-by-widget basis by calling
2901 * gtk_widget_set_double_buffered().)
2903 * If you call this function multiple times before calling the
2904 * matching gdk_window_end_paint(), the backing stores are pushed onto
2905 * a stack. gdk_window_end_paint() copies the topmost backing store
2906 * onscreen, subtracts the topmost region from all other regions in
2907 * the stack, and pops the stack. All drawing operations affect only
2908 * the topmost backing store in the stack. One matching call to
2909 * gdk_window_end_paint() is required for each call to
2910 * gdk_window_begin_paint_region().
2914 gdk_window_begin_paint_region (GdkWindow *window,
2915 const cairo_region_t *region)
2917 #ifdef USE_BACKING_STORE
2918 GdkWindowObject *private = (GdkWindowObject *)window;
2919 GdkRectangle clip_box;
2920 GdkWindowPaint *paint, *implicit_paint;
2921 GdkWindowObject *impl_window;
2924 g_return_if_fail (GDK_IS_WINDOW (window));
2926 if (GDK_WINDOW_DESTROYED (window))
2929 if (GDK_IS_PAINTABLE (private->impl))
2931 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
2933 if (iface->begin_paint_region)
2934 iface->begin_paint_region ((GdkPaintable*)private->impl, window, region);
2939 impl_window = gdk_window_get_impl_window (private);
2940 implicit_paint = impl_window->implicit_paint;
2942 paint = g_new (GdkWindowPaint, 1);
2943 paint->region = cairo_region_copy (region);
2944 paint->region_tag = new_region_tag ();
2946 cairo_region_intersect (paint->region, private->clip_region_with_children);
2947 cairo_region_get_extents (paint->region, &clip_box);
2949 cairo_region_translate (paint->region, private->abs_x, private->abs_y);
2951 /* Mark the region as valid on the implicit paint */
2954 cairo_region_union (implicit_paint->region, paint->region);
2956 /* Convert back to normal coords */
2957 cairo_region_translate (paint->region, -private->abs_x, -private->abs_y);
2961 paint->uses_implicit = TRUE;
2962 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
2963 private->abs_x + clip_box.x,
2964 private->abs_y + clip_box.y,
2965 MAX (clip_box.width, 1),
2966 MAX (clip_box.height, 1));
2970 paint->uses_implicit = FALSE;
2971 paint->surface = gdk_window_create_similar_surface (window,
2972 gdk_window_get_content (window),
2973 MAX (clip_box.width, 1),
2974 MAX (clip_box.height, 1));
2976 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
2978 for (list = private->paint_stack; list != NULL; list = list->next)
2980 GdkWindowPaint *tmp_paint = list->data;
2982 cairo_region_subtract (tmp_paint->region, paint->region);
2985 private->paint_stack = g_slist_prepend (private->paint_stack, paint);
2987 if (!cairo_region_is_empty (paint->region))
2989 gdk_window_clear_backing_region (window,
2993 #endif /* USE_BACKING_STORE */
2997 * gdk_window_end_paint:
2998 * @window: a #GdkWindow
3000 * Indicates that the backing store created by the most recent call to
3001 * gdk_window_begin_paint_region() should be copied onscreen and
3002 * deleted, leaving the next-most-recent backing store or no backing
3003 * store at all as the active paint region. See
3004 * gdk_window_begin_paint_region() for full details. It is an error to
3005 * call this function without a matching
3006 * gdk_window_begin_paint_region() first.
3010 gdk_window_end_paint (GdkWindow *window)
3012 #ifdef USE_BACKING_STORE
3013 GdkWindowObject *private = (GdkWindowObject *)window;
3014 GdkWindowObject *composited;
3015 GdkWindowPaint *paint;
3016 GdkRectangle clip_box;
3017 cairo_region_t *full_clip;
3019 g_return_if_fail (GDK_IS_WINDOW (window));
3021 if (GDK_WINDOW_DESTROYED (window))
3024 if (GDK_IS_PAINTABLE (private->impl))
3026 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (private->impl);
3028 if (iface->end_paint)
3029 iface->end_paint ((GdkPaintable*)private->impl);
3033 if (private->paint_stack == NULL)
3035 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3039 paint = private->paint_stack->data;
3041 private->paint_stack = g_slist_delete_link (private->paint_stack,
3042 private->paint_stack);
3044 cairo_region_get_extents (paint->region, &clip_box);
3046 if (!paint->uses_implicit)
3050 gdk_window_flush_outstanding_moves (window);
3052 full_clip = cairo_region_copy (private->clip_region_with_children);
3053 cairo_region_intersect (full_clip, paint->region);
3055 cr = gdk_cairo_create (window);
3056 cairo_set_source_surface (cr, paint->surface, 0, 0);
3057 gdk_cairo_region (cr, full_clip);
3061 cairo_region_destroy (full_clip);
3064 cairo_surface_destroy (paint->surface);
3065 cairo_region_destroy (paint->region);
3068 /* find a composited window in our hierarchy to signal its
3069 * parent to redraw, calculating the clip box as we go...
3071 * stop if parent becomes NULL since then we'd have nowhere
3072 * to draw (ie: 'composited' will always be non-NULL here).
3074 for (composited = private;
3076 composited = composited->parent)
3080 gdk_drawable_get_size (GDK_DRAWABLE (composited->parent),
3083 clip_box.x += composited->x;
3084 clip_box.y += composited->y;
3085 clip_box.width = MIN (clip_box.width, width - clip_box.x);
3086 clip_box.height = MIN (clip_box.height, height - clip_box.y);
3088 if (composited->composited)
3090 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3095 #endif /* USE_BACKING_STORE */
3099 gdk_window_free_paint_stack (GdkWindow *window)
3101 GdkWindowObject *private = (GdkWindowObject *)window;
3103 if (private->paint_stack)
3105 GSList *tmp_list = private->paint_stack;
3109 GdkWindowPaint *paint = tmp_list->data;
3111 if (tmp_list == private->paint_stack)
3112 cairo_surface_destroy (paint->surface);
3114 cairo_region_destroy (paint->region);
3117 tmp_list = tmp_list->next;
3120 g_slist_free (private->paint_stack);
3121 private->paint_stack = NULL;
3126 do_move_region_bits_on_impl (GdkWindowObject *impl_window,
3127 cairo_region_t *dest_region, /* In impl window coords */
3130 GdkWindowImplIface *impl_iface;
3132 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (impl_window->impl);
3134 impl_iface->translate ((GdkWindow *) impl_window, dest_region, dx, dy);
3137 static GdkWindowRegionMove *
3138 gdk_window_region_move_new (cairo_region_t *region,
3141 GdkWindowRegionMove *move;
3143 move = g_slice_new (GdkWindowRegionMove);
3144 move->dest_region = cairo_region_copy (region);
3152 gdk_window_region_move_free (GdkWindowRegionMove *move)
3154 cairo_region_destroy (move->dest_region);
3155 g_slice_free (GdkWindowRegionMove, move);
3159 append_move_region (GdkWindowObject *impl_window,
3160 cairo_region_t *new_dest_region,
3163 GdkWindowRegionMove *move, *old_move;
3164 cairo_region_t *new_total_region, *old_total_region;
3165 cairo_region_t *source_overlaps_destination;
3166 cairo_region_t *non_overwritten;
3167 gboolean added_move;
3170 if (cairo_region_is_empty (new_dest_region))
3173 /* In principle this could just append the move to the list of outstanding
3174 moves that will be replayed before drawing anything when we're handling
3175 exposes. However, we'd like to do a bit better since its commonly the case
3176 that we get multiple copies where A is copied to B and then B is copied
3177 to C, and we'd like to express this as a simple copy A to C operation. */
3179 /* We approach this by taking the new move and pushing it ahead of moves
3180 starting at the end of the list and stopping when its not safe to do so.
3181 It's not safe to push past a move if either the source of the new move
3182 is in the destination of the old move, or if the destination of the new
3183 move is in the source of the new move, or if the destination of the new
3184 move overlaps the destination of the old move. We simplify this by
3185 just comparing the total regions (src + dest) */
3186 new_total_region = cairo_region_copy (new_dest_region);
3187 cairo_region_translate (new_total_region, -dx, -dy);
3188 cairo_region_union (new_total_region, new_dest_region);
3191 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3196 old_total_region = cairo_region_copy (old_move->dest_region);
3197 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3198 cairo_region_union (old_total_region, old_move->dest_region);
3200 cairo_region_intersect (old_total_region, new_total_region);
3201 /* If these regions intersect then its not safe to push the
3202 new region before the old one */
3203 if (!cairo_region_is_empty (old_total_region))
3205 /* The area where the new moves source overlaps the old ones
3207 source_overlaps_destination = cairo_region_copy (new_dest_region);
3208 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3209 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3210 cairo_region_translate (source_overlaps_destination, dx, dy);
3212 /* We can do all sort of optimizations here, but to do things safely it becomes
3213 quite complicated. However, a very common case is that you copy something first,
3214 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3215 in the same direction). We'd like to detect this case and optimize it to one
3217 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3219 /* This means we might be able to replace the old move and the new one
3220 with the new one read from the old ones source, and a second copy of
3221 the non-overwritten parts of the old move. However, such a split
3222 is only valid if the source in the old move isn't overwritten
3223 by the destination of the new one */
3225 /* the new destination of old move if split is ok: */
3226 non_overwritten = cairo_region_copy (old_move->dest_region);
3227 cairo_region_subtract (non_overwritten, new_dest_region);
3228 /* move to source region */
3229 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3231 cairo_region_intersect (non_overwritten, new_dest_region);
3232 if (cairo_region_is_empty (non_overwritten))
3235 move = gdk_window_region_move_new (new_dest_region,
3239 impl_window->outstanding_moves =
3240 g_list_insert_before (impl_window->outstanding_moves,
3242 cairo_region_subtract (old_move->dest_region, new_dest_region);
3244 cairo_region_destroy (non_overwritten);
3247 cairo_region_destroy (source_overlaps_destination);
3248 cairo_region_destroy (old_total_region);
3251 cairo_region_destroy (old_total_region);
3254 cairo_region_destroy (new_total_region);
3258 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3261 impl_window->outstanding_moves =
3262 g_list_prepend (impl_window->outstanding_moves,
3265 impl_window->outstanding_moves =
3266 g_list_insert_before (impl_window->outstanding_moves,
3271 /* Moves bits and update area by dx/dy in impl window.
3272 Takes ownership of region to avoid copy (because we may change it) */
3274 move_region_on_impl (GdkWindowObject *impl_window,
3275 cairo_region_t *region, /* In impl window coords */
3278 if ((dx == 0 && dy == 0) ||
3279 cairo_region_is_empty (region))
3281 cairo_region_destroy (region);
3285 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3287 /* Move any old invalid regions in the copy source area by dx/dy */
3288 if (impl_window->update_area)
3290 cairo_region_t *update_area;
3292 update_area = cairo_region_copy (region);
3294 /* Convert from target to source */
3295 cairo_region_translate (update_area, -dx, -dy);
3296 cairo_region_intersect (update_area, impl_window->update_area);
3297 /* We only copy the area, so keep the old update area invalid.
3298 It would be safe to remove it too, as code that uses
3299 move_region_on_impl generally also invalidate the source
3300 area. However, it would just use waste cycles. */
3303 cairo_region_translate (update_area, dx, dy);
3304 cairo_region_union (impl_window->update_area, update_area);
3306 /* This area of the destination is now invalid,
3307 so no need to copy to it. */
3308 cairo_region_subtract (region, update_area);
3310 cairo_region_destroy (update_area);
3313 /* If we're currently exposing this window, don't copy to this
3314 destination, as it will be overdrawn when the expose is done,
3315 instead invalidate it and repaint later. */
3316 if (impl_window->implicit_paint)
3318 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3319 cairo_region_t *exposing;
3321 exposing = cairo_region_copy (implicit_paint->region);
3322 cairo_region_intersect (exposing, region);
3323 cairo_region_subtract (region, exposing);
3325 impl_window_add_update_area (impl_window, exposing);
3326 cairo_region_destroy (exposing);
3329 if (impl_window->outstanding_surfaces == 0) /* Enable flicker free handling of moves. */
3330 append_move_region (impl_window, region, dx, dy);
3332 do_move_region_bits_on_impl (impl_window,
3335 cairo_region_destroy (region);
3338 /* Flushes all outstanding changes to the window, call this
3339 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3342 gdk_window_flush_outstanding_moves (GdkWindow *window)
3344 GdkWindowObject *private;
3345 GdkWindowObject *impl_window;
3346 GList *l, *outstanding;
3347 GdkWindowRegionMove *move;
3349 private = (GdkWindowObject *) window;
3351 impl_window = gdk_window_get_impl_window (private);
3352 outstanding = impl_window->outstanding_moves;
3353 impl_window->outstanding_moves = NULL;
3355 for (l = outstanding; l != NULL; l = l->next)
3359 do_move_region_bits_on_impl (impl_window,
3360 move->dest_region, move->dx, move->dy);
3362 gdk_window_region_move_free (move);
3365 g_list_free (outstanding);
3370 * @window: a #GdkWindow
3372 * Flush all outstanding cached operations on a window, leaving the
3373 * window in a state which reflects all that has been drawn before.
3375 * Gdk uses multiple kinds of caching to get better performance and
3376 * nicer drawing. For instance, during exposes all paints to a window
3377 * using double buffered rendering are keep on a surface until the last
3378 * window has been exposed. It also delays window moves/scrolls until
3379 * as long as possible until next update to avoid tearing when moving
3382 * Normally this should be completely invisible to applications, as
3383 * we automatically flush the windows when required, but this might
3384 * be needed if you for instance mix direct native drawing with
3385 * gdk drawing. For Gtk widgets that don't use double buffering this
3386 * will be called automatically before sending the expose event.
3391 gdk_window_flush (GdkWindow *window)
3393 gdk_window_flush_outstanding_moves (window);
3394 gdk_window_flush_implicit_paint (window);
3397 /* If we're about to move/resize or otherwise change the
3398 * hierarchy of a client side window in an impl and we're
3399 * called from an expose event handler then we need to
3400 * flush any already painted parts of the implicit paint
3401 * that are not part of the current paint, as these may
3402 * be used when scrolling or may overdraw the changes
3403 * caused by the hierarchy change.
3406 gdk_window_flush_if_exposing (GdkWindow *window)
3408 GdkWindowObject *private;
3409 GdkWindowObject *impl_window;
3411 private = (GdkWindowObject *) window;
3412 impl_window = gdk_window_get_impl_window (private);
3414 /* If we're in an implicit paint (i.e. in an expose handler, flush
3415 all the already finished exposes to get things to an uptodate state. */
3416 if (impl_window->implicit_paint)
3417 gdk_window_flush (window);
3422 gdk_window_flush_recursive_helper (GdkWindowObject *window,
3425 GdkWindowObject *child;
3428 for (l = window->children; l != NULL; l = l->next)
3432 if (child->impl == impl)
3433 /* Same impl, ignore */
3434 gdk_window_flush_recursive_helper (child, impl);
3436 gdk_window_flush_recursive (child);
3441 gdk_window_flush_recursive (GdkWindowObject *window)
3443 gdk_window_flush ((GdkWindow *)window);
3444 gdk_window_flush_recursive_helper (window, window->impl);
3447 static cairo_region_t*
3448 gdk_window_get_clip_region (GdkDrawable *drawable)
3450 GdkWindowObject *private = (GdkWindowObject *)drawable;
3451 cairo_region_t *result;
3453 result = cairo_region_copy (private->clip_region);
3455 if (private->paint_stack)
3457 cairo_region_t *paint_region = cairo_region_create ();
3458 GSList *tmp_list = private->paint_stack;
3462 GdkWindowPaint *paint = tmp_list->data;
3464 cairo_region_union (paint_region, paint->region);
3466 tmp_list = tmp_list->next;
3469 cairo_region_intersect (result, paint_region);
3470 cairo_region_destroy (paint_region);
3476 static cairo_region_t*
3477 gdk_window_get_visible_region (GdkDrawable *drawable)
3479 GdkWindowObject *private = (GdkWindowObject*) drawable;
3481 return cairo_region_copy (private->clip_region);
3485 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3487 GdkWindowObject *private = (GdkWindowObject *) window;
3488 GdkWindowObject *bg_private;
3489 cairo_pattern_t *pattern = NULL;
3490 int x_offset = 0, y_offset = 0;
3493 cr = cairo_create (paint->surface);
3495 for (bg_private = private; bg_private; bg_private = bg_private->parent)
3497 pattern = gdk_window_get_background_pattern ((GdkWindow *) bg_private);
3501 x_offset += bg_private->x;
3502 y_offset += bg_private->y;
3507 cairo_translate (cr, -x_offset, -y_offset);
3508 cairo_set_source (cr, pattern);
3509 cairo_translate (cr, x_offset, y_offset);
3512 cairo_set_source_rgb (cr, 0, 0, 0);
3518 gdk_window_clear_backing_region (GdkWindow *window,
3519 cairo_region_t *region)
3521 GdkWindowObject *private = (GdkWindowObject *)window;
3522 GdkWindowPaint *paint = private->paint_stack->data;
3523 cairo_region_t *clip;
3524 GdkRectangle clipbox;
3527 if (GDK_WINDOW_DESTROYED (window))
3530 cr = setup_backing_rect (window, paint, 0, 0);
3532 clip = cairo_region_copy (paint->region);
3533 cairo_region_intersect (clip, region);
3534 cairo_region_get_extents (clip, &clipbox);
3536 gdk_cairo_region (cr, clip);
3541 cairo_region_destroy (clip);
3545 gdk_window_clear_backing_region_direct (GdkWindow *window,
3546 cairo_region_t *region)
3548 GdkWindowObject *private = (GdkWindowObject *)window;
3549 GdkWindowPaint paint;
3550 cairo_region_t *clip;
3551 GdkRectangle clipbox;
3554 if (GDK_WINDOW_DESTROYED (window))
3557 paint.surface = _gdk_drawable_ref_cairo_surface (window);
3559 cr = setup_backing_rect (window, &paint, 0, 0);
3561 clip = cairo_region_copy (private->clip_region_with_children);
3562 cairo_region_intersect (clip, region);
3563 cairo_region_get_extents (clip, &clipbox);
3565 gdk_cairo_region (cr, clip);
3570 cairo_region_destroy (clip);
3571 cairo_surface_destroy (paint.surface);
3577 * @window: a #GdkWindow
3579 * Clears an entire @window to the background pattern.
3582 gdk_window_clear (GdkWindow *window)
3586 g_return_if_fail (GDK_IS_WINDOW (window));
3588 gdk_drawable_get_size (GDK_DRAWABLE (window), &width, &height);
3590 gdk_window_clear_area (window, 0, 0,
3595 gdk_window_clear_region_internal (GdkWindow *window,
3596 cairo_region_t *region)
3598 GdkWindowObject *private = (GdkWindowObject *)window;
3600 if (private->paint_stack)
3601 gdk_window_clear_backing_region (window, region);
3603 gdk_window_clear_backing_region_direct (window, region);
3607 * gdk_window_clear_area:
3608 * @window: a #GdkWindow
3609 * @x: x coordinate of rectangle to clear
3610 * @y: y coordinate of rectangle to clear
3611 * @width: width of rectangle to clear
3612 * @height: height of rectangle to clear
3614 * Clears an area of @window to the background pattern.
3617 gdk_window_clear_area (GdkWindow *window,
3624 cairo_region_t *region;
3626 g_return_if_fail (GDK_IS_WINDOW (window));
3628 if (GDK_WINDOW_DESTROYED (window))
3631 /* Terminate early to avoid weird interpretation of
3632 zero width/height by XClearArea */
3633 if (width == 0 || height == 0)
3639 rect.height = height;
3641 region = cairo_region_create_rectangle (&rect);
3642 gdk_window_clear_region_internal (window,
3644 cairo_region_destroy (region);
3648 gdk_window_real_get_size (GdkDrawable *drawable,
3652 GdkWindowObject *private = (GdkWindowObject *)drawable;
3655 *width = private->width;
3657 *height = private->height;
3661 gdk_window_drop_cairo_surface (GdkWindowObject *private)
3663 if (private->cairo_surface)
3665 cairo_surface_finish (private->cairo_surface);
3666 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3668 private->cairo_surface = NULL;
3673 gdk_window_cairo_surface_destroy (void *data)
3675 GdkWindowObject *private = (GdkWindowObject*) data;
3677 private->cairo_surface = NULL;
3678 private->impl_window->outstanding_surfaces--;
3681 static cairo_surface_t *
3682 gdk_window_create_cairo_surface (GdkDrawable *drawable,
3686 GdkWindowObject *private = GDK_WINDOW_OBJECT(drawable);
3687 cairo_surface_t *surface, *subsurface;
3689 surface =_gdk_drawable_ref_cairo_surface (private->impl);
3690 if (gdk_window_has_impl (private))
3693 subsurface = cairo_surface_create_for_rectangle (surface,
3698 cairo_surface_destroy (surface);
3703 static cairo_surface_t *
3704 gdk_window_ref_cairo_surface (GdkDrawable *drawable)
3706 GdkWindowObject *private = (GdkWindowObject*) drawable;
3707 cairo_surface_t *surface;
3709 if (private->paint_stack)
3711 GdkWindowPaint *paint = private->paint_stack->data;
3713 surface = paint->surface;
3714 cairo_surface_reference (surface);
3719 /* This will be drawing directly to the window, so flush implicit paint */
3720 gdk_window_flush ((GdkWindow *)drawable);
3722 if (!private->cairo_surface)
3724 private->cairo_surface = _gdk_drawable_create_cairo_surface (drawable,
3728 if (private->cairo_surface)
3730 private->impl_window->outstanding_surfaces++;
3732 cairo_surface_set_user_data (private->cairo_surface, &gdk_window_cairo_key,
3733 drawable, gdk_window_cairo_surface_destroy);
3737 cairo_surface_reference (private->cairo_surface);
3739 surface = private->cairo_surface;
3746 gdk_window_set_cairo_clip (GdkDrawable *drawable,
3749 GdkWindowObject *private = (GdkWindowObject*) drawable;
3751 if (!private->paint_stack)
3753 cairo_reset_clip (cr);
3756 cairo_identity_matrix (cr);
3758 cairo_new_path (cr);
3759 gdk_cairo_region (cr, private->clip_region_with_children);
3766 GdkWindowPaint *paint = private->paint_stack->data;
3768 /* Only needs to clip to region if piggybacking
3769 on an implicit paint */
3770 cairo_reset_clip (cr);
3771 if (paint->uses_implicit)
3774 cairo_identity_matrix (cr);
3776 cairo_new_path (cr);
3777 gdk_cairo_region (cr, paint->region);
3785 /* Code for dirty-region queueing
3787 static GSList *update_windows = NULL;
3788 static guint update_idle = 0;
3789 static gboolean debug_updates = FALSE;
3791 static inline gboolean
3792 gdk_window_is_ancestor (GdkWindow *window,
3793 GdkWindow *ancestor)
3797 GdkWindow *parent = (GdkWindow*) ((GdkWindowObject*) window)->parent;
3799 if (parent == ancestor)
3809 gdk_window_add_update_window (GdkWindow *window)
3812 GSList *prev = NULL;
3813 gboolean has_ancestor_in_list = FALSE;
3815 for (tmp = update_windows; tmp; tmp = tmp->next)
3817 GdkWindowObject *parent = GDK_WINDOW_OBJECT (window)->parent;
3819 /* check if tmp is an ancestor of "window"; if it is, set a
3820 * flag indicating that all following windows are either
3821 * children of "window" or from a differen hierarchy
3823 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3824 has_ancestor_in_list = TRUE;
3826 /* insert in reverse stacking order when adding around siblings,
3827 * so processing updates properly paints over lower stacked windows
3829 if (parent == GDK_WINDOW_OBJECT (tmp->data)->parent)
3831 gint index = g_list_index (parent->children, window);
3832 for (; tmp && parent == GDK_WINDOW_OBJECT (tmp->data)->parent; tmp = tmp->next)
3834 gint sibling_index = g_list_index (parent->children, tmp->data);
3835 if (index > sibling_index)
3839 /* here, tmp got advanced past all lower stacked siblings */
3840 tmp = g_slist_prepend (tmp, window);
3844 update_windows = tmp;
3848 /* if "window" has an ancestor in the list and tmp is one of
3849 * "window's" children, insert "window" before tmp
3851 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3853 tmp = g_slist_prepend (tmp, window);
3858 update_windows = tmp;
3862 /* if we're at the end of the list and had an ancestor it it,
3863 * append to the list
3865 if (! tmp->next && has_ancestor_in_list)
3867 tmp = g_slist_append (tmp, window);
3874 /* if all above checks failed ("window" is from a different
3875 * hierarchy than what is already in the list) or the list is
3878 update_windows = g_slist_prepend (update_windows, window);
3882 gdk_window_remove_update_window (GdkWindow *window)
3884 update_windows = g_slist_remove (update_windows, window);
3888 gdk_window_update_idle (gpointer data)
3890 gdk_window_process_all_updates ();
3896 gdk_window_is_toplevel_frozen (GdkWindow *window)
3898 GdkWindowObject *toplevel;
3900 toplevel = (GdkWindowObject *)gdk_window_get_toplevel (window);
3902 return toplevel->update_and_descendants_freeze_count > 0;
3906 gdk_window_schedule_update (GdkWindow *window)
3909 (GDK_WINDOW_OBJECT (window)->update_freeze_count ||
3910 gdk_window_is_toplevel_frozen (window)))
3915 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
3916 gdk_window_update_idle,
3921 _gdk_window_process_updates_recurse (GdkWindow *window,
3922 cairo_region_t *expose_region)
3924 GdkWindowObject *private = (GdkWindowObject *)window;
3925 GdkWindowObject *child;
3926 cairo_region_t *child_region;
3928 GList *l, *children;
3930 if (cairo_region_is_empty (expose_region))
3933 if (gdk_window_is_offscreen (private->impl_window) &&
3934 private == private->impl_window)
3935 _gdk_window_add_damage ((GdkWindow *) private->impl_window, expose_region);
3937 /* Make this reentrancy safe for expose handlers freeing windows */
3938 children = g_list_copy (private->children);
3939 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3941 /* Iterate over children, starting at topmost */
3942 for (l = children; l != NULL; l = l->next)
3946 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3949 /* Ignore offscreen children, as they don't draw in their parent and
3950 * don't take part in the clipping */
3951 if (gdk_window_is_offscreen (child))
3956 r.width = child->width;
3957 r.height = child->height;
3959 child_region = cairo_region_create_rectangle (&r);
3962 /* Adjust shape region to parent window coords */
3963 cairo_region_translate (child->shape, child->x, child->y);
3964 cairo_region_intersect (child_region, child->shape);
3965 cairo_region_translate (child->shape, -child->x, -child->y);
3968 if (child->impl == private->impl)
3970 /* Client side child, expose */
3971 cairo_region_intersect (child_region, expose_region);
3972 cairo_region_subtract (expose_region, child_region);
3973 cairo_region_translate (child_region, -child->x, -child->y);
3974 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
3978 /* Native child, just remove area from expose region */
3979 cairo_region_subtract (expose_region, child_region);
3981 cairo_region_destroy (child_region);
3984 g_list_foreach (children, (GFunc)g_object_unref, NULL);
3985 g_list_free (children);
3987 if (!cairo_region_is_empty (expose_region) &&
3988 !private->destroyed)
3990 if (private->event_mask & GDK_EXPOSURE_MASK)
3994 event.expose.type = GDK_EXPOSE;
3995 event.expose.window = g_object_ref (window);
3996 event.expose.send_event = FALSE;
3997 event.expose.count = 0;
3998 event.expose.region = expose_region;
3999 cairo_region_get_extents (expose_region, &event.expose.area);
4001 (*_gdk_event_func) (&event, _gdk_event_data);
4003 g_object_unref (window);
4005 else if (private->window_type != GDK_WINDOW_FOREIGN)
4007 /* No exposure mask set, so nothing will be drawn, the
4008 * app relies on the background being what it specified
4009 * for the window. So, we need to clear this manually.
4011 * For foreign windows if expose is not set that generally
4012 * means some other client paints them, so don't clear
4015 * We use begin/end_paint around the clear so that we can
4016 * piggyback on the implicit paint */
4018 gdk_window_begin_paint_region (window, expose_region);
4019 gdk_window_clear_region_internal (window, expose_region);
4020 gdk_window_end_paint (window);
4025 /* Process and remove any invalid area on the native window by creating
4026 * expose events for the window and all non-native descendants.
4027 * Also processes any outstanding moves on the window before doing
4028 * any drawing. Note that its possible to have outstanding moves without
4029 * any invalid area as we use the update idle mechanism to coalesce
4030 * multiple moves as well as multiple invalidations.
4033 gdk_window_process_updates_internal (GdkWindow *window)
4035 GdkWindowObject *private = (GdkWindowObject *)window;
4036 GdkWindowImplIface *impl_iface;
4037 gboolean save_region = FALSE;
4038 GdkRectangle clip_box;
4040 /* Ensure the window lives while updating it */
4041 g_object_ref (window);
4043 /* If an update got queued during update processing, we can get a
4044 * window in the update queue that has an empty update_area.
4047 if (private->update_area)
4049 cairo_region_t *update_area = private->update_area;
4050 private->update_area = NULL;
4052 if (_gdk_event_func && gdk_window_is_viewable (window))
4054 cairo_region_t *expose_region;
4055 gboolean end_implicit;
4057 /* Clip to part visible in toplevel */
4058 cairo_region_intersect (update_area, private->clip_region);
4062 /* Make sure we see the red invalid area before redrawing. */
4063 gdk_display_sync (gdk_window_get_display (window));
4067 /* At this point we will be completely redrawing all of update_area.
4068 * If we have any outstanding moves that end up moving stuff inside
4069 * this area we don't actually need to move that as that part would
4070 * be overdrawn by the expose anyway. So, in order to copy less data
4071 * we remove these areas from the outstanding moves.
4073 if (private->outstanding_moves)
4075 GdkWindowRegionMove *move;
4076 cairo_region_t *remove;
4079 remove = cairo_region_copy (update_area);
4080 /* We iterate backwards, starting from the state that would be
4081 if we had applied all the moves. */
4082 for (l = g_list_last (private->outstanding_moves); l != NULL; l = prev)
4087 /* Don't need this area */
4088 cairo_region_subtract (move->dest_region, remove);
4090 /* However if any of the destination we do need has a source
4091 in the updated region we do need that as a destination for
4092 the earlier moves */
4093 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
4094 cairo_region_subtract (remove, move->dest_region);
4096 if (cairo_region_is_empty (move->dest_region))
4098 gdk_window_region_move_free (move);
4099 private->outstanding_moves =
4100 g_list_delete_link (private->outstanding_moves, l);
4102 else /* move back */
4103 cairo_region_translate (move->dest_region, move->dx, move->dy);
4105 cairo_region_destroy (remove);
4108 /* By now we a set of window moves that should be applied, and then
4109 * an update region that should be repainted. A trivial implementation
4110 * would just do that in order, however in order to get nicer drawing
4111 * we do some tricks:
4113 * First of all, each subwindow expose may be double buffered by
4114 * itself (depending on widget setting) via
4115 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
4116 * creating a single surface the size of the invalid area on the
4117 * native window which all the individual normal paints will draw
4118 * into. This way in the normal case there will be only one surface
4119 * allocated and only once surface draw done for all the windows
4120 * in this native window.
4121 * There are a couple of reasons this may fail, for instance, some
4122 * backends (like quartz) do its own double buffering, so we disable
4123 * gdk double buffering there. Secondly, some subwindow could be
4124 * non-double buffered and draw directly to the window outside a
4125 * begin/end_paint pair. That will be lead to a gdk_window_flush
4126 * which immediately executes all outstanding moves and paints+removes
4127 * the implicit paint (further paints will allocate their own surfaces).
4129 * Secondly, in the case of implicit double buffering we expose all
4130 * the child windows into the implicit surface before we execute
4131 * the outstanding moves. This way we minimize the time between
4132 * doing the moves and rendering the new update area, thus minimizing
4133 * flashing. Of course, if any subwindow is non-double buffered we
4134 * well flush earlier than that.
4136 * Thirdly, after having done the outstanding moves we queue an
4137 * "antiexpose" on the area that will be drawn by the expose, which
4138 * means that any invalid region on the native window side before
4139 * the first expose drawing operation will be discarded, as it
4140 * has by then been overdrawn with valid data. This means we can
4141 * avoid doing the unnecessary repaint any outstanding expose events.
4144 cairo_region_get_extents (update_area, &clip_box);
4145 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
4146 expose_region = cairo_region_copy (update_area);
4149 /* Rendering is not double buffered by gdk, do outstanding
4150 * moves and queue antiexposure immediately. No need to do
4152 gdk_window_flush_outstanding_moves (window);
4153 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4154 save_region = impl_iface->queue_antiexpose (window, update_area);
4157 /* Render the invalid areas to the implicit paint, by sending exposes.
4158 * May flush if non-double buffered widget draw. */
4159 _gdk_windowing_window_process_updates_recurse (window, expose_region);
4163 /* Do moves right before exposes are rendered to the window */
4164 gdk_window_flush_outstanding_moves (window);
4166 /* By this time we know that any outstanding expose for this
4167 * area is invalid and we can avoid it, so queue an antiexpose.
4168 * However, it may be that due to an non-double buffered expose
4169 * we have already started drawing to the window, so it would
4170 * be to late to anti-expose now. Since this is merely an
4171 * optimization we just avoid doing it at all in that case.
4173 if (private->implicit_paint != NULL &&
4174 !private->implicit_paint->flushed)
4176 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
4177 save_region = impl_iface->queue_antiexpose (window, update_area);
4180 gdk_window_end_implicit_paint (window);
4182 cairo_region_destroy (expose_region);
4185 cairo_region_destroy (update_area);
4188 if (private->outstanding_moves)
4190 /* Flush any outstanding moves, may happen if we moved a window but got
4191 no actual invalid area */
4192 gdk_window_flush_outstanding_moves (window);
4195 g_object_unref (window);
4199 flush_all_displays (void)
4201 GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4204 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
4205 gdk_display_flush (tmp_list->data);
4207 g_slist_free (displays);
4210 /* Currently it is not possible to override
4211 * gdk_window_process_all_updates in the same manner as
4212 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4213 * by implementing the GdkPaintable interface. If in the future a
4214 * backend would need this, the right solution would be to add a
4215 * method to GdkDisplay that can be optionally
4216 * NULL. gdk_window_process_all_updates can then walk the list of open
4217 * displays and call the mehod.
4221 * gdk_window_process_all_updates:
4223 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4224 * in the application.
4228 gdk_window_process_all_updates (void)
4230 GSList *old_update_windows = update_windows;
4231 GSList *tmp_list = update_windows;
4232 static gboolean in_process_all_updates = FALSE;
4233 static gboolean got_recursive_update = FALSE;
4235 if (in_process_all_updates)
4237 /* We can't do this now since that would recurse, so
4238 delay it until after the recursion is done. */
4239 got_recursive_update = TRUE;
4244 in_process_all_updates = TRUE;
4245 got_recursive_update = FALSE;
4248 g_source_remove (update_idle);
4250 update_windows = NULL;
4253 _gdk_windowing_before_process_all_updates ();
4255 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4259 GdkWindowObject *private = (GdkWindowObject *)tmp_list->data;
4261 if (!GDK_WINDOW_DESTROYED (tmp_list->data))
4263 if (private->update_freeze_count ||
4264 gdk_window_is_toplevel_frozen (tmp_list->data))
4265 gdk_window_add_update_window ((GdkWindow *) private);
4267 gdk_window_process_updates_internal (tmp_list->data);
4270 g_object_unref (tmp_list->data);
4271 tmp_list = tmp_list->next;
4274 g_slist_free (old_update_windows);
4276 flush_all_displays ();
4278 _gdk_windowing_after_process_all_updates ();
4280 in_process_all_updates = FALSE;
4282 /* If we ignored a recursive call, schedule a
4283 redraw now so that it eventually happens,
4284 otherwise we could miss an update if nothing
4285 else schedules an update. */
4286 if (got_recursive_update && !update_idle)
4288 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4289 gdk_window_update_idle,
4294 * gdk_window_process_updates:
4295 * @window: a #GdkWindow
4296 * @update_children: whether to also process updates for child windows
4298 * Sends one or more expose events to @window. The areas in each
4299 * expose event will cover the entire update area for the window (see
4300 * gdk_window_invalidate_region() for details). Normally GDK calls
4301 * gdk_window_process_all_updates() on your behalf, so there's no
4302 * need to call this function unless you want to force expose events
4303 * to be delivered immediately and synchronously (vs. the usual
4304 * case, where GDK delivers them in an idle handler). Occasionally
4305 * this is useful to produce nicer scrolling behavior, for example.
4309 gdk_window_process_updates (GdkWindow *window,
4310 gboolean update_children)
4312 GdkWindowObject *private = (GdkWindowObject *)window;
4313 GdkWindowObject *impl_window;
4315 g_return_if_fail (GDK_IS_WINDOW (window));
4317 if (GDK_WINDOW_DESTROYED (window))
4320 /* Make sure the window lives during the expose callouts */
4321 g_object_ref (window);
4323 impl_window = gdk_window_get_impl_window (private);
4324 if ((impl_window->update_area ||
4325 impl_window->outstanding_moves) &&
4326 !impl_window->update_freeze_count &&
4327 !gdk_window_is_toplevel_frozen (window) &&
4329 /* Don't recurse into process_updates_internal, we'll
4330 * do the update later when idle instead. */
4331 impl_window->implicit_paint == NULL)
4333 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4334 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4337 if (update_children)
4339 /* process updates in reverse stacking order so composition or
4340 * painting over achieves the desired effect for offscreen windows
4342 GList *node, *children;
4344 children = g_list_copy (private->children);
4345 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4347 for (node = g_list_last (children); node; node = node->prev)
4349 gdk_window_process_updates (node->data, TRUE);
4350 g_object_unref (node->data);
4353 g_list_free (children);
4356 g_object_unref (window);
4360 gdk_window_invalidate_rect_full (GdkWindow *window,
4361 const GdkRectangle *rect,
4362 gboolean invalidate_children,
4365 GdkRectangle window_rect;
4366 cairo_region_t *region;
4367 GdkWindowObject *private = (GdkWindowObject *)window;
4369 g_return_if_fail (GDK_IS_WINDOW (window));
4371 if (GDK_WINDOW_DESTROYED (window))
4374 if (private->input_only || !private->viewable)
4381 gdk_drawable_get_size (GDK_DRAWABLE (window),
4383 &window_rect.height);
4384 rect = &window_rect;
4387 region = cairo_region_create_rectangle (rect);
4388 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4389 cairo_region_destroy (region);
4393 * gdk_window_invalidate_rect:
4394 * @window: a #GdkWindow
4395 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4397 * @invalidate_children: whether to also invalidate child windows
4399 * A convenience wrapper around gdk_window_invalidate_region() which
4400 * invalidates a rectangular region. See
4401 * gdk_window_invalidate_region() for details.
4404 gdk_window_invalidate_rect (GdkWindow *window,
4405 const GdkRectangle *rect,
4406 gboolean invalidate_children)
4408 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4412 draw_ugly_color (GdkWindow *window,
4413 const cairo_region_t *region)
4417 cr = gdk_cairo_create (window);
4418 /* Draw ugly color all over the newly-invalid region */
4419 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4420 gdk_cairo_region (cr, region);
4427 impl_window_add_update_area (GdkWindowObject *impl_window,
4428 cairo_region_t *region)
4430 if (impl_window->update_area)
4431 cairo_region_union (impl_window->update_area, region);
4434 gdk_window_add_update_window ((GdkWindow *)impl_window);
4435 impl_window->update_area = cairo_region_copy (region);
4436 gdk_window_schedule_update ((GdkWindow *)impl_window);
4440 /* clear_bg controls if the region will be cleared to
4441 * the background pattern if the exposure mask is not
4442 * set for the window, whereas this might not otherwise be
4443 * done (unless necessary to emulate background settings).
4444 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4445 * need to clear the background, such as when exposing the area beneath a
4446 * hidden or moved window, but not when an app requests repaint or when the
4447 * windowing system exposes a newly visible area (because then the windowing
4448 * system has already cleared the area).
4451 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4452 const cairo_region_t *region,
4454 gboolean (*child_func) (GdkWindow *,
4458 GdkWindowObject *private = (GdkWindowObject *)window;
4459 GdkWindowObject *impl_window;
4460 cairo_region_t *visible_region;
4463 g_return_if_fail (GDK_IS_WINDOW (window));
4465 if (GDK_WINDOW_DESTROYED (window))
4468 if (private->input_only ||
4469 !private->viewable ||
4470 cairo_region_is_empty (region) ||
4471 private->window_type == GDK_WINDOW_ROOT)
4474 visible_region = gdk_drawable_get_visible_region (window);
4475 cairo_region_intersect (visible_region, region);
4477 tmp_list = private->children;
4480 GdkWindowObject *child = tmp_list->data;
4482 if (!child->input_only)
4484 cairo_region_t *child_region;
4485 GdkRectangle child_rect;
4487 child_rect.x = child->x;
4488 child_rect.y = child->y;
4489 child_rect.width = child->width;
4490 child_rect.height = child->height;
4491 child_region = cairo_region_create_rectangle (&child_rect);
4493 /* remove child area from the invalid area of the parent */
4494 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4495 !child->composited &&
4496 !gdk_window_is_offscreen (child))
4497 cairo_region_subtract (visible_region, child_region);
4499 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4501 cairo_region_t *tmp = cairo_region_copy (region);
4503 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4504 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4505 cairo_region_intersect (child_region, tmp);
4507 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4508 child_region, clear_bg, child_func, user_data);
4510 cairo_region_destroy (tmp);
4513 cairo_region_destroy (child_region);
4516 tmp_list = tmp_list->next;
4519 impl_window = gdk_window_get_impl_window (private);
4521 if (!cairo_region_is_empty (visible_region) ||
4522 /* Even if we're not exposing anything, make sure we process
4523 idles for windows with outstanding moves */
4524 (impl_window->outstanding_moves != NULL &&
4525 impl_window->update_area == NULL))
4528 draw_ugly_color (window, region);
4530 /* Convert to impl coords */
4531 cairo_region_translate (visible_region, private->abs_x, private->abs_y);
4533 /* Only invalidate area if app requested expose events or if
4534 we need to clear the area (by request or to emulate background
4535 clearing for non-native windows or native windows with no support
4536 for window backgrounds */
4537 if (private->event_mask & GDK_EXPOSURE_MASK ||
4538 clear_bg == CLEAR_BG_ALL ||
4539 clear_bg == CLEAR_BG_WINCLEARED)
4540 impl_window_add_update_area (impl_window, visible_region);
4543 cairo_region_destroy (visible_region);
4547 * gdk_window_invalidate_maybe_recurse:
4548 * @window: a #GdkWindow
4549 * @region: a #cairo_region_t
4550 * @child_func: function to use to decide if to recurse to a child,
4551 * %NULL means never recurse.
4552 * @user_data: data passed to @child_func
4554 * Adds @region to the update area for @window. The update area is the
4555 * region that needs to be redrawn, or "dirty region." The call
4556 * gdk_window_process_updates() sends one or more expose events to the
4557 * window, which together cover the entire update area. An
4558 * application would normally redraw the contents of @window in
4559 * response to those expose events.
4561 * GDK will call gdk_window_process_all_updates() on your behalf
4562 * whenever your program returns to the main loop and becomes idle, so
4563 * normally there's no need to do that manually, you just need to
4564 * invalidate regions that you know should be redrawn.
4566 * The @child_func parameter controls whether the region of
4567 * each child window that intersects @region will also be invalidated.
4568 * Only children for which @child_func returns TRUE will have the area
4572 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4573 const cairo_region_t *region,
4574 gboolean (*child_func) (GdkWindow *,
4578 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4579 child_func, user_data);
4583 true_predicate (GdkWindow *window,
4590 gdk_window_invalidate_region_full (GdkWindow *window,
4591 const cairo_region_t *region,
4592 gboolean invalidate_children,
4595 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4596 invalidate_children ?
4597 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4602 * gdk_window_invalidate_region:
4603 * @window: a #GdkWindow
4604 * @region: a #cairo_region_t
4605 * @invalidate_children: %TRUE to also invalidate child windows
4607 * Adds @region to the update area for @window. The update area is the
4608 * region that needs to be redrawn, or "dirty region." The call
4609 * gdk_window_process_updates() sends one or more expose events to the
4610 * window, which together cover the entire update area. An
4611 * application would normally redraw the contents of @window in
4612 * response to those expose events.
4614 * GDK will call gdk_window_process_all_updates() on your behalf
4615 * whenever your program returns to the main loop and becomes idle, so
4616 * normally there's no need to do that manually, you just need to
4617 * invalidate regions that you know should be redrawn.
4619 * The @invalidate_children parameter controls whether the region of
4620 * each child window that intersects @region will also be invalidated.
4621 * If %FALSE, then the update area for child windows will remain
4622 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4623 * fine grained control over which children are invalidated.
4626 gdk_window_invalidate_region (GdkWindow *window,
4627 const cairo_region_t *region,
4628 gboolean invalidate_children)
4630 gdk_window_invalidate_maybe_recurse (window, region,
4631 invalidate_children ?
4632 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4637 * _gdk_window_invalidate_for_expose:
4638 * @window: a #GdkWindow
4639 * @region: a #cairo_region_t
4641 * Adds @region to the update area for @window. The update area is the
4642 * region that needs to be redrawn, or "dirty region." The call
4643 * gdk_window_process_updates() sends one or more expose events to the
4644 * window, which together cover the entire update area. An
4645 * application would normally redraw the contents of @window in
4646 * response to those expose events.
4648 * GDK will call gdk_window_process_all_updates() on your behalf
4649 * whenever your program returns to the main loop and becomes idle, so
4650 * normally there's no need to do that manually, you just need to
4651 * invalidate regions that you know should be redrawn.
4653 * This version of invalidation is used when you recieve expose events
4654 * from the native window system. It exposes the native window, plus
4655 * any non-native child windows (but not native child windows, as those would
4656 * have gotten their own expose events).
4659 _gdk_window_invalidate_for_expose (GdkWindow *window,
4660 cairo_region_t *region)
4662 GdkWindowObject *private = (GdkWindowObject *) window;
4663 GdkWindowRegionMove *move;
4664 cairo_region_t *move_region;
4667 /* Any invalidations comming from the windowing system will
4668 be in areas that may be moved by outstanding moves,
4669 so we need to modify the expose region correspondingly,
4670 otherwise we would expose in the wrong place, as the
4671 outstanding moves will be copied before we draw the
4673 for (l = private->outstanding_moves; l != NULL; l = l->next)
4677 /* covert to move source region */
4678 move_region = cairo_region_copy (move->dest_region);
4679 cairo_region_translate (move_region, -move->dx, -move->dy);
4681 /* Move area of region that intersects with move source
4682 by dx, dy of the move*/
4683 cairo_region_intersect (move_region, region);
4684 cairo_region_subtract (region, move_region);
4685 cairo_region_translate (move_region, move->dx, move->dy);
4686 cairo_region_union (region, move_region);
4688 cairo_region_destroy (move_region);
4691 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4692 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4698 * gdk_window_get_update_area:
4699 * @window: a #GdkWindow
4701 * Transfers ownership of the update area from @window to the caller
4702 * of the function. That is, after calling this function, @window will
4703 * no longer have an invalid/dirty region; the update area is removed
4704 * from @window and handed to you. If a window has no update area,
4705 * gdk_window_get_update_area() returns %NULL. You are responsible for
4706 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4708 * Return value: the update area for @window
4711 gdk_window_get_update_area (GdkWindow *window)
4713 GdkWindowObject *private = (GdkWindowObject *)window;
4714 GdkWindowObject *impl_window;
4715 cairo_region_t *tmp_region;
4717 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4719 impl_window = gdk_window_get_impl_window (private);
4721 if (impl_window->update_area)
4723 tmp_region = cairo_region_copy (private->clip_region_with_children);
4724 /* Convert to impl coords */
4725 cairo_region_translate (tmp_region, private->abs_x, private->abs_y);
4726 cairo_region_intersect (tmp_region, impl_window->update_area);
4728 if (cairo_region_is_empty (tmp_region))
4730 cairo_region_destroy (tmp_region);
4735 cairo_region_subtract (impl_window->update_area, tmp_region);
4737 if (cairo_region_is_empty (impl_window->update_area) &&
4738 impl_window->outstanding_moves == NULL)
4740 cairo_region_destroy (impl_window->update_area);
4741 impl_window->update_area = NULL;
4743 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4746 /* Convert from impl coords */
4747 cairo_region_translate (tmp_region, -private->abs_x, -private->abs_y);
4757 * _gdk_window_clear_update_area:
4758 * @window: a #GdkWindow.
4760 * Internal function to clear the update area for a window. This
4761 * is called when the window is hidden or destroyed.
4764 _gdk_window_clear_update_area (GdkWindow *window)
4766 GdkWindowObject *private = (GdkWindowObject *)window;
4768 g_return_if_fail (GDK_IS_WINDOW (window));
4770 if (private->update_area)
4772 gdk_window_remove_update_window (window);
4774 cairo_region_destroy (private->update_area);
4775 private->update_area = NULL;
4780 * gdk_window_freeze_updates:
4781 * @window: a #GdkWindow
4783 * Temporarily freezes a window such that it won't receive expose
4784 * events. The window will begin receiving expose events again when
4785 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4786 * has been called more than once, gdk_window_thaw_updates() must be called
4787 * an equal number of times to begin processing exposes.
4790 gdk_window_freeze_updates (GdkWindow *window)
4792 GdkWindowObject *private = (GdkWindowObject *)window;
4793 GdkWindowObject *impl_window;
4795 g_return_if_fail (GDK_IS_WINDOW (window));
4797 impl_window = gdk_window_get_impl_window (private);
4798 impl_window->update_freeze_count++;
4802 * gdk_window_thaw_updates:
4803 * @window: a #GdkWindow
4805 * Thaws a window frozen with gdk_window_freeze_updates().
4808 gdk_window_thaw_updates (GdkWindow *window)
4810 GdkWindowObject *private = (GdkWindowObject *)window;
4811 GdkWindowObject *impl_window;
4813 g_return_if_fail (GDK_IS_WINDOW (window));
4815 impl_window = gdk_window_get_impl_window (private);
4817 g_return_if_fail (impl_window->update_freeze_count > 0);
4819 if (--impl_window->update_freeze_count == 0)
4820 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4824 * gdk_window_freeze_toplevel_updates_libgtk_only:
4825 * @window: a #GdkWindow
4827 * Temporarily freezes a window and all its descendants such that it won't
4828 * receive expose events. The window will begin receiving expose events
4829 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4830 * gdk_window_freeze_toplevel_updates_libgtk_only()
4831 * has been called more than once,
4832 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4833 * an equal number of times to begin processing exposes.
4835 * This function is not part of the GDK public API and is only
4839 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4841 GdkWindowObject *private = (GdkWindowObject *)window;
4843 g_return_if_fail (GDK_IS_WINDOW (window));
4844 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4846 private->update_and_descendants_freeze_count++;
4850 * gdk_window_thaw_toplevel_updates_libgtk_only:
4851 * @window: a #GdkWindow
4853 * Thaws a window frozen with
4854 * gdk_window_freeze_toplevel_updates_libgtk_only().
4856 * This function is not part of the GDK public API and is only
4860 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4862 GdkWindowObject *private = (GdkWindowObject *)window;
4864 g_return_if_fail (GDK_IS_WINDOW (window));
4865 g_return_if_fail (private->window_type != GDK_WINDOW_CHILD);
4866 g_return_if_fail (private->update_and_descendants_freeze_count > 0);
4868 private->update_and_descendants_freeze_count--;
4870 gdk_window_schedule_update (window);
4874 * gdk_window_set_debug_updates:
4875 * @setting: %TRUE to turn on update debugging
4877 * With update debugging enabled, calls to
4878 * gdk_window_invalidate_region() clear the invalidated region of the
4879 * screen to a noticeable color, and GDK pauses for a short time
4880 * before sending exposes to windows during
4881 * gdk_window_process_updates(). The net effect is that you can see
4882 * the invalid region for each window and watch redraws as they
4883 * occur. This allows you to diagnose inefficiencies in your application.
4885 * In essence, because the GDK rendering model prevents all flicker,
4886 * if you are redrawing the same region 400 times you may never
4887 * notice, aside from noticing a speed problem. Enabling update
4888 * debugging causes GTK to flicker slowly and noticeably, so you can
4889 * see exactly what's being redrawn when, in what order.
4891 * The --gtk-debug=updates command line option passed to GTK+ programs
4892 * enables this debug option at application startup time. That's
4893 * usually more useful than calling gdk_window_set_debug_updates()
4894 * yourself, though you might want to use this function to enable
4895 * updates sometime after application startup time.
4899 gdk_window_set_debug_updates (gboolean setting)
4901 debug_updates = setting;
4905 * gdk_window_constrain_size:
4906 * @geometry: a #GdkGeometry structure
4907 * @flags: a mask indicating what portions of @geometry are set
4908 * @width: desired width of window
4909 * @height: desired height of the window
4910 * @new_width: location to store resulting width
4911 * @new_height: location to store resulting height
4913 * Constrains a desired width and height according to a
4914 * set of geometry hints (such as minimum and maximum size).
4917 gdk_window_constrain_size (GdkGeometry *geometry,
4924 /* This routine is partially borrowed from fvwm.
4926 * Copyright 1993, Robert Nation
4927 * You may use this code for any purpose, as long as the original
4928 * copyright remains in the source code and all documentation
4930 * which in turn borrows parts of the algorithm from uwm
4933 gint min_height = 0;
4934 gint base_width = 0;
4935 gint base_height = 0;
4938 gint max_width = G_MAXINT;
4939 gint max_height = G_MAXINT;
4941 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4943 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4945 base_width = geometry->base_width;
4946 base_height = geometry->base_height;
4947 min_width = geometry->min_width;
4948 min_height = geometry->min_height;
4950 else if (flags & GDK_HINT_BASE_SIZE)
4952 base_width = geometry->base_width;
4953 base_height = geometry->base_height;
4954 min_width = geometry->base_width;
4955 min_height = geometry->base_height;
4957 else if (flags & GDK_HINT_MIN_SIZE)
4959 base_width = geometry->min_width;
4960 base_height = geometry->min_height;
4961 min_width = geometry->min_width;
4962 min_height = geometry->min_height;
4965 if (flags & GDK_HINT_MAX_SIZE)
4967 max_width = geometry->max_width ;
4968 max_height = geometry->max_height;
4971 if (flags & GDK_HINT_RESIZE_INC)
4973 xinc = MAX (xinc, geometry->width_inc);
4974 yinc = MAX (yinc, geometry->height_inc);
4977 /* clamp width and height to min and max values
4979 width = CLAMP (width, min_width, max_width);
4980 height = CLAMP (height, min_height, max_height);
4982 /* shrink to base + N * inc
4984 width = base_width + FLOOR (width - base_width, xinc);
4985 height = base_height + FLOOR (height - base_height, yinc);
4987 /* constrain aspect ratio, according to:
4990 * min_aspect <= -------- <= max_aspect
4994 if (flags & GDK_HINT_ASPECT &&
4995 geometry->min_aspect > 0 &&
4996 geometry->max_aspect > 0)
5000 if (geometry->min_aspect * height > width)
5002 delta = FLOOR (height - width / geometry->min_aspect, yinc);
5003 if (height - delta >= min_height)
5007 delta = FLOOR (height * geometry->min_aspect - width, xinc);
5008 if (width + delta <= max_width)
5013 if (geometry->max_aspect * height < width)
5015 delta = FLOOR (width - height * geometry->max_aspect, xinc);
5016 if (width - delta >= min_width)
5020 delta = FLOOR (width / geometry->max_aspect - height, yinc);
5021 if (height + delta <= max_height)
5030 *new_height = height;
5034 * gdk_window_get_pointer:
5035 * @window: a #GdkWindow
5036 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
5037 * return the X coordinate
5038 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
5039 * return the Y coordinate
5040 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
5043 * Obtains the current pointer position and modifier state.
5044 * The position is given in coordinates relative to the upper left
5045 * corner of @window.
5047 * Return value: (transfer none): the window containing the pointer (as with
5048 * gdk_window_at_pointer()), or %NULL if the window containing the
5049 * pointer isn't known to GDK
5051 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
5054 gdk_window_get_pointer (GdkWindow *window,
5057 GdkModifierType *mask)
5059 GdkDisplay *display;
5061 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5063 display = gdk_window_get_display (window);
5065 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
5069 * gdk_window_get_device_position:
5070 * @window: a #GdkWindow.
5071 * @device: #GdkDevice to query to.
5072 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
5073 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
5074 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
5076 * Obtains the current device position and modifier state.
5077 * The position is given in coordinates relative to the upper left
5078 * corner of @window.
5080 * Return value: (transfer none): The window underneath @device (as with
5081 * gdk_display_get_window_at_device_position()), or %NULL if the
5082 * window is not known to GDK.
5087 gdk_window_get_device_position (GdkWindow *window,
5091 GdkModifierType *mask)
5093 GdkDisplay *display;
5095 GdkModifierType tmp_mask;
5098 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5099 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
5101 display = gdk_window_get_display (window);
5102 child = display->device_hooks->window_get_device_position (display, device, window,
5103 &tmp_x, &tmp_y, &tmp_mask);
5112 _gdk_display_enable_motion_hints (display, device);
5118 * gdk_window_at_pointer:
5119 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
5120 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
5122 * Obtains the window underneath the mouse pointer, returning the
5123 * location of that window in @win_x, @win_y. Returns %NULL if the
5124 * window under the mouse pointer is not known to GDK (if the window
5125 * belongs to another application and a #GdkWindow hasn't been created
5126 * for it with gdk_window_foreign_new())
5128 * NOTE: For multihead-aware widgets or applications use
5129 * gdk_display_get_window_at_pointer() instead.
5131 * Return value: (transfer none): window under the mouse pointer
5133 * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
5136 gdk_window_at_pointer (gint *win_x,
5139 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
5143 * gdk_get_default_root_window:
5145 * Obtains the root window (parent all other windows are inside)
5146 * for the default display and screen.
5148 * Return value: the default root window
5151 gdk_get_default_root_window (void)
5153 return gdk_screen_get_root_window (gdk_screen_get_default ());
5157 * gdk_window_foreign_new:
5158 * @anid: a native window handle.
5160 * Wraps a native window for the default display in a #GdkWindow.
5161 * This may fail if the window has been destroyed.
5163 * For example in the X backend, a native window handle is an Xlib
5166 * Return value: the newly-created #GdkWindow wrapper for the
5167 * native window or %NULL if the window has been destroyed.
5170 gdk_window_foreign_new (GdkNativeWindow anid)
5172 return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
5176 get_all_native_children (GdkWindowObject *private,
5179 GdkWindowObject *child;
5182 for (l = private->children; l != NULL; l = l->next)
5186 if (gdk_window_has_impl (child))
5187 *native = g_list_prepend (*native, child);
5189 get_all_native_children (child, native);
5195 gdk_window_raise_internal (GdkWindow *window)
5197 GdkWindowObject *private = (GdkWindowObject *)window;
5198 GdkWindowObject *parent = private->parent;
5199 GdkWindowObject *above;
5200 GList *native_children;
5202 GdkWindowImplIface *impl_iface;
5206 parent->children = g_list_remove (parent->children, window);
5207 parent->children = g_list_prepend (parent->children, window);
5210 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5211 /* Just do native raise for toplevels */
5212 if (gdk_window_is_toplevel (private) ||
5213 /* The restack_under codepath should work correctly even if the parent
5214 is native, but it relies on the order of ->children to be correct,
5215 and some apps like SWT reorder the x windows without gdks knowledge,
5216 so we use raise directly in order to make these behave as before
5217 when using native windows */
5218 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5220 impl_iface->raise (window);
5222 else if (gdk_window_has_impl (private))
5224 above = find_native_sibling_above (parent, private);
5227 listhead.data = window;
5228 listhead.next = NULL;
5229 listhead.prev = NULL;
5230 impl_iface->restack_under ((GdkWindow *)above,
5234 impl_iface->raise (window);
5238 native_children = NULL;
5239 get_all_native_children (private, &native_children);
5240 if (native_children != NULL)
5242 above = find_native_sibling_above (parent, private);
5245 impl_iface->restack_under ((GdkWindow *)above,
5249 /* Right order, since native_children is bottom-topmost first */
5250 for (l = native_children; l != NULL; l = l->next)
5251 impl_iface->raise (l->data);
5254 g_list_free (native_children);
5260 /* Returns TRUE If the native window was mapped or unmapped */
5262 set_viewable (GdkWindowObject *w,
5265 GdkWindowObject *child;
5266 GdkWindowImplIface *impl_iface;
5269 if (w->viewable == val)
5275 recompute_visible_regions (w, FALSE, FALSE);
5277 for (l = w->children; l != NULL; l = l->next)
5281 if (GDK_WINDOW_IS_MAPPED (child) &&
5282 child->window_type != GDK_WINDOW_FOREIGN)
5283 set_viewable (child, val);
5286 if (!_gdk_native_windows &&
5287 gdk_window_has_impl (w) &&
5288 w->window_type != GDK_WINDOW_FOREIGN &&
5289 !gdk_window_is_toplevel (w))
5291 /* For most native windows we show/hide them not when they are
5292 * mapped/unmapped, because that may not produce the correct results.
5293 * For instance, if a native window have a non-native parent which is
5294 * hidden, but its native parent is viewable then showing the window
5295 * would make it viewable to X but its not viewable wrt the non-native
5296 * hierarchy. In order to handle this we track the gdk side viewability
5297 * and only map really viewable windows.
5299 * There are two exceptions though:
5301 * For foreign windows we don't want ever change the mapped state
5302 * except when explicitly done via gdk_window_show/hide, as this may
5303 * cause problems for client owning the foreign window when its window
5304 * is suddenly mapped or unmapped.
5306 * For toplevel windows embedded in a foreign window (e.g. a plug)
5307 * we sometimes synthesize a map of a window, but the native
5308 * window is really shown by the embedder, so we don't want to
5309 * do the show ourselves. We can't really tell this case from the normal
5310 * toplevel show as such toplevels are seen by gdk as parents of the
5311 * root window, so we make an exception for all toplevels.
5313 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
5314 * like this, so we just always show/hide directly.
5317 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (w->impl);
5319 impl_iface->show ((GdkWindow *)w, FALSE);
5321 impl_iface->hide ((GdkWindow *)w);
5329 /* Returns TRUE If the native window was mapped or unmapped */
5331 _gdk_window_update_viewable (GdkWindow *window)
5333 GdkWindowObject *priv = (GdkWindowObject *)window;
5336 if (priv->window_type == GDK_WINDOW_FOREIGN ||
5337 priv->window_type == GDK_WINDOW_ROOT)
5339 else if (gdk_window_is_toplevel (priv) ||
5340 priv->parent->viewable)
5341 viewable = GDK_WINDOW_IS_MAPPED (priv);
5345 return set_viewable (priv, viewable);
5349 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5351 GdkWindowObject *private;
5352 GdkWindowImplIface *impl_iface;
5353 gboolean was_mapped, was_viewable;
5356 g_return_if_fail (GDK_IS_WINDOW (window));
5358 private = (GdkWindowObject *) window;
5359 if (private->destroyed)
5362 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5363 was_viewable = private->viewable;
5366 /* Keep children in (reverse) stacking order */
5367 gdk_window_raise_internal (window);
5369 if (gdk_window_has_impl (private))
5372 gdk_synthesize_window_state (window,
5373 GDK_WINDOW_STATE_WITHDRAWN,
5381 did_show = _gdk_window_update_viewable (window);
5383 /* If it was already viewable the backend show op won't be called, call it
5384 again to ensure things happen right if the mapped tracking was not right
5385 for e.g. a foreign window.
5386 Dunno if this is strictly needed but its what happened pre-csw.
5387 Also show if not done by gdk_window_update_viewable. */
5388 if (gdk_window_has_impl (private) && (was_viewable || !did_show))
5390 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5391 impl_iface->show ((GdkWindow *)private,
5392 !did_show ? was_mapped : TRUE);
5395 if (!was_mapped && !gdk_window_has_impl (private))
5397 if (private->event_mask & GDK_STRUCTURE_MASK)
5398 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5400 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5401 _gdk_make_event (GDK_WINDOW (private), GDK_MAP, NULL, FALSE);
5404 if (!was_mapped || raise)
5406 recompute_visible_regions (private, TRUE, FALSE);
5408 /* If any decendants became visible we need to send visibility notify */
5409 gdk_window_update_visibility_recursively (private, NULL);
5411 if (gdk_window_is_viewable (window))
5413 _gdk_synthesize_crossing_events_for_geometry_change (window);
5414 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5420 * gdk_window_show_unraised:
5421 * @window: a #GdkWindow
5423 * Shows a #GdkWindow onscreen, but does not modify its stacking
5424 * order. In contrast, gdk_window_show() will raise the window
5425 * to the top of the window stack.
5427 * On the X11 platform, in Xlib terms, this function calls
5428 * XMapWindow() (it also updates some internal GDK state, which means
5429 * that you can't really use XMapWindow() directly on a GDK window).
5432 gdk_window_show_unraised (GdkWindow *window)
5434 gdk_window_show_internal (window, FALSE);
5439 * @window: a #GdkWindow
5441 * Raises @window to the top of the Z-order (stacking order), so that
5442 * other windows with the same parent window appear below @window.
5443 * This is true whether or not the windows are visible.
5445 * If @window is a toplevel, the window manager may choose to deny the
5446 * request to move the window in the Z-order, gdk_window_raise() only
5447 * requests the restack, does not guarantee it.
5450 gdk_window_raise (GdkWindow *window)
5452 GdkWindowObject *private;
5453 cairo_region_t *old_region, *new_region;
5455 g_return_if_fail (GDK_IS_WINDOW (window));
5457 private = (GdkWindowObject *) window;
5458 if (private->destroyed)
5461 gdk_window_flush_if_exposing (window);
5464 if (gdk_window_is_viewable (window) &&
5465 !private->input_only)
5466 old_region = cairo_region_copy (private->clip_region);
5468 /* Keep children in (reverse) stacking order */
5469 gdk_window_raise_internal (window);
5471 recompute_visible_regions (private, TRUE, FALSE);
5475 new_region = cairo_region_copy (private->clip_region);
5477 cairo_region_subtract (new_region, old_region);
5478 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5480 cairo_region_destroy (old_region);
5481 cairo_region_destroy (new_region);
5486 gdk_window_lower_internal (GdkWindow *window)
5488 GdkWindowObject *private = (GdkWindowObject *)window;
5489 GdkWindowObject *parent = private->parent;
5490 GdkWindowImplIface *impl_iface;
5491 GdkWindowObject *above;
5492 GList *native_children;
5497 parent->children = g_list_remove (parent->children, window);
5498 parent->children = g_list_append (parent->children, window);
5501 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5502 /* Just do native lower for toplevels */
5503 if (gdk_window_is_toplevel (private) ||
5504 /* The restack_under codepath should work correctly even if the parent
5505 is native, but it relies on the order of ->children to be correct,
5506 and some apps like SWT reorder the x windows without gdks knowledge,
5507 so we use lower directly in order to make these behave as before
5508 when using native windows */
5509 (gdk_window_has_impl (private) && gdk_window_has_impl (parent)))
5511 impl_iface->lower (window);
5513 else if (gdk_window_has_impl (private))
5515 above = find_native_sibling_above (parent, private);
5518 listhead.data = window;
5519 listhead.next = NULL;
5520 listhead.prev = NULL;
5521 impl_iface->restack_under ((GdkWindow *)above, &listhead);
5524 impl_iface->raise (window);
5528 native_children = NULL;
5529 get_all_native_children (private, &native_children);
5530 if (native_children != NULL)
5532 above = find_native_sibling_above (parent, private);
5535 impl_iface->restack_under ((GdkWindow *)above,
5539 /* Right order, since native_children is bottom-topmost first */
5540 for (l = native_children; l != NULL; l = l->next)
5541 impl_iface->raise (l->data);
5544 g_list_free (native_children);
5551 gdk_window_invalidate_in_parent (GdkWindowObject *private)
5553 GdkRectangle r, child;
5555 if (gdk_window_is_toplevel (private))
5558 /* get the visible rectangle of the parent */
5560 r.width = private->parent->width;
5561 r.height = private->parent->height;
5563 child.x = private->x;
5564 child.y = private->y;
5565 child.width = private->width;
5566 child.height = private->height;
5567 gdk_rectangle_intersect (&r, &child, &r);
5569 gdk_window_invalidate_rect_full (GDK_WINDOW (private->parent), &r, TRUE, CLEAR_BG_ALL);
5575 * @window: a #GdkWindow
5577 * Lowers @window to the bottom of the Z-order (stacking order), so that
5578 * other windows with the same parent window appear above @window.
5579 * This is true whether or not the other windows are visible.
5581 * If @window is a toplevel, the window manager may choose to deny the
5582 * request to move the window in the Z-order, gdk_window_lower() only
5583 * requests the restack, does not guarantee it.
5585 * Note that gdk_window_show() raises the window again, so don't call this
5586 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5589 gdk_window_lower (GdkWindow *window)
5591 GdkWindowObject *private;
5593 g_return_if_fail (GDK_IS_WINDOW (window));
5595 private = (GdkWindowObject *) window;
5596 if (private->destroyed)
5599 gdk_window_flush_if_exposing (window);
5601 /* Keep children in (reverse) stacking order */
5602 gdk_window_lower_internal (window);
5604 recompute_visible_regions (private, TRUE, FALSE);
5606 _gdk_synthesize_crossing_events_for_geometry_change (window);
5607 gdk_window_invalidate_in_parent (private);
5611 * gdk_window_restack:
5612 * @window: a #GdkWindow
5613 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5616 * Changes the position of @window in the Z-order (stacking order), so that
5617 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5620 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5621 * lowers the window.
5623 * If @window is a toplevel, the window manager may choose to deny the
5624 * request to move the window in the Z-order, gdk_window_restack() only
5625 * requests the restack, does not guarantee it.
5630 gdk_window_restack (GdkWindow *window,
5634 GdkWindowObject *private;
5635 GdkWindowImplIface *impl_iface;
5636 GdkWindowObject *parent;
5637 GdkWindowObject *above_native;
5638 GList *sibling_link;
5639 GList *native_children;
5642 g_return_if_fail (GDK_IS_WINDOW (window));
5643 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5645 private = (GdkWindowObject *) window;
5646 if (private->destroyed)
5649 if (sibling == NULL)
5652 gdk_window_raise (window);
5654 gdk_window_lower (window);
5658 gdk_window_flush_if_exposing (window);
5660 if (gdk_window_is_toplevel (private))
5662 g_return_if_fail (gdk_window_is_toplevel (GDK_WINDOW_OBJECT (sibling)));
5663 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5664 impl_iface->restack_toplevel (window, sibling, above);
5668 parent = private->parent;
5671 sibling_link = g_list_find (parent->children, sibling);
5672 g_return_if_fail (sibling_link != NULL);
5673 if (sibling_link == NULL)
5676 parent->children = g_list_remove (parent->children, window);
5678 parent->children = g_list_insert_before (parent->children,
5682 parent->children = g_list_insert_before (parent->children,
5686 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5687 if (gdk_window_has_impl (private))
5689 above_native = find_native_sibling_above (parent, private);
5692 listhead.data = window;
5693 listhead.next = NULL;
5694 listhead.prev = NULL;
5695 impl_iface->restack_under ((GdkWindow *)above_native, &listhead);
5698 impl_iface->raise (window);
5702 native_children = NULL;
5703 get_all_native_children (private, &native_children);
5704 if (native_children != NULL)
5706 above_native = find_native_sibling_above (parent, private);
5708 impl_iface->restack_under ((GdkWindow *)above_native,
5712 /* Right order, since native_children is bottom-topmost first */
5713 for (l = native_children; l != NULL; l = l->next)
5714 impl_iface->raise (l->data);
5717 g_list_free (native_children);
5722 recompute_visible_regions (private, TRUE, FALSE);
5724 _gdk_synthesize_crossing_events_for_geometry_change (window);
5725 gdk_window_invalidate_in_parent (private);
5731 * @window: a #GdkWindow
5733 * Like gdk_window_show_unraised(), but also raises the window to the
5734 * top of the window stack (moves the window to the front of the
5737 * This function maps a window so it's visible onscreen. Its opposite
5738 * is gdk_window_hide().
5740 * When implementing a #GtkWidget, you should call this function on the widget's
5741 * #GdkWindow as part of the "map" method.
5744 gdk_window_show (GdkWindow *window)
5746 gdk_window_show_internal (window, TRUE);
5751 * @window: a #GdkWindow
5753 * For toplevel windows, withdraws them, so they will no longer be
5754 * known to the window manager; for all windows, unmaps them, so
5755 * they won't be displayed. Normally done automatically as
5756 * part of gtk_widget_hide().
5759 gdk_window_hide (GdkWindow *window)
5761 GdkWindowObject *private;
5762 GdkWindowImplIface *impl_iface;
5763 gboolean was_mapped, did_hide;
5765 g_return_if_fail (GDK_IS_WINDOW (window));
5767 private = (GdkWindowObject *) window;
5768 if (private->destroyed)
5771 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5773 if (gdk_window_has_impl (private))
5776 if (GDK_WINDOW_IS_MAPPED (window))
5777 gdk_synthesize_window_state (window,
5779 GDK_WINDOW_STATE_WITHDRAWN);
5781 else if (was_mapped)
5783 GdkDisplay *display;
5784 GdkDeviceManager *device_manager;
5787 /* May need to break grabs on children */
5788 display = gdk_window_get_display (window);
5789 device_manager = gdk_display_get_device_manager (display);
5791 /* Get all devices */
5792 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5793 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5794 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5796 for (d = devices; d; d = d->next)
5798 GdkDevice *device = d->data;
5800 if (_gdk_display_end_device_grab (display, device,
5801 _gdk_windowing_window_get_next_serial (display),
5804 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5807 private->state = GDK_WINDOW_STATE_WITHDRAWN;
5808 g_list_free (devices);
5811 did_hide = _gdk_window_update_viewable (window);
5813 /* Hide foreign window as those are not handled by update_viewable. */
5814 if (gdk_window_has_impl (private) && (!did_hide))
5816 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5817 impl_iface->hide (window);
5820 recompute_visible_regions (private, TRUE, FALSE);
5822 /* all decendants became non-visible, we need to send visibility notify */
5823 gdk_window_update_visibility_recursively (private, NULL);
5825 if (was_mapped && !gdk_window_has_impl (private))
5827 if (private->event_mask & GDK_STRUCTURE_MASK)
5828 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5830 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5831 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5833 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5836 /* Invalidate the rect */
5838 gdk_window_invalidate_in_parent (private);
5842 * gdk_window_withdraw:
5843 * @window: a toplevel #GdkWindow
5845 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5846 * This function is not really useful as gdk_window_hide() automatically
5847 * withdraws toplevel windows before hiding them.
5850 gdk_window_withdraw (GdkWindow *window)
5852 GdkWindowObject *private;
5853 GdkWindowImplIface *impl_iface;
5854 gboolean was_mapped;
5856 g_return_if_fail (GDK_IS_WINDOW (window));
5858 private = (GdkWindowObject *) window;
5859 if (private->destroyed)
5862 was_mapped = GDK_WINDOW_IS_MAPPED (private);
5864 if (gdk_window_has_impl (private))
5866 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5867 impl_iface->withdraw (window);
5871 if (private->event_mask & GDK_STRUCTURE_MASK)
5872 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5874 if (private->parent && private->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5875 _gdk_make_event (GDK_WINDOW (private), GDK_UNMAP, NULL, FALSE);
5877 _gdk_synthesize_crossing_events_for_geometry_change (GDK_WINDOW (private->parent));
5880 recompute_visible_regions (private, TRUE, FALSE);
5885 * gdk_window_set_events:
5886 * @window: a #GdkWindow
5887 * @event_mask: event mask for @window
5889 * The event mask for a window determines which events will be reported
5890 * for that window from all master input devices. For example, an event mask
5891 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5892 * press events. The event mask is the bitwise OR of values from the
5893 * #GdkEventMask enumeration.
5896 gdk_window_set_events (GdkWindow *window,
5897 GdkEventMask event_mask)
5899 GdkWindowObject *private;
5900 GdkWindowImplIface *impl_iface;
5901 GdkDisplay *display;
5903 g_return_if_fail (GDK_IS_WINDOW (window));
5905 private = (GdkWindowObject *) window;
5906 if (private->destroyed)
5909 /* If motion hint is disabled, enable motion events again */
5910 display = gdk_window_get_display (window);
5911 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5912 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5914 GList *devices = private->devices_inside;
5918 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5919 devices = devices->next;
5923 private->event_mask = event_mask;
5925 if (gdk_window_has_impl (private))
5927 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
5928 impl_iface->set_events (window,
5929 get_native_event_mask (private));
5935 * gdk_window_get_events:
5936 * @window: a #GdkWindow
5938 * Gets the event mask for @window for all master input devices. See
5939 * gdk_window_set_events().
5941 * Return value: event mask for @window
5944 gdk_window_get_events (GdkWindow *window)
5946 GdkWindowObject *private;
5948 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5950 private = (GdkWindowObject *) window;
5951 if (private->destroyed)
5954 return private->event_mask;
5958 * gdk_window_set_device_events:
5959 * @window: a #GdkWindow
5960 * @device: #GdkDevice to enable events for.
5961 * @event_mask: event mask for @window
5963 * Sets the event mask for a given device (Normally a floating device, not
5964 * attached to any visible pointer) to @window. For example, an event mask
5965 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5966 * press events. The event mask is the bitwise OR of values from the
5967 * #GdkEventMask enumeration.
5972 gdk_window_set_device_events (GdkWindow *window,
5974 GdkEventMask event_mask)
5976 GdkEventMask device_mask;
5977 GdkWindowObject *private;
5978 GdkDisplay *display;
5981 g_return_if_fail (GDK_IS_WINDOW (window));
5982 g_return_if_fail (GDK_IS_DEVICE (device));
5984 if (GDK_WINDOW_DESTROYED (window))
5987 private = (GdkWindowObject *) window;
5989 /* If motion hint is disabled, enable motion events again */
5990 display = gdk_window_get_display (window);
5991 if ((private->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5992 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5993 _gdk_display_enable_motion_hints (display, device);
5995 if (G_UNLIKELY (!private->device_events))
5996 private->device_events = g_hash_table_new (NULL, NULL);
5998 if (event_mask == 0)
6000 /* FIXME: unsetting events on a master device
6001 * would restore private->event_mask
6003 g_hash_table_remove (private->device_events, device);
6006 g_hash_table_insert (private->device_events, device,
6007 GINT_TO_POINTER (event_mask));
6009 if (_gdk_native_windows)
6012 native = gdk_window_get_toplevel (window);
6014 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
6016 native = gdk_offscreen_window_get_embedder (native);
6018 if (native == NULL ||
6019 (!_gdk_window_has_impl (native) &&
6020 !gdk_window_is_viewable (native)))
6023 native = gdk_window_get_toplevel (native);
6026 device_mask = get_native_device_event_mask (private, device);
6027 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
6031 * gdk_window_get_device_events:
6032 * @window: a #GdkWindow.
6033 * @device: a #GdkDevice.
6035 * Returns the event mask for @window corresponding to an specific device.
6037 * Returns: device event mask for @window
6042 gdk_window_get_device_events (GdkWindow *window,
6045 GdkWindowObject *private;
6048 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6049 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
6051 if (GDK_WINDOW_DESTROYED (window))
6054 private = (GdkWindowObject *) window;
6056 if (!private->device_events)
6059 mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
6061 /* FIXME: device could be controlled by private->event_mask */
6067 gdk_window_move_resize_toplevel (GdkWindow *window,
6074 GdkWindowObject *private;
6075 cairo_region_t *old_region, *new_region;
6076 GdkWindowImplIface *impl_iface;
6078 int old_x, old_y, old_abs_x, old_abs_y;
6082 private = (GdkWindowObject *) window;
6090 is_resize = (width != -1) || (height != -1);
6092 if (gdk_window_is_viewable (window) &&
6093 !private->input_only)
6096 old_region = cairo_region_copy (private->clip_region);
6099 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6100 impl_iface->move_resize (window, with_move, x, y, width, height);
6102 dx = private->x - old_x;
6103 dy = private->y - old_y;
6105 old_abs_x = private->abs_x;
6106 old_abs_y = private->abs_y;
6108 /* Avoid recomputing for pure toplevel moves, for performance reasons */
6110 recompute_visible_regions (private, TRUE, FALSE);
6114 new_region = cairo_region_copy (private->clip_region);
6116 /* This is the newly exposed area (due to any resize),
6117 * X will expose it, but lets do that without the
6120 cairo_region_subtract (new_region, old_region);
6121 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
6123 cairo_region_destroy (old_region);
6124 cairo_region_destroy (new_region);
6127 _gdk_synthesize_crossing_events_for_geometry_change (window);
6132 move_native_children (GdkWindowObject *private)
6135 GdkWindowObject *child;
6136 GdkWindowImplIface *impl_iface;
6138 for (l = private->children; l; l = l->next)
6142 if (child->impl != private->impl)
6144 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (child->impl);
6145 impl_iface->move_resize ((GdkWindow *)child, TRUE,
6147 child->width, child->height);
6150 move_native_children (child);
6155 collect_native_child_region_helper (GdkWindowObject *window,
6157 cairo_region_t **region,
6161 GdkWindowObject *child;
6162 cairo_region_t *tmp;
6165 for (l = window->children; l != NULL; l = l->next)
6169 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
6172 if (child->impl != impl)
6174 tmp = cairo_region_copy (child->clip_region);
6175 cairo_region_translate (tmp,
6176 x_offset + child->x,
6177 y_offset + child->y);
6178 if (*region == NULL)
6182 cairo_region_union (*region, tmp);
6183 cairo_region_destroy (tmp);
6187 collect_native_child_region_helper (child, impl, region,
6188 x_offset + child->x,
6189 y_offset + child->y);
6195 static cairo_region_t *
6196 collect_native_child_region (GdkWindowObject *window,
6197 gboolean include_this)
6199 cairo_region_t *region;
6201 if (include_this && gdk_window_has_impl (window) && window->viewable)
6202 return cairo_region_copy (window->clip_region);
6206 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6213 gdk_window_move_resize_internal (GdkWindow *window,
6220 GdkWindowObject *private;
6221 cairo_region_t *old_region, *new_region, *copy_area;
6222 cairo_region_t *old_native_child_region, *new_native_child_region;
6223 GdkWindowObject *impl_window;
6224 GdkWindowImplIface *impl_iface;
6226 int old_x, old_y, old_abs_x, old_abs_y;
6229 g_return_if_fail (GDK_IS_WINDOW (window));
6231 private = (GdkWindowObject *) window;
6232 if (private->destroyed)
6235 if (gdk_window_is_toplevel (private))
6237 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6241 /* Bail early if no change */
6242 if (private->width == width &&
6243 private->height == height &&
6249 gdk_window_flush_if_exposing (window);
6251 /* Handle child windows */
6256 impl_window = gdk_window_get_impl_window (private);
6261 old_native_child_region = NULL;
6262 if (gdk_window_is_viewable (window) &&
6263 !private->input_only)
6267 old_region = cairo_region_copy (private->clip_region);
6268 /* Adjust region to parent window coords */
6269 cairo_region_translate (old_region, private->x, private->y);
6271 old_native_child_region = collect_native_child_region (private, TRUE);
6272 if (old_native_child_region)
6274 /* Adjust region to parent window coords */
6275 cairo_region_translate (old_native_child_region, private->x, private->y);
6277 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6278 * source or destination for a delayed GdkWindowRegionMove. So, we need
6279 * to flush those here for the parent window and all overlapped subwindows
6280 * of it. And we need to do this before setting the new clips as those will be
6283 gdk_window_flush_recursive (private->parent);
6287 /* Set the new position and size */
6293 if (!(width < 0 && height < 0))
6297 private->width = width;
6300 private->height = height;
6303 dx = private->x - old_x;
6304 dy = private->y - old_y;
6306 old_abs_x = private->abs_x;
6307 old_abs_y = private->abs_y;
6309 recompute_visible_regions (private, TRUE, FALSE);
6311 new_native_child_region = NULL;
6312 if (old_native_child_region)
6314 new_native_child_region = collect_native_child_region (private, TRUE);
6315 /* Adjust region to parent window coords */
6316 cairo_region_translate (new_native_child_region, private->x, private->y);
6319 if (gdk_window_has_impl (private))
6321 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6323 /* Do the actual move after recomputing things, as this will have set the shape to
6324 the now correct one, thus avoiding copying regions that should not be copied. */
6325 impl_iface->move_resize (window, TRUE,
6326 private->x, private->y,
6327 private->width, private->height);
6329 else if (old_abs_x != private->abs_x ||
6330 old_abs_y != private->abs_y)
6331 move_native_children (private);
6335 new_region = cairo_region_copy (private->clip_region);
6336 /* Adjust region to parent window coords */
6337 cairo_region_translate (new_region, private->x, private->y);
6340 * Part of the data at the new location can be copied from the
6341 * old location, this area is the intersection of the old region
6342 * moved as the copy will move it and then intersected with
6346 * Everything in the old and new regions that is not copied must be
6347 * invalidated (including children) as this is newly exposed
6349 copy_area = cairo_region_copy (new_region);
6351 cairo_region_union (new_region, old_region);
6353 if (old_native_child_region)
6355 /* Don't copy from inside native children, as this is copied by
6356 * the native window move.
6358 cairo_region_subtract (old_region, old_native_child_region);
6360 cairo_region_translate (old_region, dx, dy);
6362 cairo_region_intersect (copy_area, old_region);
6364 if (new_native_child_region)
6366 /* Don't copy any bits that would cause a read from the moved
6367 native windows, as we can't read that data */
6368 cairo_region_translate (new_native_child_region, dx, dy);
6369 cairo_region_subtract (copy_area, new_native_child_region);
6370 cairo_region_translate (new_native_child_region, -dx, -dy);
6373 cairo_region_subtract (new_region, copy_area);
6375 /* Convert old region to impl coords */
6376 cairo_region_translate (old_region, -dx + private->abs_x - private->x, -dy + private->abs_y - private->y);
6378 /* convert from parent coords to impl */
6379 cairo_region_translate (copy_area, private->abs_x - private->x, private->abs_y - private->y);
6381 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6383 /* Invalidate affected part in the parent window
6384 * (no higher window should be affected)
6385 * We also invalidate any children in that area, which could include
6386 * this window if it still overlaps that area.
6388 if (old_native_child_region)
6390 /* No need to expose the region that the native window move copies */
6391 cairo_region_translate (old_native_child_region, dx, dy);
6392 cairo_region_intersect (old_native_child_region, new_native_child_region);
6393 cairo_region_subtract (new_region, old_native_child_region);
6395 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), new_region, TRUE, CLEAR_BG_ALL);
6397 cairo_region_destroy (old_region);
6398 cairo_region_destroy (new_region);
6401 if (old_native_child_region)
6403 cairo_region_destroy (old_native_child_region);
6404 cairo_region_destroy (new_native_child_region);
6407 _gdk_synthesize_crossing_events_for_geometry_change (window);
6414 * @window: a #GdkWindow
6415 * @x: X coordinate relative to window's parent
6416 * @y: Y coordinate relative to window's parent
6418 * Repositions a window relative to its parent window.
6419 * For toplevel windows, window managers may ignore or modify the move;
6420 * you should probably use gtk_window_move() on a #GtkWindow widget
6421 * anyway, instead of using GDK functions. For child windows,
6422 * the move will reliably succeed.
6424 * If you're also planning to resize the window, use gdk_window_move_resize()
6425 * to both move and resize simultaneously, for a nicer visual effect.
6428 gdk_window_move (GdkWindow *window,
6432 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6436 * gdk_window_resize:
6437 * @window: a #GdkWindow
6438 * @width: new width of the window
6439 * @height: new height of the window
6441 * Resizes @window; for toplevel windows, asks the window manager to resize
6442 * the window. The window manager may not allow the resize. When using GTK+,
6443 * use gtk_window_resize() instead of this low-level GDK function.
6445 * Windows may not be resized below 1x1.
6447 * If you're also planning to move the window, use gdk_window_move_resize()
6448 * to both move and resize simultaneously, for a nicer visual effect.
6451 gdk_window_resize (GdkWindow *window,
6455 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6460 * gdk_window_move_resize:
6461 * @window: a #GdkWindow
6462 * @x: new X position relative to window's parent
6463 * @y: new Y position relative to window's parent
6465 * @height: new height
6467 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6468 * except that both operations are performed at once, avoiding strange
6469 * visual effects. (i.e. the user may be able to see the window first
6470 * move, then resize, if you don't use gdk_window_move_resize().)
6473 gdk_window_move_resize (GdkWindow *window,
6479 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6484 * gdk_window_scroll:
6485 * @window: a #GdkWindow
6486 * @dx: Amount to scroll in the X direction
6487 * @dy: Amount to scroll in the Y direction
6489 * Scroll the contents of @window, both pixels and children, by the
6490 * given amount. @window itself does not move. Portions of the window
6491 * that the scroll operation brings in from offscreen areas are
6492 * invalidated. The invalidated region may be bigger than what would
6493 * strictly be necessary.
6495 * For X11, a minimum area will be invalidated if the window has no
6496 * subwindows, or if the edges of the window's parent do not extend
6497 * beyond the edges of the window. In other cases, a multi-step process
6498 * is used to scroll the window which may produce temporary visual
6499 * artifacts and unnecessary invalidations.
6502 gdk_window_scroll (GdkWindow *window,
6506 GdkWindowObject *private = (GdkWindowObject *) window;
6507 GdkWindowObject *impl_window;
6508 cairo_region_t *copy_area, *noncopy_area;
6509 cairo_region_t *old_native_child_region, *new_native_child_region;
6512 g_return_if_fail (GDK_IS_WINDOW (window));
6514 if (dx == 0 && dy == 0)
6517 if (private->destroyed)
6520 gdk_window_flush_if_exposing (window);
6522 old_native_child_region = collect_native_child_region (private, FALSE);
6523 if (old_native_child_region)
6525 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6526 * source or destination for a delayed GdkWindowRegionMove. So, we need
6527 * to flush those here for the window and all overlapped subwindows
6528 * of it. And we need to do this before setting the new clips as those will be
6531 gdk_window_flush_recursive (private);
6535 /* First move all child windows, without causing invalidation */
6537 tmp_list = private->children;
6540 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6541 GdkWindowObject *child_obj = GDK_WINDOW_OBJECT (child);
6543 /* Just update the positions, the bits will move with the copy */
6547 tmp_list = tmp_list->next;
6550 recompute_visible_regions (private, FALSE, TRUE);
6552 new_native_child_region = NULL;
6553 if (old_native_child_region)
6554 new_native_child_region = collect_native_child_region (private, FALSE);
6556 move_native_children (private);
6558 /* Then copy the actual bits of the window w/ child windows */
6560 impl_window = gdk_window_get_impl_window (private);
6562 /* Calculate the area that can be gotten by copying the old area */
6563 copy_area = cairo_region_copy (private->clip_region);
6564 if (old_native_child_region)
6566 /* Don't copy from inside native children, as this is copied by
6567 * the native window move.
6569 cairo_region_subtract (copy_area, old_native_child_region);
6571 /* Don't copy any bits that would cause a read from the moved
6572 native windows, as we can't read that data */
6573 cairo_region_subtract (copy_area, new_native_child_region);
6575 cairo_region_translate (copy_area, dx, dy);
6576 cairo_region_intersect (copy_area, private->clip_region);
6578 /* And the rest need to be invalidated */
6579 noncopy_area = cairo_region_copy (private->clip_region);
6580 cairo_region_subtract (noncopy_area, copy_area);
6582 /* convert from window coords to impl */
6583 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6585 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6587 /* Invalidate not copied regions */
6588 if (old_native_child_region)
6590 /* No need to expose the region that the native window move copies */
6591 cairo_region_translate (old_native_child_region, dx, dy);
6592 cairo_region_intersect (old_native_child_region, new_native_child_region);
6593 cairo_region_subtract (noncopy_area, old_native_child_region);
6595 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6597 cairo_region_destroy (noncopy_area);
6599 if (old_native_child_region)
6601 cairo_region_destroy (old_native_child_region);
6602 cairo_region_destroy (new_native_child_region);
6605 _gdk_synthesize_crossing_events_for_geometry_change (window);
6609 * gdk_window_move_region:
6610 * @window: a #GdkWindow
6611 * @region: The #cairo_region_t to move
6612 * @dx: Amount to move in the X direction
6613 * @dy: Amount to move in the Y direction
6615 * Move the part of @window indicated by @region by @dy pixels in the Y
6616 * direction and @dx pixels in the X direction. The portions of @region
6617 * that not covered by the new position of @region are invalidated.
6619 * Child windows are not moved.
6624 gdk_window_move_region (GdkWindow *window,
6625 const cairo_region_t *region,
6629 GdkWindowObject *private = (GdkWindowObject *) window;
6630 GdkWindowObject *impl_window;
6631 cairo_region_t *nocopy_area;
6632 cairo_region_t *copy_area;
6634 g_return_if_fail (GDK_IS_WINDOW (window));
6635 g_return_if_fail (region != NULL);
6637 if (dx == 0 && dy == 0)
6640 if (private->destroyed)
6643 impl_window = gdk_window_get_impl_window (private);
6645 /* compute source regions */
6646 copy_area = cairo_region_copy (region);
6647 cairo_region_intersect (copy_area, private->clip_region_with_children);
6649 /* compute destination regions */
6650 cairo_region_translate (copy_area, dx, dy);
6651 cairo_region_intersect (copy_area, private->clip_region_with_children);
6653 /* Invalidate parts of the region (source and dest) not covered
6655 nocopy_area = cairo_region_copy (region);
6656 cairo_region_translate (nocopy_area, dx, dy);
6657 cairo_region_union (nocopy_area, region);
6658 cairo_region_subtract (nocopy_area, copy_area);
6660 /* convert from window coords to impl */
6661 cairo_region_translate (copy_area, private->abs_x, private->abs_y);
6662 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6664 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6665 cairo_region_destroy (nocopy_area);
6669 * gdk_window_set_background:
6670 * @window: a #GdkWindow
6671 * @color: a #GdkColor
6673 * Sets the background color of @window. (However, when using GTK+,
6674 * set the background of a widget with gtk_widget_modify_bg() - if
6675 * you're an application - or gtk_style_set_background() - if you're
6676 * implementing a custom widget.)
6678 * See also gdk_window_set_background_pattern().
6681 gdk_window_set_background (GdkWindow *window,
6682 const GdkColor *color)
6684 cairo_pattern_t *pattern;
6686 g_return_if_fail (GDK_IS_WINDOW (window));
6688 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6689 color->green / 65535.,
6690 color->blue / 65535.);
6692 gdk_window_set_background_pattern (window, pattern);
6694 cairo_pattern_destroy (pattern);
6698 * gdk_window_set_background_pattern:
6699 * @window: a #GdkWindow
6700 * @pattern: (allow-none): a pattern to use, or %NULL
6702 * Sets the background of @window.
6704 * A background of %NULL means that the window will inherit its
6705 * background form its parent window.
6707 * The windowing system will normally fill a window with its background
6708 * when the window is obscured then exposed, and when you call
6709 * gdk_window_clear().
6712 gdk_window_set_background_pattern (GdkWindow *window,
6713 cairo_pattern_t *pattern)
6715 GdkWindowObject *private;
6717 g_return_if_fail (GDK_IS_WINDOW (window));
6719 private = (GdkWindowObject *) window;
6722 cairo_pattern_reference (pattern);
6723 if (private->background)
6724 cairo_pattern_destroy (private->background);
6725 private->background = pattern;
6727 if (gdk_window_has_impl (private) &&
6728 !private->input_only)
6730 GdkWindowImplIface *impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6731 impl_iface->set_background (window, pattern);
6736 * gdk_window_get_background_pattern:
6739 * Gets the pattern used to clear the background on @window. If @window
6740 * does not have its own background and reuses the parent's, %NULL is
6741 * returned and you'll have to query it yourself.
6743 * Returns: The pattern to use for the background or %NULL to use the
6744 * parent's background.
6749 gdk_window_get_background_pattern (GdkWindow *window)
6751 GdkWindowObject *private = (GdkWindowObject *) window;
6753 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6755 return private->background;
6759 update_cursor_foreach (GdkDisplay *display,
6761 GdkPointerWindowInfo *pointer_info,
6764 GdkWindow *window = user_data;
6765 GdkWindowObject *private = (GdkWindowObject *) window;
6767 if (_gdk_native_windows ||
6768 private->window_type == GDK_WINDOW_ROOT ||
6769 private->window_type == GDK_WINDOW_FOREIGN)
6770 GDK_WINDOW_IMPL_GET_IFACE (private->impl)->set_device_cursor (window, device, private->cursor);
6771 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6772 update_cursor (display, device);
6776 * gdk_window_get_cursor:
6777 * @window: a #GdkWindow
6779 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6780 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6781 * there is no custom cursor set on the specified window, and it is
6782 * using the cursor for its parent window.
6784 * Return value: a #GdkCursor, or %NULL. The returned object is owned
6785 * by the #GdkWindow and should not be unreferenced directly. Use
6786 * gdk_window_set_cursor() to unset the cursor of the window
6791 gdk_window_get_cursor (GdkWindow *window)
6793 GdkWindowObject *private;
6795 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6797 private = (GdkWindowObject *) window;
6799 return private->cursor;
6803 * gdk_window_set_cursor:
6804 * @window: a #GdkWindow
6805 * @cursor: (allow-none): a cursor
6807 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6808 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6809 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6810 * to gdk_window_set_cursor() means that @window will use the cursor of its
6811 * parent window. Most windows should use this default.
6814 gdk_window_set_cursor (GdkWindow *window,
6817 GdkWindowObject *private;
6818 GdkDisplay *display;
6820 g_return_if_fail (GDK_IS_WINDOW (window));
6822 private = (GdkWindowObject *) window;
6823 display = gdk_window_get_display (window);
6825 if (private->cursor)
6827 gdk_cursor_unref (private->cursor);
6828 private->cursor = NULL;
6831 if (!GDK_WINDOW_DESTROYED (window))
6834 private->cursor = gdk_cursor_ref (cursor);
6836 _gdk_display_pointer_info_foreach (display,
6837 update_cursor_foreach,
6840 g_object_notify (G_OBJECT (window), "cursor");
6845 * gdk_window_get_device_cursor:
6846 * @window: a #GdkWindow.
6847 * @device: a #GdkDevice.
6849 * Retrieves a #GdkCursor pointer for the @device currently set on the
6850 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6851 * there is no custom cursor set on the specified window, and it is
6852 * using the cursor for its parent window.
6854 * Returns: a #GdkCursor, or %NULL. The returned object is owned
6855 * by the #GdkWindow and should not be unreferenced directly. Use
6856 * gdk_window_set_cursor() to unset the cursor of the window
6861 gdk_window_get_device_cursor (GdkWindow *window,
6864 GdkWindowObject *private;
6866 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6867 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6869 private = (GdkWindowObject *) window;
6871 return g_hash_table_lookup (private->device_cursor, device);
6875 * gdk_window_set_device_cursor:
6876 * @window: a #Gdkwindow
6877 * @device: a #GdkDevice
6878 * @cursor: a #GdkCursor
6880 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6881 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6882 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6883 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6884 * @window will use the cursor of its parent window. Most windows should
6890 gdk_window_set_device_cursor (GdkWindow *window,
6894 GdkWindowObject *private;
6895 GdkDisplay *display;
6897 g_return_if_fail (GDK_IS_WINDOW (window));
6898 g_return_if_fail (GDK_IS_DEVICE (device));
6900 private = (GdkWindowObject *) window;
6901 display = gdk_window_get_display (window);
6904 g_hash_table_remove (private->device_cursor, device);
6906 g_hash_table_replace (private->device_cursor, device, gdk_cursor_ref (cursor));
6908 if (!GDK_WINDOW_DESTROYED (window))
6910 GdkPointerWindowInfo *pointer_info;
6912 pointer_info = _gdk_display_get_pointer_info (display, device);
6914 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6915 update_cursor (display, device);
6920 * gdk_window_get_geometry:
6921 * @window: a #GdkWindow
6922 * @x: return location for X coordinate of window (relative to its parent)
6923 * @y: return location for Y coordinate of window (relative to its parent)
6924 * @width: return location for width of window
6925 * @height: return location for height of window
6926 * @depth: return location for bit depth of window
6928 * Any of the return location arguments to this function may be %NULL,
6929 * if you aren't interested in getting the value of that field.
6931 * The X and Y coordinates returned are relative to the parent window
6932 * of @window, which for toplevels usually means relative to the
6933 * window decorations (titlebar, etc.) rather than relative to the
6934 * root window (screen-size background window).
6936 * On the X11 platform, the geometry is obtained from the X server,
6937 * so reflects the latest position of @window; this may be out-of-sync
6938 * with the position of @window delivered in the most-recently-processed
6939 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6940 * position from the most recent configure event.
6943 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6944 * to call gdk_window_get_position() and gdk_drawable_get_size() instead,
6945 * because it avoids the roundtrip to the X server and because
6946 * gdk_drawable_get_size() supports the full 32-bit coordinate space,
6947 * whereas gdk_window_get_geometry() is restricted to the 16-bit
6948 * coordinates of X11.
6952 gdk_window_get_geometry (GdkWindow *window,
6959 GdkWindowObject *private, *parent;
6960 GdkWindowImplIface *impl_iface;
6964 GDK_NOTE (MULTIHEAD,
6965 g_message ("gdk_window_get_geometry(): Window needs "
6966 "to be non-NULL to be multi head safe"));
6967 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
6970 g_return_if_fail (GDK_IS_WINDOW (window));
6972 private = (GdkWindowObject *) window;
6974 if (!GDK_WINDOW_DESTROYED (window))
6976 if (gdk_window_has_impl (private))
6978 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
6979 impl_iface->get_geometry (window, x, y,
6982 /* This reports the position wrt to the native parent, we need to convert
6983 it to be relative to the client side parent */
6984 parent = private->parent;
6985 if (parent && !gdk_window_has_impl (parent))
6988 *x -= parent->abs_x;
6990 *y -= parent->abs_y;
7000 *width = private->width;
7002 *height = private->height;
7004 *depth = private->depth;
7010 * gdk_window_get_width:
7011 * @window: a #GdkWindow
7013 * Returns the width of the given @window.
7015 * On the X11 platform the returned size is the size reported in the
7016 * most-recently-processed configure event, rather than the current
7017 * size on the X server.
7019 * Returns: The width of @window
7022 gdk_window_get_width (GdkWindow *window)
7024 GdkWindowObject *private;
7026 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7028 private = (GdkWindowObject *) window;
7030 return private->width;
7034 * gdk_window_get_height:
7035 * @window: a #GdkWindow
7037 * Returns the height of the given @window.
7039 * On the X11 platform the returned size is the size reported in the
7040 * most-recently-processed configure event, rather than the current
7041 * size on the X server.
7043 * Returns: The height of @window
7046 gdk_window_get_height (GdkWindow *window)
7048 GdkWindowObject *private;
7050 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7052 private = (GdkWindowObject *) window;
7054 return private->height;
7058 * gdk_window_get_origin:
7059 * @window: a #GdkWindow
7060 * @x: return location for X coordinate
7061 * @y: return location for Y coordinate
7063 * Obtains the position of a window in root window coordinates.
7064 * (Compare with gdk_window_get_position() and
7065 * gdk_window_get_geometry() which return the position of a window
7066 * relative to its parent window.)
7068 * Return value: not meaningful, ignore
7071 gdk_window_get_origin (GdkWindow *window,
7075 GdkWindowObject *private;
7076 GdkWindowImplIface *impl_iface;
7078 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7080 if (GDK_WINDOW_DESTROYED (window))
7089 private = (GdkWindowObject *) window;
7091 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7092 impl_iface->get_root_coords (window,
7101 * gdk_window_get_root_coords:
7102 * @window: a #GdkWindow
7103 * @x: X coordinate in window
7104 * @y: Y coordinate in window
7105 * @root_x: return location for X coordinate
7106 * @root_y: return location for Y coordinate
7108 * Obtains the position of a window position in root
7109 * window coordinates. This is similar to
7110 * gdk_window_get_origin() but allows you go pass
7111 * in any position in the window, not just the origin.
7116 gdk_window_get_root_coords (GdkWindow *window,
7122 GdkWindowObject *private;
7123 GdkWindowImplIface *impl_iface;
7125 g_return_if_fail (GDK_IS_WINDOW (window));
7127 private = (GdkWindowObject *) window;
7129 if (GDK_WINDOW_DESTROYED (window))
7138 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7139 impl_iface->get_root_coords (window,
7146 * gdk_window_coords_to_parent:
7147 * @window: a child window
7148 * @x: X coordinate in child's coordinate system
7149 * @y: Y coordinate in child's coordinate system
7150 * @parent_x: (out) (allow-none): return location for X coordinate
7151 * in parent's coordinate system, or %NULL
7152 * @parent_y: (out) (allow-none): return location for Y coordinate
7153 * in parent's coordinate system, or %NULL
7155 * Transforms window coordinates from a child window to its parent
7156 * window, where the parent window is the normal parent as returned by
7157 * gdk_window_get_parent() for normal windows, and the window's
7158 * embedder as returned by gdk_offscreen_window_get_embedder() for
7159 * offscreen windows.
7161 * For normal windows, calling this function is equivalent to adding
7162 * the return values of gdk_window_get_position() to the child coordinates.
7163 * For offscreen windows however (which can be arbitrarily transformed),
7164 * this function calls the GdkWindow::to-embedder: signal to translate
7167 * You should always use this function when writing generic code that
7168 * walks up a window hierarchy.
7170 * See also: gdk_window_coords_from_parent()
7175 gdk_window_coords_to_parent (GdkWindow *window,
7181 GdkWindowObject *obj;
7183 g_return_if_fail (GDK_IS_WINDOW (window));
7185 obj = (GdkWindowObject *) window;
7187 if (gdk_window_is_offscreen (obj))
7191 to_embedder (obj, x, y, &px, &py);
7202 *parent_x = x + obj->x;
7205 *parent_y = y + obj->y;
7210 * gdk_window_coords_from_parent:
7211 * @window: a child window
7212 * @parent_x: X coordinate in parent's coordinate system
7213 * @parent_y: Y coordinate in parent's coordinate system
7214 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7215 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7217 * Transforms window coordinates from a parent window to a child
7218 * window, where the parent window is the normal parent as returned by
7219 * gdk_window_get_parent() for normal windows, and the window's
7220 * embedder as returned by gdk_offscreen_window_get_embedder() for
7221 * offscreen windows.
7223 * For normal windows, calling this function is equivalent to subtracting
7224 * the return values of gdk_window_get_position() from the parent coordinates.
7225 * For offscreen windows however (which can be arbitrarily transformed),
7226 * this function calls the GdkWindow::from-embedder: signal to translate
7229 * You should always use this function when writing generic code that
7230 * walks down a window hierarchy.
7232 * See also: gdk_window_coords_to_parent()
7237 gdk_window_coords_from_parent (GdkWindow *window,
7243 GdkWindowObject *obj;
7245 g_return_if_fail (GDK_IS_WINDOW (window));
7247 obj = (GdkWindowObject *) window;
7249 if (gdk_window_is_offscreen (obj))
7253 from_embedder (obj, parent_x, parent_y, &cx, &cy);
7264 *x = parent_x - obj->x;
7267 *y = parent_y - obj->y;
7272 * gdk_window_shape_combine_region:
7273 * @window: a #GdkWindow
7274 * @shape_region: region of window to be non-transparent
7275 * @offset_x: X position of @shape_region in @window coordinates
7276 * @offset_y: Y position of @shape_region in @window coordinates
7278 * Makes pixels in @window outside @shape_region be transparent,
7279 * so that the window may be nonrectangular.
7281 * If @shape_region is %NULL, the shape will be unset, so the whole
7282 * window will be opaque again. @offset_x and @offset_y are ignored
7283 * if @shape_region is %NULL.
7285 * On the X11 platform, this uses an X server extension which is
7286 * widely available on most common platforms, but not available on
7287 * very old X servers, and occasionally the implementation will be
7288 * buggy. On servers without the shape extension, this function
7291 * This function works on both toplevel and child windows.
7294 gdk_window_shape_combine_region (GdkWindow *window,
7295 const cairo_region_t *shape_region,
7299 GdkWindowObject *private;
7300 cairo_region_t *old_region, *new_region, *diff;
7302 g_return_if_fail (GDK_IS_WINDOW (window));
7304 private = (GdkWindowObject *) window;
7306 if (GDK_WINDOW_DESTROYED (window))
7309 private->shaped = (shape_region != NULL);
7312 cairo_region_destroy (private->shape);
7315 if (GDK_WINDOW_IS_MAPPED (window))
7316 old_region = cairo_region_copy (private->clip_region);
7320 private->shape = cairo_region_copy (shape_region);
7321 cairo_region_translate (private->shape, offset_x, offset_y);
7324 private->shape = NULL;
7326 recompute_visible_regions (private, TRUE, FALSE);
7328 if (gdk_window_has_impl (private) &&
7329 !should_apply_clip_as_shape (private))
7330 apply_shape (private, private->shape);
7334 new_region = cairo_region_copy (private->clip_region);
7336 /* New area in the window, needs invalidation */
7337 diff = cairo_region_copy (new_region);
7338 cairo_region_subtract (diff, old_region);
7340 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7342 cairo_region_destroy (diff);
7344 if (!gdk_window_is_toplevel (private))
7346 /* New area in the non-root parent window, needs invalidation */
7347 diff = cairo_region_copy (old_region);
7348 cairo_region_subtract (diff, new_region);
7350 /* Adjust region to parent window coords */
7351 cairo_region_translate (diff, private->x, private->y);
7353 gdk_window_invalidate_region_full (GDK_WINDOW (private->parent), diff, TRUE, CLEAR_BG_ALL);
7355 cairo_region_destroy (diff);
7358 cairo_region_destroy (new_region);
7359 cairo_region_destroy (old_region);
7364 do_child_shapes (GdkWindow *window,
7367 GdkWindowObject *private;
7369 cairo_region_t *region;
7371 private = (GdkWindowObject *) window;
7375 r.width = private->width;
7376 r.height = private->height;
7378 region = cairo_region_create_rectangle (&r);
7379 remove_child_area (private, NULL, FALSE, region);
7381 if (merge && private->shape)
7382 cairo_region_subtract (region, private->shape);
7384 gdk_window_shape_combine_region (window, region, 0, 0);
7388 * gdk_window_set_child_shapes:
7389 * @window: a #GdkWindow
7391 * Sets the shape mask of @window to the union of shape masks
7392 * for all children of @window, ignoring the shape mask of @window
7393 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7394 * the shape mask of @window in the masks to be merged.
7397 gdk_window_set_child_shapes (GdkWindow *window)
7399 g_return_if_fail (GDK_IS_WINDOW (window));
7401 do_child_shapes (window, FALSE);
7405 * gdk_window_merge_child_shapes:
7406 * @window: a #GdkWindow
7408 * Merges the shape masks for any child windows into the
7409 * shape mask for @window. i.e. the union of all masks
7410 * for @window and its children will become the new mask
7411 * for @window. See gdk_window_shape_combine_region().
7413 * This function is distinct from gdk_window_set_child_shapes()
7414 * because it includes @window's shape mask in the set of shapes to
7418 gdk_window_merge_child_shapes (GdkWindow *window)
7420 g_return_if_fail (GDK_IS_WINDOW (window));
7422 do_child_shapes (window, TRUE);
7426 * gdk_window_input_shape_combine_region:
7427 * @window: a #GdkWindow
7428 * @shape_region: region of window to be non-transparent
7429 * @offset_x: X position of @shape_region in @window coordinates
7430 * @offset_y: Y position of @shape_region in @window coordinates
7432 * Like gdk_window_shape_combine_region(), but the shape applies
7433 * only to event handling. Mouse events which happen while
7434 * the pointer position corresponds to an unset bit in the
7435 * mask will be passed on the window below @window.
7437 * An input shape is typically used with RGBA windows.
7438 * The alpha channel of the window defines which pixels are
7439 * invisible and allows for nicely antialiased borders,
7440 * and the input shape controls where the window is
7443 * On the X11 platform, this requires version 1.1 of the
7446 * On the Win32 platform, this functionality is not present and the
7447 * function does nothing.
7452 gdk_window_input_shape_combine_region (GdkWindow *window,
7453 const cairo_region_t *shape_region,
7457 GdkWindowObject *private;
7458 GdkWindowImplIface *impl_iface;
7460 g_return_if_fail (GDK_IS_WINDOW (window));
7462 private = (GdkWindowObject *) window;
7464 if (GDK_WINDOW_DESTROYED (window))
7467 if (private->input_shape)
7468 cairo_region_destroy (private->input_shape);
7472 private->input_shape = cairo_region_copy (shape_region);
7473 cairo_region_translate (private->input_shape, offset_x, offset_y);
7476 private->input_shape = NULL;
7478 if (gdk_window_has_impl (private))
7480 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7481 impl_iface->input_shape_combine_region (window, private->input_shape, 0, 0);
7484 /* Pointer may have e.g. moved outside window due to the input mask change */
7485 _gdk_synthesize_crossing_events_for_geometry_change (window);
7489 do_child_input_shapes (GdkWindow *window,
7492 GdkWindowObject *private;
7494 cairo_region_t *region;
7496 private = (GdkWindowObject *) window;
7500 r.width = private->width;
7501 r.height = private->height;
7503 region = cairo_region_create_rectangle (&r);
7504 remove_child_area (private, NULL, TRUE, region);
7506 if (merge && private->shape)
7507 cairo_region_subtract (region, private->shape);
7508 if (merge && private->input_shape)
7509 cairo_region_subtract (region, private->input_shape);
7511 gdk_window_input_shape_combine_region (window, region, 0, 0);
7516 * gdk_window_set_child_input_shapes:
7517 * @window: a #GdkWindow
7519 * Sets the input shape mask of @window to the union of input shape masks
7520 * for all children of @window, ignoring the input shape mask of @window
7521 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7522 * the input shape mask of @window in the masks to be merged.
7527 gdk_window_set_child_input_shapes (GdkWindow *window)
7529 g_return_if_fail (GDK_IS_WINDOW (window));
7531 do_child_input_shapes (window, FALSE);
7535 * gdk_window_merge_child_input_shapes:
7536 * @window: a #GdkWindow
7538 * Merges the input shape masks for any child windows into the
7539 * input shape mask for @window. i.e. the union of all input masks
7540 * for @window and its children will become the new input mask
7541 * for @window. See gdk_window_input_shape_combine_region().
7543 * This function is distinct from gdk_window_set_child_input_shapes()
7544 * because it includes @window's input shape mask in the set of
7545 * shapes to be merged.
7550 gdk_window_merge_child_input_shapes (GdkWindow *window)
7552 g_return_if_fail (GDK_IS_WINDOW (window));
7554 do_child_input_shapes (window, TRUE);
7559 * gdk_window_set_static_gravities:
7560 * @window: a #GdkWindow
7561 * @use_static: %TRUE to turn on static gravity
7563 * Set the bit gravity of the given window to static, and flag it so
7564 * all children get static subwindow gravity. This is used if you are
7565 * implementing scary features that involve deep knowledge of the
7566 * windowing system. Don't worry about it unless you have to.
7568 * Return value: %TRUE if the server supports static gravity
7571 gdk_window_set_static_gravities (GdkWindow *window,
7572 gboolean use_static)
7574 GdkWindowObject *private;
7575 GdkWindowImplIface *impl_iface;
7577 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7579 private = (GdkWindowObject *) window;
7581 if (gdk_window_has_impl (private))
7583 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (private->impl);
7584 return impl_iface->set_static_gravities (window, use_static);
7591 * gdk_window_get_composited:
7592 * @window: a #GdkWindow
7594 * Determines whether @window is composited.
7596 * See gdk_window_set_composited().
7598 * Returns: %TRUE if the window is composited.
7603 gdk_window_get_composited (GdkWindow *window)
7605 GdkWindowObject *private;
7607 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7609 private = (GdkWindowObject *)window;
7611 return private->composited;
7615 * gdk_window_set_composited:
7616 * @window: a #GdkWindow
7617 * @composited: %TRUE to set the window as composited
7619 * Sets a #GdkWindow as composited, or unsets it. Composited
7620 * windows do not automatically have their contents drawn to
7621 * the screen. Drawing is redirected to an offscreen buffer
7622 * and an expose event is emitted on the parent of the composited
7623 * window. It is the responsibility of the parent's expose handler
7624 * to manually merge the off-screen content onto the screen in
7625 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7628 * It only makes sense for child windows to be composited; see
7629 * gdk_window_set_opacity() if you need translucent toplevel
7632 * An additional effect of this call is that the area of this
7633 * window is no longer clipped from regions marked for
7634 * invalidation on its parent. Draws done on the parent
7635 * window are also no longer clipped by the child.
7637 * This call is only supported on some systems (currently,
7638 * only X11 with new enough Xcomposite and Xdamage extensions).
7639 * You must call gdk_display_supports_composite() to check if
7640 * setting a window as composited is supported before
7641 * attempting to do so.
7646 gdk_window_set_composited (GdkWindow *window,
7647 gboolean composited)
7649 GdkWindowObject *private = (GdkWindowObject *)window;
7650 GdkDisplay *display;
7652 g_return_if_fail (GDK_IS_WINDOW (window));
7654 composited = composited != FALSE;
7656 if (private->composited == composited)
7660 gdk_window_ensure_native (window);
7662 display = gdk_window_get_display (window);
7664 if (!gdk_display_supports_composite (display) && composited)
7666 g_warning ("gdk_window_set_composited called but "
7667 "compositing is not supported");
7671 _gdk_windowing_window_set_composited (window, composited);
7673 recompute_visible_regions (private, TRUE, FALSE);
7675 if (GDK_WINDOW_IS_MAPPED (window))
7676 gdk_window_invalidate_in_parent (private);
7678 private->composited = composited;
7682 * gdk_window_get_modal_hint:
7683 * @window: A toplevel #GdkWindow.
7685 * Determines whether or not the window manager is hinted that @window
7686 * has modal behaviour.
7688 * Return value: whether or not the window has the modal hint set.
7693 gdk_window_get_modal_hint (GdkWindow *window)
7695 GdkWindowObject *private;
7697 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7699 private = (GdkWindowObject*) window;
7701 return private->modal_hint;
7705 * gdk_window_get_accept_focus:
7706 * @window: a toplevel #GdkWindow.
7708 * Determines whether or not the desktop environment shuld be hinted that
7709 * the window does not want to receive input focus.
7711 * Return value: whether or not the window should receive input focus.
7716 gdk_window_get_accept_focus (GdkWindow *window)
7718 GdkWindowObject *private;
7720 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7722 private = (GdkWindowObject *)window;
7724 return private->accept_focus;
7728 * gdk_window_get_focus_on_map:
7729 * @window: a toplevel #GdkWindow.
7731 * Determines whether or not the desktop environment should be hinted that the
7732 * window does not want to receive input focus when it is mapped.
7734 * Return value: whether or not the window wants to receive input focus when
7740 gdk_window_get_focus_on_map (GdkWindow *window)
7742 GdkWindowObject *private;
7744 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7746 private = (GdkWindowObject *)window;
7748 return private->focus_on_map;
7752 * gdk_window_is_input_only:
7753 * @window: a toplevel #GdkWindow
7755 * Determines whether or not the window is an input only window.
7757 * Return value: %TRUE if @window is input only
7762 gdk_window_is_input_only (GdkWindow *window)
7764 GdkWindowObject *private;
7766 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7768 private = (GdkWindowObject *)window;
7770 return private->input_only;
7774 * gdk_window_is_shaped:
7775 * @window: a toplevel #GdkWindow
7777 * Determines whether or not the window is shaped.
7779 * Return value: %TRUE if @window is shaped
7784 gdk_window_is_shaped (GdkWindow *window)
7786 GdkWindowObject *private;
7788 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7790 private = (GdkWindowObject *)window;
7792 return private->shaped;
7796 window_get_size_rectangle (GdkWindow *window,
7799 GdkWindowObject *private = (GdkWindowObject *) window;
7801 rect->x = rect->y = 0;
7802 rect->width = private->width;
7803 rect->height = private->height;
7806 /* Calculates the real clipping region for a window, in window coordinates,
7807 * taking into account other windows, gc clip region and gc clip mask.
7810 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7811 GdkWindow *base_window,
7812 gboolean do_children,
7813 gint *base_x_offset,
7814 gint *base_y_offset)
7816 GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
7817 GdkRectangle visible_rect;
7818 cairo_region_t *real_clip_region;
7819 gint x_offset, y_offset;
7820 GdkWindowObject *parentwin, *lastwin;
7827 if (!private->viewable || private->input_only)
7828 return cairo_region_create ();
7830 window_get_size_rectangle (window, &visible_rect);
7832 /* real_clip_region is in window coordinates */
7833 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7835 x_offset = y_offset = 0;
7839 parentwin = lastwin;
7841 parentwin = lastwin->parent;
7843 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7844 for (; parentwin != NULL &&
7845 (parentwin == private || lastwin != (GdkWindowObject*) base_window);
7846 lastwin = parentwin, parentwin = lastwin->parent)
7849 GdkRectangle real_clip_rect;
7851 if (parentwin != private)
7853 x_offset += GDK_WINDOW_OBJECT (lastwin)->x;
7854 y_offset += GDK_WINDOW_OBJECT (lastwin)->y;
7857 /* children is ordered in reverse stack order */
7858 for (cur = parentwin->children;
7859 cur && cur->data != lastwin;
7862 GdkWindow *child = cur->data;
7863 GdkWindowObject *child_private = (GdkWindowObject *)child;
7865 if (!GDK_WINDOW_IS_MAPPED (child) || child_private->input_only)
7868 /* Ignore offscreen children, as they don't draw in their parent and
7869 * don't take part in the clipping */
7870 if (gdk_window_is_offscreen (child_private))
7873 window_get_size_rectangle (child, &visible_rect);
7875 /* Convert rect to "window" coords */
7876 visible_rect.x += child_private->x - x_offset;
7877 visible_rect.y += child_private->y - y_offset;
7879 /* This shortcut is really necessary for performance when there are a lot of windows */
7880 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7881 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7882 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7883 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7884 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7887 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7890 /* Clip to the parent */
7891 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7892 /* Convert rect to "window" coords */
7893 visible_rect.x += - x_offset;
7894 visible_rect.y += - y_offset;
7896 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7900 *base_x_offset = x_offset;
7902 *base_y_offset = y_offset;
7904 return real_clip_region;
7908 _gdk_window_add_damage (GdkWindow *toplevel,
7909 cairo_region_t *damaged_region)
7911 GdkDisplay *display;
7912 GdkEvent event = { 0, };
7913 event.expose.type = GDK_DAMAGE;
7914 event.expose.window = toplevel;
7915 event.expose.send_event = FALSE;
7916 event.expose.region = damaged_region;
7917 cairo_region_get_extents (event.expose.region, &event.expose.area);
7918 display = gdk_window_get_display (event.expose.window);
7919 _gdk_event_queue_append (display, gdk_event_copy (&event));
7922 /* Gets the toplevel for a window as used for events,
7923 i.e. including offscreen parents */
7924 static GdkWindowObject *
7925 get_event_parent (GdkWindowObject *window)
7927 if (gdk_window_is_offscreen (window))
7928 return (GdkWindowObject *)gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7930 return window->parent;
7933 /* Gets the toplevel for a window as used for events,
7934 i.e. including offscreen parents going up to the native
7937 get_event_toplevel (GdkWindow *w)
7939 GdkWindowObject *private = GDK_WINDOW_OBJECT (w);
7940 GdkWindowObject *parent;
7942 while ((parent = get_event_parent (private)) != NULL &&
7943 (parent->window_type != GDK_WINDOW_ROOT))
7946 return GDK_WINDOW (private);
7950 _gdk_window_event_parent_of (GdkWindow *parent,
7961 w = (GdkWindow *)get_event_parent ((GdkWindowObject *)w);
7968 update_cursor (GdkDisplay *display,
7971 GdkWindowObject *cursor_window, *parent, *toplevel;
7972 GdkWindow *pointer_window;
7973 GdkWindowImplIface *impl_iface;
7974 GdkPointerWindowInfo *pointer_info;
7975 GdkDeviceGrabInfo *grab;
7978 pointer_info = _gdk_display_get_pointer_info (display, device);
7979 pointer_window = pointer_info->window_under_pointer;
7981 /* We ignore the serials here and just pick the last grab
7982 we've sent, as that would shortly be used anyway. */
7983 grab = _gdk_display_get_last_device_grab (display, device);
7986 /* the pointer is not in a descendant of the grab window */
7987 !_gdk_window_event_parent_of (grab->window, pointer_window))
7989 /* use the cursor from the grab window */
7990 cursor_window = (GdkWindowObject *) grab->window;
7994 /* otherwise use the cursor from the pointer window */
7995 cursor_window = (GdkWindowObject *) pointer_window;
7998 /* Find the first window with the cursor actually set, as
7999 the cursor is inherited from the parent */
8000 while (cursor_window->cursor == NULL &&
8001 (parent = get_event_parent (cursor_window)) != NULL &&
8002 parent->window_type != GDK_WINDOW_ROOT)
8003 cursor_window = parent;
8005 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
8008 cursor = cursor_window->cursor;
8010 /* Set all cursors on toplevel, otherwise its tricky to keep track of
8011 * which native window has what cursor set. */
8012 toplevel = (GdkWindowObject *) get_event_toplevel (pointer_window);
8013 impl_iface = GDK_WINDOW_IMPL_GET_IFACE (toplevel->impl);
8014 impl_iface->set_device_cursor ((GdkWindow *) toplevel, device, cursor);
8018 point_in_window (GdkWindowObject *window,
8023 x >= 0 && x < window->width &&
8024 y >= 0 && y < window->height &&
8025 (window->shape == NULL ||
8026 cairo_region_contains_point (window->shape,
8028 (window->input_shape == NULL ||
8029 cairo_region_contains_point (window->input_shape,
8034 convert_native_coords_to_toplevel (GdkWindow *window,
8037 gdouble *toplevel_x,
8038 gdouble *toplevel_y)
8040 GdkWindowObject *private = (GdkWindowObject *)window;
8046 while (!gdk_window_is_toplevel (private))
8050 private = private->parent;
8056 return (GdkWindow *)private;
8060 convert_toplevel_coords_to_window (GdkWindow *window,
8066 GdkWindowObject *private;
8067 GdkWindowObject *parent;
8069 GList *children, *l;
8071 private = GDK_WINDOW_OBJECT (window);
8077 while ((parent = get_event_parent (private)) != NULL &&
8078 (parent->window_type != GDK_WINDOW_ROOT))
8080 children = g_list_prepend (children, private);
8084 for (l = children; l != NULL; l = l->next)
8085 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
8087 g_list_free (children);
8093 static GdkWindowObject *
8094 pick_embedded_child (GdkWindowObject *window,
8098 GdkWindowObject *res;
8101 g_signal_emit (window,
8102 signals[PICK_EMBEDDED_CHILD], 0,
8109 _gdk_window_find_child_at (GdkWindow *window,
8113 GdkWindowObject *private, *sub;
8114 double child_x, child_y;
8117 private = (GdkWindowObject *)window;
8119 if (point_in_window (private, x, y))
8121 /* Children is ordered in reverse stack order, i.e. first is topmost */
8122 for (l = private->children; l != NULL; l = l->next)
8126 if (!GDK_WINDOW_IS_MAPPED (sub))
8129 gdk_window_coords_from_parent ((GdkWindow *)sub,
8131 &child_x, &child_y);
8132 if (point_in_window (sub, child_x, child_y))
8133 return (GdkWindow *)sub;
8136 if (private->num_offscreen_children > 0)
8138 sub = pick_embedded_child (private,
8141 return (GdkWindow *)sub;
8149 _gdk_window_find_descendant_at (GdkWindow *toplevel,
8155 GdkWindowObject *private, *sub;
8156 gdouble child_x, child_y;
8160 private = (GdkWindowObject *)toplevel;
8162 if (point_in_window (private, x, y))
8167 /* Children is ordered in reverse stack order, i.e. first is topmost */
8168 for (l = private->children; l != NULL; l = l->next)
8172 if (!GDK_WINDOW_IS_MAPPED (sub))
8175 gdk_window_coords_from_parent ((GdkWindow *)sub,
8177 &child_x, &child_y);
8178 if (point_in_window (sub, child_x, child_y))
8188 private->num_offscreen_children > 0)
8190 sub = pick_embedded_child (private,
8196 from_embedder (sub, x, y, &x, &y);
8204 /* Not in window at all */
8213 return (GdkWindow *)private;
8218 * @window: a toplevel #GdkWindow
8220 * Emits a short beep associated to @window in the appropriate
8221 * display, if supported. Otherwise, emits a short beep on
8222 * the display just as gdk_display_beep().
8227 gdk_window_beep (GdkWindow *window)
8229 GdkDisplay *display;
8230 GdkWindow *toplevel;
8232 g_return_if_fail (GDK_IS_WINDOW (window));
8234 if (GDK_WINDOW_DESTROYED (window))
8237 toplevel = get_event_toplevel (window);
8238 display = gdk_window_get_display (window);
8240 if (toplevel && !gdk_window_is_offscreen ((GdkWindowObject *)toplevel))
8241 _gdk_windowing_window_beep (toplevel);
8243 gdk_display_beep (display);
8247 * gdk_window_set_support_multidevice:
8248 * @window: a #GdkWindow.
8249 * @support_multidevice: %TRUE to enable multidevice support in @window.
8251 * This function will enable multidevice features in @window.
8253 * Multidevice aware windows will need to handle properly multiple,
8254 * per device enter/leave events, device grabs and grab ownerships.
8259 gdk_window_set_support_multidevice (GdkWindow *window,
8260 gboolean support_multidevice)
8262 GdkWindowObject *private = (GdkWindowObject *) window;
8264 g_return_if_fail (GDK_IS_WINDOW (window));
8266 if (GDK_WINDOW_DESTROYED (window))
8269 if (private->support_multidevice == support_multidevice)
8272 private->support_multidevice = support_multidevice;
8274 /* FIXME: What to do if called when some pointers are inside the window ? */
8278 * gdk_window_get_support_multidevice:
8279 * @window: a #GdkWindow.
8281 * Returns %TRUE if the window is aware of the existence of multiple
8284 * Returns: %TRUE if the window handles multidevice features.
8289 gdk_window_get_support_multidevice (GdkWindow *window)
8291 GdkWindowObject *private = (GdkWindowObject *) window;
8293 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8295 if (GDK_WINDOW_DESTROYED (window))
8298 return private->support_multidevice;
8301 static const guint type_masks[] = {
8302 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8303 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8304 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8305 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8306 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8307 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8308 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8309 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8310 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8311 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8312 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8313 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8314 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8315 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8316 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8317 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8318 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8319 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8320 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8321 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8322 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8323 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8324 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8325 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8326 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8327 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8328 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8329 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8330 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8331 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8332 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8333 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8334 0, /* GDK_WINDOW_STATE = 32 */
8335 0, /* GDK_SETTING = 33 */
8336 0, /* GDK_OWNER_CHANGE = 34 */
8337 0, /* GDK_GRAB_BROKEN = 35 */
8338 0, /* GDK_DAMAGE = 36 */
8340 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8342 /* send motion events if the right buttons are down */
8344 update_evmask_for_button_motion (guint evmask,
8345 GdkModifierType mask)
8347 if (evmask & GDK_BUTTON_MOTION_MASK &&
8348 mask & (GDK_BUTTON1_MASK |
8353 evmask |= GDK_POINTER_MOTION_MASK;
8355 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8356 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8357 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8358 evmask |= GDK_POINTER_MOTION_MASK;
8364 is_button_type (GdkEventType type)
8366 return type == GDK_BUTTON_PRESS ||
8367 type == GDK_2BUTTON_PRESS ||
8368 type == GDK_3BUTTON_PRESS ||
8369 type == GDK_BUTTON_RELEASE ||
8374 is_motion_type (GdkEventType type)
8376 return type == GDK_MOTION_NOTIFY ||
8377 type == GDK_ENTER_NOTIFY ||
8378 type == GDK_LEAVE_NOTIFY;
8381 static GdkWindowObject *
8382 find_common_ancestor (GdkWindowObject *win1,
8383 GdkWindowObject *win2)
8385 GdkWindowObject *tmp;
8386 GList *path1 = NULL, *path2 = NULL;
8387 GList *list1, *list2;
8390 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8392 path1 = g_list_prepend (path1, tmp);
8393 tmp = get_event_parent (tmp);
8397 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8399 path2 = g_list_prepend (path2, tmp);
8400 tmp = get_event_parent (tmp);
8406 while (list1 && list2 && (list1->data == list2->data))
8408 tmp = (GdkWindowObject *)list1->data;
8409 list1 = g_list_next (list1);
8410 list2 = g_list_next (list2);
8412 g_list_free (path1);
8413 g_list_free (path2);
8419 _gdk_make_event (GdkWindow *window,
8421 GdkEvent *event_in_queue,
8422 gboolean before_event)
8424 GdkEvent *event = gdk_event_new (type);
8426 GdkModifierType the_state;
8428 the_time = gdk_event_get_time (event_in_queue);
8429 gdk_event_get_state (event_in_queue, &the_state);
8431 event->any.window = g_object_ref (window);
8432 event->any.send_event = FALSE;
8433 if (event_in_queue && event_in_queue->any.send_event)
8434 event->any.send_event = TRUE;
8438 case GDK_MOTION_NOTIFY:
8439 event->motion.time = the_time;
8440 event->motion.axes = NULL;
8441 event->motion.state = the_state;
8444 case GDK_BUTTON_PRESS:
8445 case GDK_2BUTTON_PRESS:
8446 case GDK_3BUTTON_PRESS:
8447 case GDK_BUTTON_RELEASE:
8448 event->button.time = the_time;
8449 event->button.axes = NULL;
8450 event->button.state = the_state;
8454 event->scroll.time = the_time;
8455 event->scroll.state = the_state;
8459 case GDK_KEY_RELEASE:
8460 event->key.time = the_time;
8461 event->key.state = the_state;
8464 case GDK_ENTER_NOTIFY:
8465 case GDK_LEAVE_NOTIFY:
8466 event->crossing.time = the_time;
8467 event->crossing.state = the_state;
8470 case GDK_PROPERTY_NOTIFY:
8471 event->property.time = the_time;
8472 event->property.state = the_state;
8475 case GDK_SELECTION_CLEAR:
8476 case GDK_SELECTION_REQUEST:
8477 case GDK_SELECTION_NOTIFY:
8478 event->selection.time = the_time;
8481 case GDK_PROXIMITY_IN:
8482 case GDK_PROXIMITY_OUT:
8483 event->proximity.time = the_time;
8486 case GDK_DRAG_ENTER:
8487 case GDK_DRAG_LEAVE:
8488 case GDK_DRAG_MOTION:
8489 case GDK_DRAG_STATUS:
8490 case GDK_DROP_START:
8491 case GDK_DROP_FINISHED:
8492 event->dnd.time = the_time;
8495 case GDK_FOCUS_CHANGE:
8499 case GDK_CLIENT_EVENT:
8500 case GDK_VISIBILITY_NOTIFY:
8512 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8514 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8517 _gdk_event_queue_append (gdk_window_get_display (window), event);
8523 send_crossing_event (GdkDisplay *display,
8524 GdkWindowObject *toplevel,
8525 GdkWindowObject *window,
8527 GdkCrossingMode mode,
8528 GdkNotifyType notify_type,
8529 GdkWindow *subwindow,
8533 GdkModifierType mask,
8535 GdkEvent *event_in_queue,
8539 guint32 window_event_mask, type_event_mask;
8540 GdkDeviceGrabInfo *grab;
8541 gboolean block_event = FALSE;
8543 grab = _gdk_display_has_device_grab (display, device, serial);
8546 !grab->owner_events)
8548 /* !owner_event => only report events wrt grab window, ignore rest */
8549 if ((GdkWindow *)window != grab->window)
8551 window_event_mask = grab->event_mask;
8554 window_event_mask = window->event_mask;
8556 if (type == GDK_LEAVE_NOTIFY)
8558 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8559 window->devices_inside = g_list_remove (window->devices_inside, device);
8561 if (!window->support_multidevice && window->devices_inside)
8563 /* Block leave events unless it's the last pointer */
8569 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8571 if (!window->support_multidevice && window->devices_inside)
8573 /* Only emit enter events for the first device */
8577 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8578 device->mode != GDK_MODE_DISABLED &&
8579 !g_list_find (window->devices_inside, device))
8580 window->devices_inside = g_list_prepend (window->devices_inside, device);
8586 if (window_event_mask & type_event_mask)
8588 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8589 gdk_event_set_device (event, device);
8590 event->crossing.time = time_;
8591 event->crossing.subwindow = subwindow;
8593 g_object_ref (subwindow);
8594 convert_toplevel_coords_to_window ((GdkWindow *)window,
8595 toplevel_x, toplevel_y,
8596 &event->crossing.x, &event->crossing.y);
8597 event->crossing.x_root = toplevel_x + toplevel->x;
8598 event->crossing.y_root = toplevel_y + toplevel->y;
8599 event->crossing.mode = mode;
8600 event->crossing.detail = notify_type;
8601 event->crossing.focus = FALSE;
8602 event->crossing.state = mask;
8607 /* The coordinates are in the toplevel window that src/dest are in.
8608 * src and dest are always (if != NULL) in the same toplevel, as
8609 * we get a leave-notify and set the window_under_pointer to null
8610 * before crossing to another toplevel.
8613 _gdk_synthesize_crossing_events (GdkDisplay *display,
8617 GdkCrossingMode mode,
8620 GdkModifierType mask,
8622 GdkEvent *event_in_queue,
8624 gboolean non_linear)
8627 GdkWindowObject *win, *last, *next;
8631 GdkWindowObject *toplevel;
8632 GdkNotifyType notify_type;
8634 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8636 a = (GdkWindowObject *)src;
8637 b = (GdkWindowObject *)dest;
8639 return; /* No crossings generated between src and dest */
8641 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8643 if (a && gdk_window_get_device_events (src, device) == 0)
8646 if (b && gdk_window_get_device_events (dest, device) == 0)
8653 c = find_common_ancestor (a, b);
8655 non_linear |= (c != a) && (c != b);
8657 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8659 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)a);
8661 /* Traverse up from a to (excluding) c sending leave events */
8663 notify_type = GDK_NOTIFY_NONLINEAR;
8665 notify_type = GDK_NOTIFY_INFERIOR;
8667 notify_type = GDK_NOTIFY_ANCESTOR;
8668 send_crossing_event (display, toplevel,
8669 a, GDK_LEAVE_NOTIFY,
8673 toplevel_x, toplevel_y,
8681 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8683 notify_type = GDK_NOTIFY_VIRTUAL;
8686 win = get_event_parent (a);
8687 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8689 send_crossing_event (display, toplevel,
8690 win, GDK_LEAVE_NOTIFY,
8695 toplevel_x, toplevel_y,
8701 win = get_event_parent (win);
8706 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8708 toplevel = (GdkWindowObject *)gdk_window_get_toplevel ((GdkWindow *)b);
8710 /* Traverse down from c to b */
8714 win = get_event_parent (b);
8715 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8717 path = g_list_prepend (path, win);
8718 win = get_event_parent (win);
8722 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8724 notify_type = GDK_NOTIFY_VIRTUAL;
8729 win = (GdkWindowObject *)list->data;
8730 list = g_list_next (list);
8732 next = (GdkWindowObject *)list->data;
8736 send_crossing_event (display, toplevel,
8737 win, GDK_ENTER_NOTIFY,
8742 toplevel_x, toplevel_y,
8752 notify_type = GDK_NOTIFY_NONLINEAR;
8754 notify_type = GDK_NOTIFY_ANCESTOR;
8756 notify_type = GDK_NOTIFY_INFERIOR;
8758 send_crossing_event (display, toplevel,
8759 b, GDK_ENTER_NOTIFY,
8764 toplevel_x, toplevel_y,
8771 /* Returns the window inside the event window with the pointer in it
8772 * at the specified coordinates, or NULL if its not in any child of
8773 * the toplevel. It also takes into account !owner_events grabs.
8776 get_pointer_window (GdkDisplay *display,
8777 GdkWindow *event_window,
8783 GdkWindow *pointer_window;
8784 GdkDeviceGrabInfo *grab;
8785 GdkPointerWindowInfo *pointer_info;
8787 pointer_info = _gdk_display_get_pointer_info (display, device);
8789 if (event_window == pointer_info->toplevel_under_pointer)
8791 _gdk_window_find_descendant_at (event_window,
8792 toplevel_x, toplevel_y,
8795 pointer_window = NULL;
8797 grab = _gdk_display_has_device_grab (display, device, serial);
8799 !grab->owner_events &&
8800 pointer_window != grab->window)
8801 pointer_window = NULL;
8803 return pointer_window;
8807 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8811 GdkPointerWindowInfo *device_info;
8813 /* We don't track this if all native, and it can cause issues
8814 with the update_cursor call below */
8815 if (_gdk_native_windows)
8818 device_info = _gdk_display_get_pointer_info (display, device);
8820 if (device_info->window_under_pointer)
8821 g_object_unref (device_info->window_under_pointer);
8822 device_info->window_under_pointer = window;
8826 g_object_ref (window);
8827 update_cursor (display, device);
8830 _gdk_display_enable_motion_hints (display, device);
8835 * @window: the #GdkWindow which will own the grab (the grab window).
8836 * @owner_events: if %FALSE then all pointer events are reported with respect to
8837 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8838 * events for this application are reported as normal, but pointer events outside
8839 * this application are reported with respect to @window and only if selected by
8840 * @event_mask. In either mode, unreported events are discarded.
8841 * @event_mask: specifies the event mask, which is used in accordance with
8842 * @owner_events. Note that only pointer events (i.e. button and motion events)
8844 * @confine_to: If non-%NULL, the pointer will be confined to this
8845 * window during the grab. If the pointer is outside @confine_to, it will
8846 * automatically be moved to the closest edge of @confine_to and enter
8847 * and leave events will be generated as necessary.
8848 * @cursor: the cursor to display while the grab is active. If this is %NULL then
8849 * the normal cursors are used for @window and its descendants, and the cursor
8850 * for @window is used for all other windows.
8851 * @time_: the timestamp of the event which led to this pointer grab. This usually
8852 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8853 * the time isn't known.
8855 * Grabs the pointer (usually a mouse) so that all events are passed to this
8856 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8857 * the grab window becomes unviewable.
8858 * This overrides any previous pointer grab by this client.
8860 * Pointer grabs are used for operations which need complete control over mouse
8861 * events, even if the mouse leaves the application.
8862 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8863 * the #GtkHPaned and #GtkVPaned widgets, and for resizing columns in #GtkCList
8866 * Note that if the event mask of an X window has selected both button press and
8867 * button release events, then a button press event will cause an automatic
8868 * pointer grab until the button is released.
8869 * X does this automatically since most applications expect to receive button
8870 * press and release events in pairs.
8871 * It is equivalent to a pointer grab on the window with @owner_events set to
8874 * If you set up anything at the time you take the grab that needs to be cleaned
8875 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8876 * are emitted when the grab ends unvoluntarily.
8878 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8880 * Deprecated: 3.0: Use gdk_device_grab() instead.
8883 gdk_pointer_grab (GdkWindow * window,
8884 gboolean owner_events,
8885 GdkEventMask event_mask,
8886 GdkWindow * confine_to,
8891 GdkDisplay *display;
8892 GdkDeviceManager *device_manager;
8894 GdkGrabStatus res = 0;
8896 GList *devices, *dev;
8898 g_return_val_if_fail (window != NULL, 0);
8899 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8900 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8902 /* We need a native window for confine to to work, ensure we have one */
8905 if (!gdk_window_ensure_native (confine_to))
8907 g_warning ("Can't confine to grabbed window, not native");
8912 /* Non-viewable client side window => fail */
8913 if (!_gdk_window_has_impl (window) &&
8914 !gdk_window_is_viewable (window))
8915 return GDK_GRAB_NOT_VIEWABLE;
8917 if (_gdk_native_windows)
8920 native = gdk_window_get_toplevel (window);
8921 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
8923 native = gdk_offscreen_window_get_embedder (native);
8925 if (native == NULL ||
8926 (!_gdk_window_has_impl (native) &&
8927 !gdk_window_is_viewable (native)))
8928 return GDK_GRAB_NOT_VIEWABLE;
8930 native = gdk_window_get_toplevel (native);
8933 display = gdk_window_get_display (window);
8935 serial = _gdk_windowing_window_get_next_serial (display);
8936 device_manager = gdk_display_get_device_manager (display);
8937 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8939 /* FIXME: Should this be generic to all backends? */
8940 /* FIXME: What happens with extended devices? */
8941 for (dev = devices; dev; dev = dev->next)
8945 if (device->source != GDK_SOURCE_MOUSE)
8948 res = _gdk_windowing_device_grab (device,
8952 get_native_grab_event_mask (event_mask),
8957 if (res == GDK_GRAB_SUCCESS)
8958 _gdk_display_add_device_grab (display,
8970 /* FIXME: handle errors when grabbing */
8972 g_list_free (devices);
8978 * gdk_keyboard_grab:
8979 * @window: the #GdkWindow which will own the grab (the grab window).
8980 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8981 * @window. If %TRUE then keyboard events for this application are
8982 * reported as normal, but keyboard events outside this application
8983 * are reported with respect to @window. Both key press and key
8984 * release events are always reported, independant of the event mask
8985 * set by the application.
8986 * @time: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8989 * Grabs the keyboard so that all events are passed to this
8990 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8991 * This overrides any previous keyboard grab by this client.
8993 * If you set up anything at the time you take the grab that needs to be cleaned
8994 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8995 * are emitted when the grab ends unvoluntarily.
8997 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8999 * Deprecated: 3.0: Use gdk_device_grab() instead.
9002 gdk_keyboard_grab (GdkWindow *window,
9003 gboolean owner_events,
9007 GdkDisplay *display;
9008 GdkDeviceManager *device_manager;
9010 GdkGrabStatus res = 0;
9012 GList *devices, *dev;
9014 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
9016 /* Non-viewable client side window => fail */
9017 if (!_gdk_window_has_impl (window) &&
9018 !gdk_window_is_viewable (window))
9019 return GDK_GRAB_NOT_VIEWABLE;
9021 if (_gdk_native_windows)
9024 native = gdk_window_get_toplevel (window);
9026 while (gdk_window_is_offscreen ((GdkWindowObject *)native))
9028 native = gdk_offscreen_window_get_embedder (native);
9030 if (native == NULL ||
9031 (!_gdk_window_has_impl (native) &&
9032 !gdk_window_is_viewable (native)))
9033 return GDK_GRAB_NOT_VIEWABLE;
9035 native = gdk_window_get_toplevel (native);
9038 display = gdk_window_get_display (window);
9040 serial = _gdk_windowing_window_get_next_serial (display);
9041 device_manager = gdk_display_get_device_manager (display);
9042 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
9044 /* FIXME: Should this be generic to all backends? */
9045 /* FIXME: What happens with extended devices? */
9046 for (dev = devices; dev; dev = dev->next)
9050 if (device->source != GDK_SOURCE_KEYBOARD)
9053 res = _gdk_windowing_device_grab (device,
9057 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
9062 if (res == GDK_GRAB_SUCCESS)
9063 _gdk_display_add_device_grab (display,
9074 /* FIXME: handle errors when grabbing */
9076 g_list_free (devices);
9082 * gdk_window_geometry_changed:
9083 * @window: an embedded offscreen #GdkWindow
9085 * This function informs GDK that the geometry of an embedded
9086 * offscreen window has changed. This is necessary for GDK to keep
9087 * track of which offscreen window the pointer is in.
9092 gdk_window_geometry_changed (GdkWindow *window)
9094 _gdk_synthesize_crossing_events_for_geometry_change (window);
9098 do_synthesize_crossing_event (gpointer data)
9100 GdkDisplay *display;
9101 GdkWindow *changed_toplevel;
9102 GdkWindowObject *changed_toplevel_priv;
9103 GHashTableIter iter;
9104 gpointer key, value;
9107 changed_toplevel = data;
9108 changed_toplevel_priv = (GdkWindowObject *)changed_toplevel;
9110 changed_toplevel_priv->synthesize_crossing_event_queued = FALSE;
9112 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9115 display = gdk_window_get_display (changed_toplevel);
9116 serial = _gdk_windowing_window_get_next_serial (display);
9117 g_hash_table_iter_init (&iter, display->pointers_info);
9119 while (g_hash_table_iter_next (&iter, &key, &value))
9121 GdkWindow *new_window_under_pointer;
9122 GdkPointerWindowInfo *pointer_info = value;
9123 GdkDevice *device = key;
9125 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9127 new_window_under_pointer =
9128 get_pointer_window (display, changed_toplevel,
9130 pointer_info->toplevel_x,
9131 pointer_info->toplevel_y,
9133 if (new_window_under_pointer != pointer_info->window_under_pointer)
9135 _gdk_synthesize_crossing_events (display,
9136 pointer_info->window_under_pointer,
9137 new_window_under_pointer,
9139 GDK_CROSSING_NORMAL,
9140 pointer_info->toplevel_x,
9141 pointer_info->toplevel_y,
9142 pointer_info->state,
9147 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9156 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9158 GdkDisplay *display;
9159 GdkWindow *toplevel;
9160 GdkWindowObject *toplevel_priv;
9162 if (_gdk_native_windows)
9163 return; /* We use the native crossing events if all native */
9165 display = gdk_window_get_display (changed_window);
9167 toplevel = get_event_toplevel (changed_window);
9168 toplevel_priv = (GdkWindowObject *) toplevel;
9170 if (!toplevel_priv->synthesize_crossing_event_queued)
9172 toplevel_priv->synthesize_crossing_event_queued = TRUE;
9174 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9175 do_synthesize_crossing_event,
9176 g_object_ref (toplevel),
9181 /* Don't use for crossing events */
9183 get_event_window (GdkDisplay *display,
9185 GdkWindow *pointer_window,
9187 GdkModifierType mask,
9192 GdkWindow *grab_window;
9194 GdkDeviceGrabInfo *grab;
9196 grab = _gdk_display_has_device_grab (display, device, serial);
9198 if (grab != NULL && !grab->owner_events)
9200 evmask = grab->event_mask;
9201 evmask = update_evmask_for_button_motion (evmask, mask);
9203 grab_window = grab->window;
9205 if (evmask & type_masks[type])
9208 *evmask_out = evmask;
9215 w = (GdkWindowObject *)pointer_window;
9218 evmask = w->event_mask;
9219 evmask = update_evmask_for_button_motion (evmask, mask);
9221 if (evmask & type_masks[type])
9224 *evmask_out = evmask;
9225 return (GdkWindow *)w;
9228 w = get_event_parent (w);
9234 evmask = grab->event_mask;
9235 evmask = update_evmask_for_button_motion (evmask, mask);
9237 if (evmask & type_masks[type])
9240 *evmask_out = evmask;
9241 return grab->window;
9251 proxy_pointer_event (GdkDisplay *display,
9252 GdkEvent *source_event,
9255 GdkWindow *toplevel_window, *event_window;
9256 GdkWindow *pointer_window;
9257 GdkPointerWindowInfo *pointer_info;
9261 gdouble toplevel_x, toplevel_y;
9263 gboolean non_linear;
9265 event_window = source_event->any.window;
9266 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9267 gdk_event_get_state (source_event, &state);
9268 time_ = gdk_event_get_time (source_event);
9269 device = gdk_event_get_device (source_event);
9270 pointer_info = _gdk_display_get_pointer_info (display, device);
9271 toplevel_window = convert_native_coords_to_toplevel (event_window,
9272 toplevel_x, toplevel_y,
9273 &toplevel_x, &toplevel_y);
9276 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9277 source_event->type == GDK_ENTER_NOTIFY) &&
9278 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9279 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9282 /* If we get crossing events with subwindow unexpectedly being NULL
9283 that means there is a native subwindow that gdk doesn't know about.
9284 We track these and forward them, with the correct virtual window
9286 This is important to get right, as metacity uses gdk for the frame
9287 windows, but gdk doesn't know about the client windows reparented
9289 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9290 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9291 (source_event->type == GDK_ENTER_NOTIFY &&
9292 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9293 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9294 source_event->crossing.subwindow == NULL)
9296 /* Left for an unknown (to gdk) subwindow */
9298 /* Send leave events from window under pointer to event window
9299 that will get the subwindow == NULL window */
9300 _gdk_synthesize_crossing_events (display,
9301 pointer_info->window_under_pointer,
9304 source_event->crossing.mode,
9305 toplevel_x, toplevel_y,
9311 /* Send subwindow == NULL event */
9312 send_crossing_event (display,
9313 (GdkWindowObject *)toplevel_window,
9314 (GdkWindowObject *)event_window,
9316 source_event->crossing.mode,
9317 source_event->crossing.detail,
9320 toplevel_x, toplevel_y,
9325 _gdk_display_set_window_under_pointer (display, device, NULL);
9329 pointer_window = get_pointer_window (display, toplevel_window, device,
9330 toplevel_x, toplevel_y, serial);
9332 if (((source_event->type == GDK_ENTER_NOTIFY &&
9333 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9334 (source_event->type == GDK_LEAVE_NOTIFY &&
9335 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9336 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9337 source_event->crossing.subwindow == NULL)
9339 /* Entered from an unknown (to gdk) subwindow */
9341 /* Send subwindow == NULL event */
9342 send_crossing_event (display,
9343 (GdkWindowObject *)toplevel_window,
9344 (GdkWindowObject *)event_window,
9346 source_event->crossing.mode,
9347 source_event->crossing.detail,
9350 toplevel_x, toplevel_y,
9355 /* Send enter events from event window to pointer_window */
9356 _gdk_synthesize_crossing_events (display,
9360 source_event->crossing.mode,
9361 toplevel_x, toplevel_y,
9364 serial, non_linear);
9365 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9369 if (pointer_info->window_under_pointer != pointer_window)
9371 /* Either a toplevel crossing notify that ended up inside a child window,
9372 or a motion notify that got into another child window */
9374 /* Different than last time, send crossing events */
9375 _gdk_synthesize_crossing_events (display,
9376 pointer_info->window_under_pointer,
9379 GDK_CROSSING_NORMAL,
9380 toplevel_x, toplevel_y,
9383 serial, non_linear);
9384 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9386 else if (source_event->type == GDK_MOTION_NOTIFY)
9388 GdkWindow *event_win;
9392 event_win = get_event_window (display,
9401 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9402 gdk_window_get_device_events (event_win, device) == 0)
9408 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9410 gulong *device_serial;
9412 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9414 if (!device_serial ||
9415 (*device_serial != 0 &&
9416 serial < *device_serial))
9417 event_win = NULL; /* Ignore event */
9421 *device_serial = G_MAXULONG;
9425 if (event_win && !display->ignore_core_events)
9427 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9428 event->motion.time = time_;
9429 convert_toplevel_coords_to_window (event_win,
9430 toplevel_x, toplevel_y,
9431 &event->motion.x, &event->motion.y);
9432 event->motion.x_root = source_event->motion.x_root;
9433 event->motion.y_root = source_event->motion.y_root;
9434 event->motion.state = state;
9435 event->motion.is_hint = is_hint;
9436 event->motion.device = source_event->motion.device;
9437 event->motion.axes = g_memdup (source_event->motion.axes,
9438 sizeof (gdouble) * source_event->motion.device->num_axes);
9442 /* unlink all move events from queue.
9443 We handle our own, including our emulated masks. */
9447 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9448 GDK_BUTTON2_MASK | \
9449 GDK_BUTTON3_MASK | \
9450 GDK_BUTTON4_MASK | \
9454 proxy_button_event (GdkEvent *source_event,
9457 GdkWindow *toplevel_window, *event_window;
9458 GdkWindow *event_win;
9459 GdkWindow *pointer_window;
9460 GdkWindowObject *parent;
9465 gdouble toplevel_x, toplevel_y;
9466 GdkDisplay *display;
9470 type = source_event->any.type;
9471 event_window = source_event->any.window;
9472 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9473 gdk_event_get_state (source_event, &state);
9474 time_ = gdk_event_get_time (source_event);
9475 device = gdk_event_get_device (source_event);
9476 display = gdk_window_get_display (source_event->any.window);
9477 toplevel_window = convert_native_coords_to_toplevel (event_window,
9478 toplevel_x, toplevel_y,
9479 &toplevel_x, &toplevel_y);
9481 if (type == GDK_BUTTON_PRESS &&
9482 !source_event->any.send_event &&
9483 _gdk_display_has_device_grab (display, device, serial) == NULL)
9486 _gdk_window_find_descendant_at (toplevel_window,
9487 toplevel_x, toplevel_y,
9490 /* Find the event window, that gets the grab */
9491 w = (GdkWindowObject *)pointer_window;
9493 (parent = get_event_parent (w)) != NULL &&
9494 parent->window_type != GDK_WINDOW_ROOT)
9496 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9500 pointer_window = (GdkWindow *)w;
9502 _gdk_display_add_device_grab (display,
9508 gdk_window_get_events (pointer_window),
9512 _gdk_display_device_grab_update (display, device, serial);
9515 pointer_window = get_pointer_window (display, toplevel_window, device,
9516 toplevel_x, toplevel_y,
9519 event_win = get_event_window (display,
9525 if (event_win == NULL || display->ignore_core_events)
9528 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9529 gdk_window_get_device_events (event_win, device) == 0)
9532 event = _gdk_make_event (event_win, type, source_event, FALSE);
9536 case GDK_BUTTON_PRESS:
9537 case GDK_BUTTON_RELEASE:
9538 event->button.button = source_event->button.button;
9539 convert_toplevel_coords_to_window (event_win,
9540 toplevel_x, toplevel_y,
9541 &event->button.x, &event->button.y);
9542 event->button.x_root = source_event->button.x_root;
9543 event->button.y_root = source_event->button.y_root;
9544 event->button.state = state;
9545 event->button.device = source_event->button.device;
9546 event->button.axes = g_memdup (source_event->button.axes,
9547 sizeof (gdouble) * source_event->button.device->num_axes);
9549 if (type == GDK_BUTTON_PRESS)
9550 _gdk_event_button_generate (display, event);
9554 event->scroll.direction = source_event->scroll.direction;
9555 convert_toplevel_coords_to_window (event_win,
9556 toplevel_x, toplevel_y,
9557 &event->scroll.x, &event->scroll.y);
9558 event->scroll.x_root = source_event->scroll.x_root;
9559 event->scroll.y_root = source_event->scroll.y_root;
9560 event->scroll.state = state;
9561 event->scroll.device = source_event->scroll.device;
9568 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9571 #ifdef DEBUG_WINDOW_PRINTING
9573 gdk_window_print (GdkWindowObject *window,
9577 const char *window_types[] = {
9587 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9588 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9589 window->x, window->y,
9590 window->width, window->height
9593 if (gdk_window_has_impl (window))
9595 #ifdef GDK_WINDOWING_X11
9596 g_print (" impl(0x%lx)", gdk_x11_drawable_get_xid (GDK_DRAWABLE (window)));
9600 if (window->window_type != GDK_WINDOW_CHILD)
9601 g_print (" %s", window_types[window->window_type]);
9603 if (window->input_only)
9604 g_print (" input-only");
9607 g_print (" shaped");
9609 if (!gdk_window_is_visible ((GdkWindow *)window))
9610 g_print (" hidden");
9612 g_print (" abs[%d,%d]",
9613 window->abs_x, window->abs_y);
9615 cairo_region_get_extents (window->clip_region, &r);
9616 if (cairo_region_is_empty (window->clip_region))
9617 g_print (" clipbox[empty]");
9619 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9626 gdk_window_print_tree (GdkWindow *window,
9628 gboolean include_input_only)
9630 GdkWindowObject *private;
9633 private = (GdkWindowObject *)window;
9635 if (private->input_only && !include_input_only)
9638 gdk_window_print (private, indent);
9640 for (l = private->children; l != NULL; l = l->next)
9641 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9644 #endif /* DEBUG_WINDOW_PRINTING */
9647 _gdk_windowing_got_event (GdkDisplay *display,
9652 GdkWindow *event_window;
9653 GdkWindowObject *event_private;
9655 gboolean unlink_event;
9656 guint old_state, old_button;
9657 GdkDeviceGrabInfo *button_release_grab;
9658 GdkPointerWindowInfo *pointer_info;
9660 gboolean is_toplevel;
9662 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9663 display->last_event_time = gdk_event_get_time (event);
9665 device = gdk_event_get_device (event);
9671 g_object_get (device, "input-mode", &mode, NULL);
9672 _gdk_display_device_grab_update (display, device, serial);
9674 if (mode == GDK_MODE_DISABLED ||
9675 !_gdk_display_check_grab_ownership (display, device, serial))
9677 /* Device events are blocked by another
9678 * device grab, or the device is disabled
9680 unlink_event = TRUE;
9685 event_window = event->any.window;
9689 pointer_info = _gdk_display_get_pointer_info (display, device);
9690 event_private = GDK_WINDOW_OBJECT (event_window);
9692 #ifdef DEBUG_WINDOW_PRINTING
9693 if (event->type == GDK_KEY_PRESS &&
9694 (event->key.keyval == 0xa7 ||
9695 event->key.keyval == 0xbd))
9697 gdk_window_print_tree (event_window, 0,
9698 event->key.keyval == 0xbd);
9702 if (_gdk_native_windows)
9704 if (event->type == GDK_BUTTON_PRESS &&
9705 !event->any.send_event &&
9706 _gdk_display_has_device_grab (display, device, serial) == NULL)
9708 _gdk_display_add_device_grab (display,
9714 gdk_window_get_events (event_window),
9716 gdk_event_get_time (event),
9718 _gdk_display_device_grab_update (display, device, serial);
9720 if (event->type == GDK_BUTTON_RELEASE &&
9721 !event->any.send_event)
9723 button_release_grab =
9724 _gdk_display_has_device_grab (display, device, serial);
9725 if (button_release_grab &&
9726 button_release_grab->implicit &&
9727 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9729 button_release_grab->serial_end = serial;
9730 button_release_grab->implicit_ungrab = FALSE;
9731 _gdk_display_device_grab_update (display, device, serial);
9735 if (event->type == GDK_BUTTON_PRESS)
9736 _gdk_event_button_generate (display, event);
9741 if (event->type == GDK_VISIBILITY_NOTIFY)
9743 event_private->native_visibility = event->visibility.state;
9744 gdk_window_update_visibility_recursively (event_private,
9749 if (!(is_button_type (event->type) ||
9750 is_motion_type (event->type)) ||
9751 event_private->window_type == GDK_WINDOW_ROOT)
9754 is_toplevel = gdk_window_is_toplevel (event_private);
9756 if ((event->type == GDK_ENTER_NOTIFY ||
9757 event->type == GDK_LEAVE_NOTIFY) &&
9758 (event->crossing.mode == GDK_CROSSING_GRAB ||
9759 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9760 (_gdk_display_has_device_grab (display, device, serial) ||
9761 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9763 /* We synthesize all crossing events due to grabs ourselves,
9764 * so we ignore the native ones caused by our native pointer_grab
9765 * calls. Otherwise we would proxy these crossing event and cause
9766 * multiple copies of crossing events for grabs.
9768 * We do want to handle grabs from other clients though, as for
9769 * instance alt-tab in metacity causes grabs like these and
9770 * we want to handle those. Thus the has_pointer_grab check.
9772 * Implicit grabs on child windows create some grabbing events
9773 * that are sent before the button press. This means we can't
9774 * detect these with the has_pointer_grab check (as the implicit
9775 * grab is only noticed when we get button press event), so we
9776 * detect these events by checking for INFERIOR enter or leave
9777 * events. These should never be a problem to filter out.
9780 /* We ended up in this window after some (perhaps other clients)
9781 grab, so update the toplevel_under_window state */
9783 event->type == GDK_ENTER_NOTIFY &&
9784 event->crossing.mode == GDK_CROSSING_UNGRAB)
9786 if (pointer_info->toplevel_under_pointer)
9787 g_object_unref (pointer_info->toplevel_under_pointer);
9788 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9791 unlink_event = TRUE;
9795 /* Track toplevel_under_pointer */
9798 if (event->type == GDK_ENTER_NOTIFY &&
9799 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9801 if (pointer_info->toplevel_under_pointer)
9802 g_object_unref (pointer_info->toplevel_under_pointer);
9803 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9805 else if (event->type == GDK_LEAVE_NOTIFY &&
9806 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9807 pointer_info->toplevel_under_pointer == event_window)
9809 if (pointer_info->toplevel_under_pointer)
9810 g_object_unref (pointer_info->toplevel_under_pointer);
9811 pointer_info->toplevel_under_pointer = NULL;
9815 /* Store last pointer window and position/state */
9816 old_state = pointer_info->state;
9817 old_button = pointer_info->button;
9819 gdk_event_get_coords (event, &x, &y);
9820 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9821 pointer_info->toplevel_x = x;
9822 pointer_info->toplevel_y = y;
9823 gdk_event_get_state (event, &pointer_info->state);
9824 if (event->type == GDK_BUTTON_PRESS ||
9825 event->type == GDK_BUTTON_RELEASE)
9826 pointer_info->button = event->button.button;
9829 (pointer_info->state != old_state ||
9830 pointer_info->button != old_button))
9831 _gdk_display_enable_motion_hints (display, device);
9833 unlink_event = FALSE;
9834 if (is_motion_type (event->type))
9835 unlink_event = proxy_pointer_event (display,
9838 else if (is_button_type (event->type))
9839 unlink_event = proxy_button_event (event,
9842 if (event->type == GDK_BUTTON_RELEASE &&
9843 !event->any.send_event)
9845 button_release_grab =
9846 _gdk_display_has_device_grab (display, device, serial);
9847 if (button_release_grab &&
9848 button_release_grab->implicit &&
9849 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9851 button_release_grab->serial_end = serial;
9852 button_release_grab->implicit_ungrab = FALSE;
9853 _gdk_display_device_grab_update (display, device, serial);
9860 _gdk_event_queue_remove_link (display, event_link);
9861 g_list_free_1 (event_link);
9862 gdk_event_free (event);
9868 get_extension_event_window (GdkDisplay *display,
9869 GdkWindow *pointer_window,
9874 GdkWindow *grab_window;
9876 GdkDeviceGrabInfo *grab;
9878 /* FIXME: which device? */
9879 grab = _gdk_display_has_device_grab (display, display->core_pointer, serial);
9881 if (grab != NULL && !grab->owner_events)
9883 evmask = grab->event_mask;
9885 grab_window = grab->window;
9887 if (evmask & type_masks[type])
9893 w = (GdkWindowObject *)pointer_window;
9896 evmask = w->extension_events;
9898 if (evmask & type_masks[type])
9899 return (GdkWindow *)w;
9901 w = get_event_parent (w);
9907 evmask = grab->event_mask;
9909 if (evmask & type_masks[type])
9910 return grab->window;
9920 _gdk_window_get_input_window_for_event (GdkWindow *native_window,
9921 GdkEventType event_type,
9925 GdkDisplay *display;
9926 GdkWindow *toplevel_window;
9927 GdkWindow *pointer_window;
9928 GdkWindow *event_win;
9929 gdouble toplevel_x, toplevel_y;
9934 display = gdk_window_get_display (native_window);
9935 toplevel_window = convert_native_coords_to_toplevel (native_window,
9936 toplevel_x, toplevel_y,
9937 &toplevel_x, &toplevel_y);
9938 /* FIXME: which device? */
9939 pointer_window = get_pointer_window (display, toplevel_window, NULL,
9940 toplevel_x, toplevel_y, serial);
9941 event_win = get_extension_event_window (display,
9950 * gdk_window_create_similar_surface:
9951 * @window: window to make new surface similar to
9952 * @content: the content for the new surface
9953 * @width: width of the new surface
9954 * @height: height of the new surface
9956 * Create a new surface that is as compatible as possible with the
9957 * given @window. For example the new surface will have the same
9958 * fallback resolution and font options as @window. Generally, the new
9959 * surface will also use the same backend as @window, unless that is
9960 * not possible for some reason. The type of the returned surface may
9961 * be examined with cairo_surface_get_type().
9963 * Initially the surface contents are all 0 (transparent if contents
9964 * have transparency, black otherwise.)
9966 * Returns: a pointer to the newly allocated surface. The caller
9967 * owns the surface and should call cairo_surface_destroy() when done
9970 * This function always returns a valid pointer, but it will return a
9971 * pointer to a "nil" surface if @other is already in an error state
9972 * or any other error occurs.
9977 gdk_window_create_similar_surface (GdkWindow * window,
9978 cairo_content_t content,
9982 cairo_surface_t *window_surface, *surface;
9984 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9986 window_surface = _gdk_drawable_ref_cairo_surface (window);
9988 surface = cairo_surface_create_similar (window_surface,
9992 cairo_surface_destroy (window_surface);