1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3 * Josh MacDonald, Ryan Lortie
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include <cairo-gobject.h>
32 #include "gdkwindow.h"
34 #ifdef GDK_WINDOWING_X11
35 #include "x11/gdkx.h" /* For workaround */
38 #include "gdkrectangle.h"
39 #include "gdkinternals.h"
41 #include "gdkscreen.h"
42 #include "gdkdeviceprivate.h"
43 #include "gdkmarshalers.h"
44 #include "gdkscreen.h"
45 #include "gdkwindowimpl.h"
49 #undef DEBUG_WINDOW_PRINTING
54 * @Short_description: Onscreen display areas in the target window system
57 * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
58 * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
59 * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
60 * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
61 * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
64 * <refsect2 id="COMPOSITED-WINDOWS">
65 * <title>Composited Windows</title>
67 * Normally, the windowing system takes care of rendering the contents of a
68 * child window onto its parent window. This mechanism can be intercepted by
69 * calling gdk_window_set_composited() on the child window. For a
70 * <firstterm>composited</firstterm> window it is the responsibility of the
71 * application to render the window contents at the right spot.
73 * <example id="composited-window-example">
74 * <title>Composited windows</title>
76 * <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../examples/gdk/composited-window-example.c"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include>
77 * </programlisting></example>
79 * In the example <xref linkend="composited-window-example"/>, a button is
80 * placed inside of an event box inside of a window. The event box is set as
81 * composited and therefore is no longer automatically drawn to the screen.
83 * When the contents of the event box change, an expose event is generated on
84 * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
85 * The expose handler for this widget is responsible for merging the changes
86 * back on the screen in the way that it wishes.
88 * In our case, we merge the contents with a 50% transparency. We also set the
89 * background colour of the window to red. The effect is that the background
90 * shows through the button.
93 * <refsect2 id="OFFSCREEN-WINDOWS">
94 * <title>Offscreen Windows</title>
96 * Offscreen windows are more general than composited windows, since they allow
97 * not only to modify the rendering of the child window onto its parent, but
98 * also to apply coordinate transformations.
100 * To integrate an offscreen window into a window hierarchy, one has to call
101 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
102 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
103 * select an offscreen child at given coordinates, and the
104 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
105 * offscreen window are used to translate coordinates between the embedder and
106 * the offscreen window.
108 * For rendering an offscreen window onto its embedder, the contents of the
109 * offscreen window are available as a surface, via
110 * gdk_offscreen_window_get_surface().
116 /* Historically a GdkWindow always matches a platform native window,
117 * be it a toplevel window or a child window. In this setup the
118 * GdkWindow (and other GdkDrawables) were platform independent classes,
119 * and the actual platform specific implementation was in a delegate
120 * object availible as "impl" in the window object.
122 * With the addition of client side windows and offscreen windows this
123 * changes a bit. The application-visible GdkWindow object behaves as
124 * it did before, but not all such windows now have a corresponding native
125 * window. Instead windows that are "client side" are emulated by the gdk
126 * code such that clipping, drawing, moving, events etc work as expected.
128 * For GdkWindows that have a native window the "impl" object is the
129 * same as before. However, for all client side windows the impl object
130 * is shared with its parent (i.e. all client windows descendants of one
131 * native window has the same impl.
133 * Additionally there is a new type of platform independent impl object,
134 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
135 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
136 * windows). Such windows work by allocating a #cairo_surface_t as the backing
137 * store for drawing operations, which is resized with the window.
139 * GdkWindows have a pointer to the "impl window" they are in, i.e.
140 * the topmost GdkWindow which have the same "impl" value. This is stored
141 * in impl_window, which is different from the window itself only for client
143 * All GdkWindows (native or not) track the position of the window in the parent
144 * (x, y), the size of the window (width, height), the position of the window
145 * with respect to the impl window (abs_x, abs_y). We also track the clip
146 * region of the window wrt parent windows and siblings, in window-relative
147 * coordinates with and without child windows included (clip_region,
148 * clip_region_with_children).
150 * All toplevel windows are native windows, but also child windows can be
151 * native (although not children of offscreens). We always listen to
152 * a basic set of events (see get_native_event_mask) for these windows
153 * so that we can emulate events for any client side children.
155 * For native windows we apply the calculated clip region as a window shape
156 * so that eg. client side siblings that overlap the native child properly
157 * draws over the native child window.
159 * In order to minimize flicker and for performance we use a couple of cacheing
160 * tricks. First of all, every time we do a window to window copy area, for instance
161 * when moving a client side window or when scrolling/moving a region in a window
162 * we store this in outstanding_moves instead of applying immediately. We then
163 * delay this move until we really need it (because something depends on being
164 * able to read it), or until we're handing a redraw from an expose/invalidation
165 * (actually we delay it past redraw, but before blitting the double buffer
166 * to the window). This gives us two advantages. First of all it minimizes the time
167 * from the window is moved to the exposes related to that move, secondly it allows
168 * us to be smart about how to do the copy. We combine multiple moves into one (when
169 * possible) and we don't actually do copies to anything that is or will be
170 * invalidated and exposed anyway.
172 * Secondly, we use something called a "implicit paint" during repaint handling.
173 * An implicit paint is similar to a regular paint for the paint stack, but it is
174 * not put on the stack. Instead, it is set on the impl window, and later when
175 * regular gdk_window_begin_paint_region() happen on a window of this impl window
176 * we reuse the surface from the implicit paint. During repaint we create and at the
177 * end flush an implicit paint, which means we can collect all the paints on
178 * multiple client side windows in the same backing store.
181 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
183 /* This adds a local value to the GdkVisibilityState enum */
184 #define GDK_VISIBILITY_NOT_VIEWABLE 3
187 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
201 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
205 struct _GdkWindowPaint
207 cairo_region_t *region;
208 cairo_surface_t *surface;
209 guint uses_implicit : 1;
215 cairo_region_t *dest_region; /* The destination region */
216 int dx, dy; /* The amount that the source was moved to reach dest_region */
217 } GdkWindowRegionMove;
221 static void gdk_window_drop_cairo_surface (GdkWindow *private);
223 static void gdk_window_free_paint_stack (GdkWindow *window);
225 static void gdk_window_init (GdkWindow *window);
226 static void gdk_window_class_init (GdkWindowClass *klass);
227 static void gdk_window_finalize (GObject *object);
229 static void gdk_window_set_property (GObject *object,
233 static void gdk_window_get_property (GObject *object,
238 static void gdk_window_clear_backing_region (GdkWindow *window,
239 cairo_region_t *region);
241 static void recompute_visible_regions (GdkWindow *private,
242 gboolean recalculate_siblings,
243 gboolean recalculate_children);
244 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
245 static void gdk_window_flush_recursive (GdkWindow *window);
246 static void do_move_region_bits_on_impl (GdkWindow *window,
247 cairo_region_t *region, /* In impl window coords */
249 static void gdk_window_invalidate_in_parent (GdkWindow *private);
250 static void move_native_children (GdkWindow *private);
251 static void update_cursor (GdkDisplay *display,
253 static void impl_window_add_update_area (GdkWindow *impl_window,
254 cairo_region_t *region);
255 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
256 static void gdk_window_invalidate_region_full (GdkWindow *window,
257 const cairo_region_t *region,
258 gboolean invalidate_children,
260 static void gdk_window_invalidate_rect_full (GdkWindow *window,
261 const GdkRectangle *rect,
262 gboolean invalidate_children,
265 static guint signals[LAST_SIGNAL] = { 0 };
267 static gpointer parent_class = NULL;
269 static const cairo_user_data_key_t gdk_window_cairo_key;
272 new_region_tag (void)
274 static guint32 tag = 0;
280 gdk_window_get_type (void)
282 static GType object_type = 0;
285 object_type = g_type_register_static_simple (G_TYPE_OBJECT,
287 sizeof (GdkWindowClass),
288 (GClassInitFunc) gdk_window_class_init,
290 (GInstanceInitFunc) gdk_window_init,
297 _gdk_paintable_get_type (void)
299 static GType paintable_type = 0;
303 const GTypeInfo paintable_info =
305 sizeof (GdkPaintableIface), /* class_size */
306 NULL, /* base_init */
307 NULL, /* base_finalize */
310 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
311 g_intern_static_string ("GdkPaintable"),
314 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
317 return paintable_type;
321 gdk_window_init (GdkWindow *window)
323 /* 0-initialization is good for all other fields. */
325 window->window_type = GDK_WINDOW_CHILD;
327 window->state = GDK_WINDOW_STATE_WITHDRAWN;
330 window->toplevel_window_type = -1;
332 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
333 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
334 /* Default to unobscured since some backends don't send visibility events */
335 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
338 /* Stop and return on the first non-NULL parent */
340 accumulate_get_window (GSignalInvocationHint *ihint,
342 const GValue *handler_return,
345 g_value_copy (handler_return, return_accu);
346 /* Continue while returning NULL */
347 return g_value_get_object (handler_return) == NULL;
351 create_surface_accumulator (GSignalInvocationHint *ihint,
353 const GValue *handler_return,
356 g_value_copy (handler_return, return_accu);
358 /* Stop on the first non-NULL return value */
359 return g_value_get_boxed (handler_return) == NULL;
362 static GQuark quark_pointer_window = 0;
365 gdk_window_class_init (GdkWindowClass *klass)
367 GObjectClass *object_class = G_OBJECT_CLASS (klass);
369 parent_class = g_type_class_peek_parent (klass);
371 object_class->finalize = gdk_window_finalize;
372 object_class->set_property = gdk_window_set_property;
373 object_class->get_property = gdk_window_get_property;
375 klass->create_surface = _gdk_offscreen_window_create_surface;
377 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
385 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
386 * gdk_window_get_cursor() for details.
390 g_object_class_install_property (object_class,
392 g_param_spec_boxed ("cursor",
399 * GdkWindow::pick-embedded-child:
400 * @window: the window on which the signal is emitted
401 * @x: x coordinate in the window
402 * @y: y coordinate in the window
404 * The ::pick-embedded-child signal is emitted to find an embedded
405 * child at the given position.
407 * Returns: the #GdkWindow of the embedded child at @x, @y, or %NULL
411 signals[PICK_EMBEDDED_CHILD] =
412 g_signal_new (g_intern_static_string ("pick-embedded-child"),
413 G_OBJECT_CLASS_TYPE (object_class),
415 G_STRUCT_OFFSET (GdkWindowClass, pick_embedded_child),
416 accumulate_get_window, NULL,
417 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
424 * GdkWindow::to-embedder:
425 * @window: the offscreen window on which the signal is emitted
426 * @offscreen-x: x coordinate in the offscreen window
427 * @offscreen-y: y coordinate in the offscreen window
428 * @embedder-x: return location for the x coordinate in the embedder window
429 * @embedder-y: return location for the y coordinate in the embedder window
431 * The ::to-embedder signal is emitted to translate coordinates
432 * in an offscreen window to its embedder.
434 * See also #GtkWindow::from-embedder.
438 signals[TO_EMBEDDER] =
439 g_signal_new (g_intern_static_string ("to-embedder"),
440 G_OBJECT_CLASS_TYPE (object_class),
442 G_STRUCT_OFFSET (GdkWindowClass, to_embedder),
444 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
453 * GdkWindow::from-embedder:
454 * @window: the offscreen window on which the signal is emitted
455 * @embedder-x: x coordinate in the embedder window
456 * @embedder-y: y coordinate in the embedder window
457 * @offscreen-x: return location for the x coordinate in the offscreen window
458 * @offscreen-y: return location for the y coordinate in the offscreen window
460 * The ::from-embedder signal is emitted to translate coordinates
461 * in the embedder of an offscreen window to the offscreen window.
463 * See also #GtkWindow::to-embedder.
467 signals[FROM_EMBEDDER] =
468 g_signal_new (g_intern_static_string ("from-embedder"),
469 G_OBJECT_CLASS_TYPE (object_class),
471 G_STRUCT_OFFSET (GdkWindowClass, from_embedder),
473 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
482 * GdkWindow::create-surface:
483 * @window: the offscreen window on which the signal is emitted
484 * @width: the width of the offscreen surface to create
485 * @height: the height of the offscreen surface to create
487 * The ::create-surface signal is emitted when an offscreen window
488 * needs its surface (re)created, which happens either when the the
489 * window is first drawn to, or when the window is being
490 * resized. The first signal handler that returns a non-%NULL
491 * surface will stop any further signal emission, and its surface
494 * Note that it is not possible to access the window's previous
495 * surface from within any callback of this signal. Calling
496 * gdk_offscreen_window_get_surface() will lead to a crash.
498 * Returns: the newly created #cairo_surface_t for the offscreen window
502 signals[CREATE_SURFACE] =
503 g_signal_new (g_intern_static_string ("create-surface"),
504 G_OBJECT_CLASS_TYPE (object_class),
506 G_STRUCT_OFFSET (GdkWindowClass, create_surface),
507 create_surface_accumulator, NULL,
508 _gdk_marshal_BOXED__INT_INT,
509 CAIRO_GOBJECT_TYPE_SURFACE,
516 device_removed_cb (GdkDeviceManager *device_manager,
520 window->devices_inside = g_list_remove (window->devices_inside, device);
521 g_hash_table_remove (window->device_cursor, device);
523 if (window->device_events)
524 g_hash_table_remove (window->device_events, device);
528 gdk_window_finalize (GObject *object)
530 GdkWindow *window = GDK_WINDOW (object);
531 GdkDeviceManager *device_manager;
533 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
534 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
536 if (!GDK_WINDOW_DESTROYED (window))
538 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
540 g_warning ("losing last reference to undestroyed window\n");
541 _gdk_window_destroy (window, FALSE);
544 /* We use TRUE here, to keep us from actually calling
545 * XDestroyWindow() on the window
547 _gdk_window_destroy (window, TRUE);
550 gdk_window_drop_cairo_surface (window);
554 g_object_unref (window->impl);
558 if (window->impl_window != window)
560 g_object_unref (window->impl_window);
561 window->impl_window = NULL;
565 cairo_region_destroy (window->shape);
567 if (window->input_shape)
568 cairo_region_destroy (window->input_shape);
571 gdk_cursor_unref (window->cursor);
573 if (window->device_cursor)
574 g_hash_table_destroy (window->device_cursor);
576 if (window->device_events)
577 g_hash_table_destroy (window->device_events);
579 if (window->source_event_masks)
580 g_hash_table_destroy (window->source_event_masks);
582 if (window->devices_inside)
583 g_list_free (window->devices_inside);
585 G_OBJECT_CLASS (parent_class)->finalize (object);
589 gdk_window_set_property (GObject *object,
594 GdkWindow *window = (GdkWindow *)object;
599 gdk_window_set_cursor (window, g_value_get_boxed (value));
603 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
609 gdk_window_get_property (GObject *object,
614 GdkWindow *window = (GdkWindow *) object;
619 g_value_set_boxed (value, gdk_window_get_cursor (window));
623 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
629 gdk_window_is_offscreen (GdkWindow *window)
631 return window->window_type == GDK_WINDOW_OFFSCREEN;
635 gdk_window_get_impl_window (GdkWindow *window)
637 return window->impl_window;
641 _gdk_window_get_impl_window (GdkWindow *window)
643 return gdk_window_get_impl_window (window);
647 gdk_window_has_impl (GdkWindow *window)
649 return window->impl_window == window;
653 gdk_window_is_toplevel (GdkWindow *window)
656 window->parent == NULL ||
657 window->parent->window_type == GDK_WINDOW_ROOT;
661 _gdk_window_has_impl (GdkWindow *window)
663 return gdk_window_has_impl (window);
667 gdk_window_has_no_impl (GdkWindow *window)
669 return window->impl_window != window;
673 remove_child_area (GdkWindow *private,
676 cairo_region_t *region)
679 cairo_region_t *child_region;
682 cairo_region_t *shape;
684 for (l = private->children; l; l = l->next)
691 /* If region is empty already, no need to do
692 anything potentially costly */
693 if (cairo_region_is_empty (region))
696 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
699 /* Ignore offscreen children, as they don't draw in their parent and
700 * don't take part in the clipping */
701 if (gdk_window_is_offscreen (child))
706 r.width = child->width;
707 r.height = child->height;
709 /* Bail early if child totally outside region */
710 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
713 child_region = cairo_region_create_rectangle (&r);
717 /* Adjust shape region to parent window coords */
718 cairo_region_translate (child->shape, child->x, child->y);
719 cairo_region_intersect (child_region, child->shape);
720 cairo_region_translate (child->shape, -child->x, -child->y);
722 else if (private->window_type == GDK_WINDOW_FOREIGN)
724 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_shape (child);
727 cairo_region_intersect (child_region, shape);
728 cairo_region_destroy (shape);
734 if (child->input_shape)
735 cairo_region_intersect (child_region, child->input_shape);
736 else if (private->window_type == GDK_WINDOW_FOREIGN)
738 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_input_shape (child);
741 cairo_region_intersect (child_region, shape);
742 cairo_region_destroy (shape);
747 cairo_region_subtract (region, child_region);
748 cairo_region_destroy (child_region);
753 static GdkVisibilityState
754 effective_visibility (GdkWindow *window)
756 GdkVisibilityState native;
758 if (!gdk_window_is_viewable (window))
759 return GDK_VISIBILITY_NOT_VIEWABLE;
761 native = window->impl_window->native_visibility;
763 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
764 window->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
765 return GDK_VISIBILITY_FULLY_OBSCURED;
766 else if (native == GDK_VISIBILITY_UNOBSCURED)
767 return window->visibility;
768 else /* native PARTIAL, private partial or unobscured */
769 return GDK_VISIBILITY_PARTIAL;
773 gdk_window_update_visibility (GdkWindow *window)
775 GdkVisibilityState new_visibility;
778 new_visibility = effective_visibility (window);
780 if (new_visibility != window->effective_visibility)
782 window->effective_visibility = new_visibility;
784 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
785 window->event_mask & GDK_VISIBILITY_NOTIFY)
787 event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY,
789 event->visibility.state = new_visibility;
795 gdk_window_update_visibility_recursively (GdkWindow *window,
796 GdkWindow *only_for_impl)
801 gdk_window_update_visibility (window);
802 for (l = window->children; l != NULL; l = l->next)
805 if ((only_for_impl == NULL) ||
806 (only_for_impl == child->impl_window))
807 gdk_window_update_visibility_recursively (child, only_for_impl);
812 should_apply_clip_as_shape (GdkWindow *window)
815 gdk_window_has_impl (window) &&
816 /* Not for offscreens */
817 !gdk_window_is_offscreen (window) &&
818 /* or for toplevels */
819 !gdk_window_is_toplevel (window) &&
820 /* or for foreign windows */
821 window->window_type != GDK_WINDOW_FOREIGN &&
822 /* or for the root window */
823 window->window_type != GDK_WINDOW_ROOT;
827 apply_shape (GdkWindow *window,
828 cairo_region_t *region)
830 GdkWindowImplClass *impl_class;
832 /* We trash whether we applied a shape so that
833 we can avoid unsetting it many times, which
834 could happen in e.g. apply_clip_as_shape as
835 windows get resized */
836 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
838 impl_class->shape_combine_region (window,
840 else if (window->applied_shape)
841 impl_class->shape_combine_region (window,
844 window->applied_shape = region != NULL;
848 region_rect_equal (const cairo_region_t *region,
849 const GdkRectangle *rect)
851 GdkRectangle extents;
853 if (cairo_region_num_rectangles (region) != 1)
856 cairo_region_get_extents (region, &extents);
858 return extents.x == rect->x &&
859 extents.y == rect->y &&
860 extents.width == rect->width &&
861 extents.height == rect->height;
865 apply_clip_as_shape (GdkWindow *window)
870 r.width = window->width;
871 r.height = window->height;
873 /* We only apply the clip region if would differ
874 from the actual clip region implied by the size
875 of the window. This is to avoid unneccessarily
876 adding meaningless shapes to all native subwindows */
877 if (!region_rect_equal (window->clip_region, &r))
878 apply_shape (window, window->clip_region);
880 apply_shape (window, NULL);
884 recompute_visible_regions_internal (GdkWindow *private,
885 gboolean recalculate_clip,
886 gboolean recalculate_siblings,
887 gboolean recalculate_children)
892 cairo_region_t *new_clip, *old_clip_region_with_children;
893 gboolean clip_region_changed;
894 gboolean abs_pos_changed;
895 int old_abs_x, old_abs_y;
897 old_abs_x = private->abs_x;
898 old_abs_y = private->abs_y;
900 /* Update absolute position */
901 if (gdk_window_has_impl (private))
903 /* Native window starts here */
909 private->abs_x = private->parent->abs_x + private->x;
910 private->abs_y = private->parent->abs_y + private->y;
914 private->abs_x != old_abs_x ||
915 private->abs_y != old_abs_y;
917 /* Update clip region based on:
920 * siblings in parents above window
922 clip_region_changed = FALSE;
923 if (recalculate_clip)
925 if (private->viewable)
927 /* Calculate visible region (sans children) in parent window coords */
930 r.width = private->width;
931 r.height = private->height;
932 new_clip = cairo_region_create_rectangle (&r);
934 if (!gdk_window_is_toplevel (private))
936 cairo_region_intersect (new_clip, private->parent->clip_region);
938 /* Remove all overlapping children from parent.
939 * Unless we're all native, because then we don't need to take
940 * siblings into account since X does that clipping for us.
941 * This makes things like SWT that modify the raw X stacking
942 * order without GDKs knowledge work.
944 if (!_gdk_native_windows)
945 remove_child_area (private->parent, private, FALSE, new_clip);
948 /* Convert from parent coords to window coords */
949 cairo_region_translate (new_clip, -private->x, -private->y);
952 cairo_region_intersect (new_clip, private->shape);
955 new_clip = cairo_region_create ();
957 if (private->clip_region == NULL ||
958 !cairo_region_equal (private->clip_region, new_clip))
959 clip_region_changed = TRUE;
961 if (private->clip_region)
962 cairo_region_destroy (private->clip_region);
963 private->clip_region = new_clip;
965 old_clip_region_with_children = private->clip_region_with_children;
966 private->clip_region_with_children = cairo_region_copy (private->clip_region);
967 if (private->window_type != GDK_WINDOW_ROOT)
968 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
970 if (clip_region_changed ||
971 !cairo_region_equal (private->clip_region_with_children, old_clip_region_with_children))
972 private->clip_tag = new_region_tag ();
974 if (old_clip_region_with_children)
975 cairo_region_destroy (old_clip_region_with_children);
978 if (clip_region_changed)
980 GdkVisibilityState visibility;
981 gboolean fully_visible;
983 if (cairo_region_is_empty (private->clip_region))
984 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
989 fully_visible = cairo_region_equal (private->clip_region,
996 r.width = private->width;
997 r.height = private->height;
998 fully_visible = region_rect_equal (private->clip_region, &r);
1002 visibility = GDK_VISIBILITY_UNOBSCURED;
1004 visibility = GDK_VISIBILITY_PARTIAL;
1007 if (private->visibility != visibility)
1009 private->visibility = visibility;
1010 gdk_window_update_visibility (private);
1014 /* Update all children, recursively (except for root, where children are not exact). */
1015 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1016 private->window_type != GDK_WINDOW_ROOT)
1018 for (l = private->children; l; l = l->next)
1021 /* Only recalculate clip if the the clip region changed, otherwise
1022 * there is no way the child clip region could change (its has not e.g. moved)
1023 * Except if recalculate_children is set to force child updates
1025 recompute_visible_regions_internal (child,
1026 recalculate_clip && (clip_region_changed || recalculate_children),
1031 if (clip_region_changed &&
1032 should_apply_clip_as_shape (private))
1033 apply_clip_as_shape (private);
1035 if (recalculate_siblings &&
1036 !gdk_window_is_toplevel (private))
1038 /* If we moved a child window in parent or changed the stacking order, then we
1039 * need to recompute the visible area of all the other children in the parent
1041 for (l = private->parent->children; l; l = l->next)
1045 if (child != private)
1046 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1049 /* We also need to recompute the _with_children clip for the parent */
1050 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1053 if (private->cairo_surface && gdk_window_has_impl (private))
1055 GdkWindowImplClass *iface = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1057 private->cairo_surface = iface->resize_cairo_surface (private,
1058 private->cairo_surface,
1062 else if (private->cairo_surface)
1063 gdk_window_drop_cairo_surface (private);
1066 /* Call this when private has changed in one or more of these ways:
1070 * stacking order of window changed
1073 * It will recalculate abs_x/y and the clip regions
1075 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1076 * for recalculate_siblings. (Mostly used internally for the recursion)
1078 * If a child window was removed (and you can't use that child for
1079 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1082 recompute_visible_regions (GdkWindow *private,
1083 gboolean recalculate_siblings,
1084 gboolean recalculate_children)
1086 recompute_visible_regions_internal (private,
1088 recalculate_siblings,
1089 recalculate_children);
1093 _gdk_window_update_size (GdkWindow *window)
1095 recompute_visible_regions (window, TRUE, FALSE);
1098 /* Find the native window that would be just above "child"
1099 * in the native stacking order if "child" was a native window
1100 * (it doesn't have to be native). If there is no such native
1101 * window inside this native parent then NULL is returned.
1102 * If child is NULL, find lowest native window in parent.
1105 find_native_sibling_above_helper (GdkWindow *parent,
1113 l = g_list_find (parent->children, child);
1114 g_assert (l != NULL); /* Better be a child of its parent... */
1115 l = l->prev; /* Start looking at the one above the child */
1118 l = g_list_last (parent->children);
1120 for (; l != NULL; l = l->prev)
1124 if (gdk_window_has_impl (w))
1127 g_assert (parent != w);
1128 w = find_native_sibling_above_helper (w, NULL);
1138 find_native_sibling_above (GdkWindow *parent,
1143 w = find_native_sibling_above_helper (parent, child);
1147 if (gdk_window_has_impl (parent))
1150 return find_native_sibling_above (parent->parent, parent);
1154 get_native_device_event_mask (GdkWindow *private,
1157 GdkEventMask event_mask;
1160 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1162 event_mask = private->event_mask;
1164 if (_gdk_native_windows ||
1165 private->window_type == GDK_WINDOW_ROOT ||
1166 private->window_type == GDK_WINDOW_FOREIGN)
1172 /* Do whatever the app asks to, since the app
1173 * may be asking for weird things for native windows,
1174 * but don't use motion hints as that may affect non-native
1175 * child windows that don't want it. Also, we need to
1176 * set all the app-specified masks since they will be picked
1177 * up by any implicit grabs (i.e. if they were not set as
1178 * native we would not get the events we need). */
1179 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1181 /* We need thse for all native windows so we can
1182 emulate events on children: */
1185 GDK_VISIBILITY_NOTIFY_MASK |
1186 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1188 /* Additionally we select for pointer and button events
1189 * for toplevels as we need to get these to emulate
1190 * them for non-native subwindows. Even though we don't
1191 * select on them for all native windows we will get them
1192 * as the events are propagated out to the first window
1193 * that select for them.
1194 * Not selecting for button press on all windows is an
1195 * important thing, because in X only one client can do
1196 * so, and we don't want to unexpectedly prevent another
1197 * client from doing it.
1199 * We also need to do the same if the app selects for button presses
1200 * because then we will get implicit grabs for this window, and the
1201 * event mask used for that grab is based on the rest of the mask
1202 * for the window, but we might need more events than this window
1203 * lists due to some non-native child window.
1205 if (gdk_window_is_toplevel (private) ||
1206 mask & GDK_BUTTON_PRESS_MASK)
1208 GDK_POINTER_MOTION_MASK |
1209 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1217 get_native_grab_event_mask (GdkEventMask grab_mask)
1219 /* Similar to the above but for pointer events only */
1221 GDK_POINTER_MOTION_MASK |
1222 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1223 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1226 ~GDK_POINTER_MOTION_HINT_MASK);
1230 get_native_event_mask (GdkWindow *private)
1232 return get_native_device_event_mask (private, NULL);
1235 /* Puts the native window in the right order wrt the other native windows
1236 * in the hierarchy, given the position it has in the client side data.
1237 * This is useful if some operation changed the stacking order.
1238 * This calls assumes the native window is now topmost in its native parent.
1241 sync_native_window_stack_position (GdkWindow *window)
1244 GdkWindowImplClass *impl_class;
1245 GList listhead = {0};
1247 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1249 above = find_native_sibling_above (window->parent, window);
1252 listhead.data = window;
1253 impl_class->restack_under (above, &listhead);
1259 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1260 * the default root window for the default display.
1261 * @attributes: attributes of the new window
1262 * @attributes_mask: mask indicating which fields in @attributes are valid
1264 * Creates a new #GdkWindow using the attributes from
1265 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1266 * more details. Note: to use this on displays other than the default
1267 * display, @parent must be specified.
1269 * Return value: (transfer none): the new #GdkWindow
1272 gdk_window_new (GdkWindow *parent,
1273 GdkWindowAttr *attributes,
1274 gint attributes_mask)
1280 GdkEventMask event_mask;
1281 GdkWindow *real_parent;
1282 GdkDeviceManager *device_manager;
1284 g_return_val_if_fail (attributes != NULL, NULL);
1288 GDK_NOTE (MULTIHEAD,
1289 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1291 screen = gdk_screen_get_default ();
1292 parent = gdk_screen_get_root_window (screen);
1295 screen = gdk_window_get_screen (parent);
1297 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1299 if (GDK_WINDOW_DESTROYED (parent))
1301 g_warning ("gdk_window_new(): parent is destroyed\n");
1305 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1306 _gdk_native_windows)
1308 g_warning ("Offscreen windows not supported with native-windows gdk");
1312 window = g_object_new (GDK_TYPE_WINDOW, NULL);
1314 /* Windows with a foreign parent are treated as if they are children
1315 * of the root window, except for actual creation.
1317 real_parent = parent;
1318 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1319 parent = gdk_screen_get_root_window (screen);
1321 window->parent = parent;
1323 window->accept_focus = TRUE;
1324 window->focus_on_map = TRUE;
1326 if (attributes_mask & GDK_WA_X)
1331 if (attributes_mask & GDK_WA_Y)
1338 window->width = (attributes->width > 1) ? (attributes->width) : (1);
1339 window->height = (attributes->height > 1) ? (attributes->height) : (1);
1341 #ifdef GDK_WINDOWING_X11
1342 /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
1343 * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
1345 if (attributes->wclass == GDK_INPUT_ONLY &&
1346 window->parent->window_type == GDK_WINDOW_ROOT &&
1347 !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
1349 g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
1350 attributes->wclass = GDK_INPUT_OUTPUT;
1354 if (attributes->wclass == GDK_INPUT_ONLY)
1356 /* Backwards compatiblity - we've always ignored
1357 * attributes->window_type for input-only windows
1360 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1361 window->window_type = GDK_WINDOW_TEMP;
1363 window->window_type = GDK_WINDOW_CHILD;
1366 window->window_type = attributes->window_type;
1369 switch (window->window_type)
1371 case GDK_WINDOW_TOPLEVEL:
1372 case GDK_WINDOW_TEMP:
1373 case GDK_WINDOW_OFFSCREEN:
1374 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1375 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1376 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1377 case GDK_WINDOW_CHILD:
1381 g_warning (G_STRLOC "cannot make windows of type %d", window->window_type);
1385 if (attributes_mask & GDK_WA_VISUAL)
1386 window->visual = attributes->visual;
1388 window->visual = gdk_screen_get_system_visual (screen);
1390 window->event_mask = attributes->event_mask;
1392 if (attributes->wclass == GDK_INPUT_OUTPUT)
1394 window->input_only = FALSE;
1395 window->depth = window->visual->depth;
1397 /* XXX: Cache this somehow? */
1398 window->background = cairo_pattern_create_rgb (0, 0, 0);
1403 window->input_only = TRUE;
1407 window->parent->children = g_list_prepend (window->parent->children, window);
1409 window->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
1410 (GDestroyNotify) gdk_cursor_unref);
1412 native = _gdk_native_windows; /* Default */
1413 if (window->parent->window_type == GDK_WINDOW_ROOT)
1414 native = TRUE; /* Always use native windows for toplevels */
1415 else if (!window->input_only &&
1416 (attributes_mask & GDK_WA_VISUAL &&
1417 attributes->visual != gdk_window_get_visual (window->parent)))
1418 native = TRUE; /* InputOutput window with different visual than parent, needs native window */
1420 if (gdk_window_is_offscreen (window))
1422 _gdk_offscreen_window_new (window, attributes, attributes_mask);
1423 window->impl_window = window;
1427 event_mask = get_native_event_mask (window);
1429 /* Create the impl */
1430 _gdk_window_impl_new (window, real_parent, screen, event_mask, attributes, attributes_mask);
1431 window->impl_window = window;
1433 /* This will put the native window topmost in the native parent, which may
1434 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1435 if (!_gdk_window_has_impl (real_parent))
1436 sync_native_window_stack_position (window);
1440 window->impl_window = g_object_ref (window->parent->impl_window);
1441 window->impl = g_object_ref (window->impl_window->impl);
1444 recompute_visible_regions (window, TRUE, FALSE);
1446 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1447 (attributes->cursor) :
1450 device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent));
1451 g_signal_connect (device_manager, "device-removed",
1452 G_CALLBACK (device_removed_cb), window);
1458 is_parent_of (GdkWindow *parent,
1469 w = gdk_window_get_parent (w);
1476 change_impl (GdkWindow *private,
1477 GdkWindow *impl_window,
1482 GdkWindowImpl *old_impl;
1483 GdkWindow *old_impl_window;
1485 old_impl = private->impl;
1486 old_impl_window = private->impl_window;
1487 if (private != impl_window)
1488 private->impl_window = g_object_ref (impl_window);
1490 private->impl_window = private;
1491 private->impl = g_object_ref (new);
1492 if (old_impl_window != private)
1493 g_object_unref (old_impl_window);
1494 g_object_unref (old_impl);
1496 for (l = private->children; l != NULL; l = l->next)
1500 if (child->impl == old_impl)
1501 change_impl (child, impl_window, new);
1506 reparent_to_impl (GdkWindow *private)
1511 GdkWindowImplClass *impl_class;
1513 impl_class = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1515 /* Enumerate in reverse order so we get the right order for the native
1516 windows (first in childrens list is topmost, and reparent places on top) */
1517 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1521 if (child->impl == private->impl)
1522 reparent_to_impl (child);
1525 show = impl_class->reparent ((GdkWindow *)child,
1526 (GdkWindow *)private,
1527 child->x, child->y);
1529 gdk_window_show_unraised ((GdkWindow *)child);
1536 * gdk_window_reparent:
1537 * @window: a #GdkWindow
1538 * @new_parent: new parent to move @window into
1539 * @x: X location inside the new parent
1540 * @y: Y location inside the new parent
1542 * Reparents @window into the given @new_parent. The window being
1543 * reparented will be unmapped as a side effect.
1547 gdk_window_reparent (GdkWindow *window,
1548 GdkWindow *new_parent,
1552 GdkWindow *old_parent;
1554 gboolean show, was_mapped, applied_clip_as_shape;
1555 gboolean do_reparent_to_impl;
1556 GdkEventMask old_native_event_mask;
1557 GdkWindowImplClass *impl_class;
1559 g_return_if_fail (GDK_IS_WINDOW (window));
1560 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1561 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1563 if (GDK_WINDOW_DESTROYED (window) ||
1564 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1567 screen = gdk_window_get_screen (window);
1569 new_parent = gdk_screen_get_root_window (screen);
1571 /* No input-output children of input-only windows */
1572 if (new_parent->input_only && !window->input_only)
1575 /* Don't create loops in hierarchy */
1576 if (is_parent_of (window, new_parent))
1579 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1580 To make sure we're ok, just wipe it. */
1581 gdk_window_drop_cairo_surface (window);
1583 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1584 old_parent = window->parent;
1586 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1589 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1590 if (new_parent->window_type == GDK_WINDOW_ROOT ||
1591 new_parent->window_type == GDK_WINDOW_FOREIGN)
1592 gdk_window_ensure_native (window);
1594 applied_clip_as_shape = should_apply_clip_as_shape (window);
1596 old_native_event_mask = 0;
1597 do_reparent_to_impl = FALSE;
1598 if (gdk_window_has_impl (window))
1600 old_native_event_mask = get_native_event_mask (window);
1602 show = impl_class->reparent (window, new_parent, x, y);
1606 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1607 g_assert (new_parent->window_type != GDK_WINDOW_ROOT &&
1608 new_parent->window_type != GDK_WINDOW_FOREIGN);
1611 gdk_window_hide (window);
1613 do_reparent_to_impl = TRUE;
1614 change_impl (window,
1615 new_parent->impl_window,
1619 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1622 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1624 new_parent = gdk_screen_get_root_window (screen);
1628 old_parent->children = g_list_remove (old_parent->children, window);
1630 window->parent = new_parent;
1634 new_parent->children = g_list_prepend (new_parent->children, window);
1636 /* Switch the window type as appropriate */
1638 switch (GDK_WINDOW_TYPE (new_parent))
1640 case GDK_WINDOW_ROOT:
1641 case GDK_WINDOW_FOREIGN:
1642 if (window->toplevel_window_type != -1)
1643 GDK_WINDOW_TYPE (window) = window->toplevel_window_type;
1644 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1645 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1647 case GDK_WINDOW_OFFSCREEN:
1648 case GDK_WINDOW_TOPLEVEL:
1649 case GDK_WINDOW_CHILD:
1650 case GDK_WINDOW_TEMP:
1651 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1652 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1654 /* Save the original window type so we can restore it if the
1655 * window is reparented back to be a toplevel
1657 window->toplevel_window_type = GDK_WINDOW_TYPE (window);
1658 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1662 /* We might have changed window type for a native windows, so we
1663 need to change the event mask too. */
1664 if (gdk_window_has_impl (window))
1666 GdkEventMask native_event_mask = get_native_event_mask (window);
1668 if (native_event_mask != old_native_event_mask)
1669 impl_class->set_events (window, native_event_mask);
1672 _gdk_window_update_viewable (window);
1674 recompute_visible_regions (window, TRUE, FALSE);
1675 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1676 recompute_visible_regions (old_parent, FALSE, TRUE);
1678 /* We used to apply the clip as the shape, but no more.
1679 Reset this to the real shape */
1680 if (gdk_window_has_impl (window) &&
1681 applied_clip_as_shape &&
1682 !should_apply_clip_as_shape (window))
1683 apply_shape (window, window->shape);
1685 if (do_reparent_to_impl)
1686 reparent_to_impl (window);
1689 /* The reparent will have put the native window topmost in the native parent,
1690 * which may be wrong wrt other native windows in the non-native hierarchy,
1692 if (!gdk_window_has_impl (new_parent))
1693 sync_native_window_stack_position (window);
1697 gdk_window_show_unraised (window);
1699 _gdk_synthesize_crossing_events_for_geometry_change (window);
1703 * gdk_window_ensure_native:
1704 * @window: a #GdkWindow
1706 * Tries to ensure that there is a window-system native window for this
1707 * GdkWindow. This may fail in some situations, returning %FALSE.
1709 * Offscreen window and children of them can never have native windows.
1711 * Some backends may not support native child windows.
1713 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1718 gdk_window_ensure_native (GdkWindow *window)
1720 GdkWindow *impl_window;
1721 GdkWindowImpl *new_impl, *old_impl;
1725 GdkWindowImplClass *impl_class;
1727 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1729 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1730 GDK_WINDOW_DESTROYED (window))
1733 impl_window = gdk_window_get_impl_window (window);
1735 if (gdk_window_is_offscreen (impl_window))
1736 return FALSE; /* native in offscreens not supported */
1738 if (impl_window == window)
1739 /* Already has an impl, and its not offscreen . */
1742 /* Need to create a native window */
1744 gdk_window_drop_cairo_surface (window);
1746 screen = gdk_window_get_screen (window);
1748 old_impl = window->impl;
1749 _gdk_window_impl_new (window, window->parent,
1751 get_native_event_mask (window),
1753 new_impl = window->impl;
1755 window->impl = old_impl;
1756 change_impl (window, window, new_impl);
1758 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1760 /* Native window creation will put the native window topmost in the
1761 * native parent, which may be wrong wrt the position of the previous
1762 * non-native window wrt to the other non-native children, so correct this.
1764 above = find_native_sibling_above (window->parent, window);
1767 listhead.data = window;
1768 listhead.prev = NULL;
1769 listhead.next = NULL;
1770 impl_class->restack_under ((GdkWindow *)above, &listhead);
1773 recompute_visible_regions (window, FALSE, FALSE);
1775 /* The shape may not have been set, as the clip region doesn't actually
1776 change, so do it here manually */
1777 if (should_apply_clip_as_shape (window))
1778 apply_clip_as_shape (window);
1780 reparent_to_impl (window);
1782 if (!window->input_only)
1784 impl_class->set_background (window, window->background);
1787 impl_class->input_shape_combine_region (window,
1788 window->input_shape,
1791 if (gdk_window_is_viewable (window))
1792 impl_class->show (window, FALSE);
1798 * _gdk_event_filter_unref:
1799 * @window: A #GdkWindow, or %NULL to be the global window
1800 * @filter: A window filter
1802 * Release a reference to @filter. Note this function may
1803 * mutate the list storage, so you need to handle this
1804 * if iterating over a list of filters.
1807 _gdk_event_filter_unref (GdkWindow *window,
1808 GdkEventFilter *filter)
1814 filters = &_gdk_default_filters;
1816 filters = &window->filters;
1818 for (tmp_list = *filters; tmp_list; tmp_list = tmp_list->next)
1820 GdkEventFilter *iter_filter = tmp_list->data;
1823 if (iter_filter != filter)
1826 g_assert (iter_filter->ref_count > 0);
1828 filter->ref_count--;
1829 if (filter->ref_count != 0)
1833 tmp_list = tmp_list->next;
1835 *filters = g_list_remove_link (*filters, node);
1837 g_list_free_1 (node);
1842 window_remove_filters (GdkWindow *window)
1844 while (window->filters)
1845 _gdk_event_filter_unref (window, window->filters->data);
1849 update_pointer_info_foreach (GdkDisplay *display,
1851 GdkPointerWindowInfo *pointer_info,
1854 GdkWindow *window = user_data;
1856 if (pointer_info->toplevel_under_pointer == window)
1858 g_object_unref (pointer_info->toplevel_under_pointer);
1859 pointer_info->toplevel_under_pointer = NULL;
1864 window_remove_from_pointer_info (GdkWindow *window,
1865 GdkDisplay *display)
1867 _gdk_display_pointer_info_foreach (display,
1868 update_pointer_info_foreach,
1873 * _gdk_window_destroy_hierarchy:
1874 * @window: a #GdkWindow
1875 * @recursing: If TRUE, then this is being called because a parent
1877 * @recursing_native: If TRUE, then this is being called because a native parent
1878 * was destroyed. This generally means that the call to the
1879 * windowing system to destroy the window can be omitted, since
1880 * it will be destroyed as a result of the parent being destroyed.
1881 * Unless @foreign_destroy.
1882 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1883 * external agency. The window has already been destroyed and no
1884 * windowing system calls should be made. (This may never happen
1885 * for some windowing systems.)
1887 * Internal function to destroy a window. Like gdk_window_destroy(),
1888 * but does not drop the reference count created by gdk_window_new().
1891 _gdk_window_destroy_hierarchy (GdkWindow *window,
1893 gboolean recursing_native,
1894 gboolean foreign_destroy)
1896 GdkWindowImplClass *impl_class;
1897 GdkWindow *temp_window;
1899 GdkDisplay *display;
1903 g_return_if_fail (GDK_IS_WINDOW (window));
1905 if (GDK_WINDOW_DESTROYED (window))
1908 display = gdk_window_get_display (window);
1909 screen = gdk_window_get_screen (window);
1910 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1911 if (temp_window == window)
1912 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1915 switch (window->window_type)
1917 case GDK_WINDOW_ROOT:
1918 if (!screen->closed)
1920 g_error ("attempted to destroy root window");
1923 /* else fall thru */
1924 case GDK_WINDOW_TOPLEVEL:
1925 case GDK_WINDOW_CHILD:
1926 case GDK_WINDOW_TEMP:
1927 case GDK_WINDOW_FOREIGN:
1928 case GDK_WINDOW_OFFSCREEN:
1929 if (window->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
1931 /* Logically, it probably makes more sense to send
1932 * a "destroy yourself" message to the foreign window
1933 * whether or not it's in our hierarchy; but for historical
1934 * reasons, we only send "destroy yourself" messages to
1935 * foreign windows in our hierarchy.
1938 _gdk_windowing_window_destroy_foreign (window);
1940 /* Also for historical reasons, we remove any filters
1941 * on a foreign window when it or a parent is destroyed;
1942 * this likely causes problems if two separate portions
1943 * of code are maintaining filter lists on a foreign window.
1945 window_remove_filters (window);
1951 if (window->parent->children)
1952 window->parent->children = g_list_remove (window->parent->children, window);
1955 GDK_WINDOW_IS_MAPPED (window))
1957 recompute_visible_regions (window, TRUE, FALSE);
1958 gdk_window_invalidate_in_parent (window);
1962 gdk_window_free_paint_stack (window);
1964 if (window->background)
1966 cairo_pattern_destroy (window->background);
1967 window->background = NULL;
1970 if (window->window_type == GDK_WINDOW_FOREIGN)
1971 g_assert (window->children == NULL);
1974 children = tmp = window->children;
1975 window->children = NULL;
1979 temp_window = tmp->data;
1983 _gdk_window_destroy_hierarchy (temp_window,
1985 recursing_native || gdk_window_has_impl (window),
1989 g_list_free (children);
1992 _gdk_window_clear_update_area (window);
1994 gdk_window_drop_cairo_surface (window);
1996 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1998 if (gdk_window_has_impl (window))
1999 impl_class->destroy (window, recursing_native,
2003 /* hide to make sure we repaint and break grabs */
2004 gdk_window_hide (window);
2007 window->state |= GDK_WINDOW_STATE_WITHDRAWN;
2008 window->parent = NULL;
2009 window->destroyed = TRUE;
2011 window_remove_filters (window);
2013 window_remove_from_pointer_info (window, display);
2015 if (window->clip_region)
2017 cairo_region_destroy (window->clip_region);
2018 window->clip_region = NULL;
2021 if (window->clip_region_with_children)
2023 cairo_region_destroy (window->clip_region_with_children);
2024 window->clip_region_with_children = NULL;
2027 if (window->outstanding_moves)
2029 g_list_foreach (window->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2030 g_list_free (window->outstanding_moves);
2031 window->outstanding_moves = NULL;
2039 * _gdk_window_destroy:
2040 * @window: a #GdkWindow
2041 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2042 * external agency. The window has already been destroyed and no
2043 * windowing system calls should be made. (This may never happen
2044 * for some windowing systems.)
2046 * Internal function to destroy a window. Like gdk_window_destroy(),
2047 * but does not drop the reference count created by gdk_window_new().
2050 _gdk_window_destroy (GdkWindow *window,
2051 gboolean foreign_destroy)
2053 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2057 * gdk_window_destroy:
2058 * @window: a #GdkWindow
2060 * Destroys the window system resources associated with @window and decrements @window's
2061 * reference count. The window system resources for all children of @window are also
2062 * destroyed, but the children's reference counts are not decremented.
2064 * Note that a window will not be destroyed automatically when its reference count
2065 * reaches zero. You must call this function yourself before that happens.
2069 gdk_window_destroy (GdkWindow *window)
2071 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2072 g_object_unref (window);
2076 * gdk_window_set_user_data:
2077 * @window: a #GdkWindow
2078 * @user_data: user data
2080 * For most purposes this function is deprecated in favor of
2081 * g_object_set_data(). However, for historical reasons GTK+ stores
2082 * the #GtkWidget that owns a #GdkWindow as user data on the
2083 * #GdkWindow. So, custom widget implementations should use
2084 * this function for that. If GTK+ receives an event for a #GdkWindow,
2085 * and the user data for the window is non-%NULL, GTK+ will assume the
2086 * user data is a #GtkWidget, and forward the event to that widget.
2090 gdk_window_set_user_data (GdkWindow *window,
2093 g_return_if_fail (GDK_IS_WINDOW (window));
2095 window->user_data = user_data;
2099 * gdk_window_get_user_data:
2100 * @window: a #GdkWindow
2101 * @data: return location for user data
2103 * Retrieves the user data for @window, which is normally the widget
2104 * that @window belongs to. See gdk_window_set_user_data().
2108 gdk_window_get_user_data (GdkWindow *window,
2111 g_return_if_fail (GDK_IS_WINDOW (window));
2113 *data = window->user_data;
2117 * gdk_window_get_window_type:
2118 * @window: a #GdkWindow
2120 * Gets the type of the window. See #GdkWindowType.
2122 * Return value: type of window
2125 gdk_window_get_window_type (GdkWindow *window)
2127 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2129 return GDK_WINDOW_TYPE (window);
2133 * gdk_window_get_visual:
2134 * @window: a #GdkWindow
2136 * Gets the #GdkVisual describing the pixel format of @window.
2138 * Return value: (transfer none): a #GdkVisual
2143 gdk_window_get_visual (GdkWindow *window)
2145 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2147 return window->visual;
2151 * gdk_window_get_screen:
2152 * @window: a #GdkWindow
2154 * Gets the #GdkScreen associated with a #GdkWindow.
2156 * Return value: (transfer none): the #GdkScreen associated with @window
2161 gdk_window_get_screen (GdkWindow *window)
2163 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2165 return gdk_visual_get_screen (window->visual);
2169 * gdk_window_get_display:
2170 * @window: a #GdkWindow
2172 * Gets the #GdkDisplay associated with a #GdkWindow.
2174 * Return value: (transfer none): the #GdkDisplay associated with @window
2179 gdk_window_get_display (GdkWindow *window)
2181 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2183 return gdk_screen_get_display (gdk_visual_get_screen (window->visual));
2186 * gdk_window_is_destroyed:
2187 * @window: a #GdkWindow
2189 * Check to see if a window is destroyed..
2191 * Return value: %TRUE if the window is destroyed
2196 gdk_window_is_destroyed (GdkWindow *window)
2198 return GDK_WINDOW_DESTROYED (window);
2202 to_embedder (GdkWindow *window,
2203 gdouble offscreen_x,
2204 gdouble offscreen_y,
2205 gdouble *embedder_x,
2206 gdouble *embedder_y)
2208 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2209 offscreen_x, offscreen_y,
2210 embedder_x, embedder_y);
2214 from_embedder (GdkWindow *window,
2217 gdouble *offscreen_x,
2218 gdouble *offscreen_y)
2220 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2221 embedder_x, embedder_y,
2222 offscreen_x, offscreen_y);
2226 * gdk_window_has_native:
2227 * @window: a #GdkWindow
2229 * Checks whether the window has a native window or not. Note that
2230 * you can use gdk_window_ensure_native() if a native window is needed.
2232 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2237 gdk_window_has_native (GdkWindow *window)
2239 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2241 return window->parent == NULL || window->parent->impl != window->impl;
2245 * gdk_window_get_position:
2246 * @window: a #GdkWindow
2247 * @x: (out) (allow-none): X coordinate of window
2248 * @y: (out) (allow-none): Y coordinate of window
2250 * Obtains the position of the window as reported in the
2251 * most-recently-processed #GdkEventConfigure. Contrast with
2252 * gdk_window_get_geometry() which queries the X server for the
2253 * current window position, regardless of which events have been
2254 * received or processed.
2256 * The position coordinates are relative to the window's parent window.
2260 gdk_window_get_position (GdkWindow *window,
2264 g_return_if_fail (GDK_IS_WINDOW (window));
2273 * gdk_window_get_parent:
2274 * @window: a #GdkWindow
2276 * Obtains the parent of @window, as known to GDK. Does not query the
2277 * X server; thus this returns the parent as passed to gdk_window_new(),
2278 * not the actual parent. This should never matter unless you're using
2279 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2280 * matter for toplevel windows, because the window manager may choose
2283 * Note that you should use gdk_window_get_effective_parent() when
2284 * writing generic code that walks up a window hierarchy, because
2285 * gdk_window_get_parent() will most likely not do what you expect if
2286 * there are offscreen windows in the hierarchy.
2288 * Return value: (transfer none): parent of @window
2291 gdk_window_get_parent (GdkWindow *window)
2293 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2295 return window->parent;
2299 * gdk_window_get_effective_parent:
2300 * @window: a #GdkWindow
2302 * Obtains the parent of @window, as known to GDK. Works like
2303 * gdk_window_get_parent() for normal windows, but returns the
2304 * window's embedder for offscreen windows.
2306 * See also: gdk_offscreen_window_get_embedder()
2308 * Return value: (transfer none): effective parent of @window
2313 gdk_window_get_effective_parent (GdkWindow *window)
2315 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2317 if (gdk_window_is_offscreen (window))
2318 return gdk_offscreen_window_get_embedder (window);
2320 return window->parent;
2324 * gdk_window_get_toplevel:
2325 * @window: a #GdkWindow
2327 * Gets the toplevel window that's an ancestor of @window.
2329 * Any window type but %GDK_WINDOW_CHILD is considered a
2330 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2331 * has a root window as parent.
2333 * Note that you should use gdk_window_get_effective_toplevel() when
2334 * you want to get to a window's toplevel as seen on screen, because
2335 * gdk_window_get_toplevel() will most likely not do what you expect
2336 * if there are offscreen windows in the hierarchy.
2338 * Return value: (transfer none): the toplevel window containing @window
2341 gdk_window_get_toplevel (GdkWindow *window)
2343 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2345 while (window->window_type == GDK_WINDOW_CHILD)
2347 if (gdk_window_is_toplevel (window))
2349 window = window->parent;
2356 * gdk_window_get_effective_toplevel:
2357 * @window: a #GdkWindow
2359 * Gets the toplevel window that's an ancestor of @window.
2361 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2362 * embedder as its parent, using gdk_window_get_effective_parent().
2364 * See also: gdk_offscreen_window_get_embedder()
2366 * Return value: (transfer none): the effective toplevel window containing @window
2371 gdk_window_get_effective_toplevel (GdkWindow *window)
2375 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2377 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2378 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2385 * gdk_window_get_children:
2386 * @window: a #GdkWindow
2388 * Gets the list of children of @window known to GDK.
2389 * This function only returns children created via GDK,
2390 * so for example it's useless when used with the root window;
2391 * it only returns windows an application created itself.
2393 * The returned list must be freed, but the elements in the
2396 * Return value: (transfer container) (element-type GdkWindow):
2397 * list of child windows inside @window
2400 gdk_window_get_children (GdkWindow *window)
2402 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2404 if (GDK_WINDOW_DESTROYED (window))
2407 return g_list_copy (window->children);
2411 * gdk_window_peek_children:
2412 * @window: a #GdkWindow
2414 * Like gdk_window_get_children(), but does not copy the list of
2415 * children, so the list does not need to be freed.
2417 * Return value: (transfer none) (element-type GdkWindow):
2418 * a reference to the list of child windows in @window
2421 gdk_window_peek_children (GdkWindow *window)
2423 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2425 if (GDK_WINDOW_DESTROYED (window))
2428 return window->children;
2432 * gdk_window_add_filter:
2433 * @window: a #GdkWindow
2434 * @function: filter callback
2435 * @data: data to pass to filter callback
2437 * Adds an event filter to @window, allowing you to intercept events
2438 * before they reach GDK. This is a low-level operation and makes it
2439 * easy to break GDK and/or GTK+, so you have to know what you're
2440 * doing. Pass %NULL for @window to get all events for all windows,
2441 * instead of events for a specific window.
2443 * See gdk_display_add_client_message_filter() if you are interested
2444 * in X ClientMessage events.
2447 gdk_window_add_filter (GdkWindow *window,
2448 GdkFilterFunc function,
2452 GdkEventFilter *filter;
2454 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2456 if (window && GDK_WINDOW_DESTROYED (window))
2459 /* Filters are for the native events on the native window, so
2460 ensure there is a native window. */
2462 gdk_window_ensure_native (window);
2465 tmp_list = window->filters;
2467 tmp_list = _gdk_default_filters;
2471 filter = (GdkEventFilter *)tmp_list->data;
2472 if ((filter->function == function) && (filter->data == data))
2474 filter->ref_count++;
2477 tmp_list = tmp_list->next;
2480 filter = g_new (GdkEventFilter, 1);
2481 filter->function = function;
2482 filter->data = data;
2483 filter->ref_count = 1;
2487 window->filters = g_list_append (window->filters, filter);
2489 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2493 * gdk_window_remove_filter:
2494 * @window: a #GdkWindow
2495 * @function: previously-added filter function
2496 * @data: user data for previously-added filter function
2498 * Remove a filter previously added with gdk_window_add_filter().
2502 gdk_window_remove_filter (GdkWindow *window,
2503 GdkFilterFunc function,
2506 GList *tmp_list, *node;
2507 GdkEventFilter *filter;
2509 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2512 tmp_list = window->filters;
2514 tmp_list = _gdk_default_filters;
2518 filter = (GdkEventFilter *)tmp_list->data;
2520 tmp_list = tmp_list->next;
2522 if ((filter->function == function) && (filter->data == data))
2524 filter->flags |= GDK_EVENT_FILTER_REMOVED;
2526 _gdk_event_filter_unref (window, filter);
2534 * gdk_screen_get_toplevel_windows:
2535 * @screen: The #GdkScreen where the toplevels are located.
2537 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2538 * A toplevel window is a child of the root window (see
2539 * gdk_get_default_root_window()).
2541 * The returned list should be freed with g_list_free(), but
2542 * its elements need not be freed.
2544 * Return value: (transfer container) (element-type GdkWindow):
2545 * list of toplevel windows, free with g_list_free()
2550 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2552 GdkWindow * root_window;
2553 GList *new_list = NULL;
2556 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2558 root_window = gdk_screen_get_root_window (screen);
2560 tmp_list = root_window->children;
2563 GdkWindow *w = tmp_list->data;
2565 if (w->window_type != GDK_WINDOW_FOREIGN)
2566 new_list = g_list_prepend (new_list, w);
2567 tmp_list = tmp_list->next;
2574 * gdk_window_is_visible:
2575 * @window: a #GdkWindow
2577 * Checks whether the window has been mapped (with gdk_window_show() or
2578 * gdk_window_show_unraised()).
2580 * Return value: %TRUE if the window is mapped
2583 gdk_window_is_visible (GdkWindow *window)
2585 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2587 return GDK_WINDOW_IS_MAPPED (window);
2591 * gdk_window_is_viewable:
2592 * @window: a #GdkWindow
2594 * Check if the window and all ancestors of the window are
2595 * mapped. (This is not necessarily "viewable" in the X sense, since
2596 * we only check as far as we have GDK window parents, not to the root
2599 * Return value: %TRUE if the window is viewable
2602 gdk_window_is_viewable (GdkWindow *window)
2604 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2606 if (window->destroyed)
2609 return window->viewable;
2613 * gdk_window_get_state:
2614 * @window: a #GdkWindow
2616 * Gets the bitwise OR of the currently active window state flags,
2617 * from the #GdkWindowState enumeration.
2619 * Return value: window state bitfield
2622 gdk_window_get_state (GdkWindow *window)
2624 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2626 return window->state;
2629 static cairo_content_t
2630 gdk_window_get_content (GdkWindow *window)
2632 cairo_surface_t *surface;
2633 cairo_content_t content;
2635 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2637 surface = _gdk_window_ref_cairo_surface (window);
2638 content = cairo_surface_get_content (surface);
2639 cairo_surface_destroy (surface);
2644 /* This creates an empty "implicit" paint region for the impl window.
2645 * By itself this does nothing, but real paints to this window
2646 * or children of it can use this surface as backing to avoid allocating
2647 * multiple surfaces for subwindow rendering. When doing so they
2648 * add to the region of the implicit paint region, which will be
2649 * pushed to the window when the implicit paint region is ended.
2650 * Such paints should not copy anything to the window on paint end, but
2651 * should rely on the implicit paint end.
2652 * The implicit paint will be automatically ended if someone draws
2653 * directly to the window or a child window.
2656 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2658 GdkWindowPaint *paint;
2660 g_assert (gdk_window_has_impl (window));
2662 if (_gdk_native_windows)
2663 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2665 if (GDK_IS_PAINTABLE (window->impl))
2666 return FALSE; /* Implementation does double buffering */
2668 if (window->paint_stack != NULL ||
2669 window->implicit_paint != NULL)
2670 return FALSE; /* Don't stack implicit paints */
2672 /* Never do implicit paints for foreign windows, they don't need
2673 * double buffer combination since they have no client side children,
2674 * and creating surfaces for them is risky since they could disappear
2677 if (window->window_type == GDK_WINDOW_FOREIGN)
2680 paint = g_new (GdkWindowPaint, 1);
2681 paint->region = cairo_region_create (); /* Empty */
2682 paint->uses_implicit = FALSE;
2683 paint->flushed = FALSE;
2684 paint->surface = gdk_window_create_similar_surface (window,
2685 gdk_window_get_content (window),
2686 MAX (rect->width, 1),
2687 MAX (rect->height, 1));
2688 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2690 window->implicit_paint = paint;
2695 static cairo_surface_t *
2696 gdk_window_ref_impl_surface (GdkWindow *window)
2698 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->ref_cairo_surface (window);
2702 gdk_cairo_create_for_impl (GdkWindow *window)
2704 cairo_surface_t *surface;
2707 surface = gdk_window_ref_impl_surface (window);
2708 cr = cairo_create (surface);
2710 cairo_surface_destroy (surface);
2715 /* Ensure that all content related to this (sub)window is pushed to the
2716 native region. If there is an active paint then that area is not
2717 pushed, in order to not show partially finished double buffers. */
2719 gdk_window_flush_implicit_paint (GdkWindow *window)
2721 GdkWindow *impl_window;
2722 GdkWindowPaint *paint;
2723 cairo_region_t *region;
2726 impl_window = gdk_window_get_impl_window (window);
2727 if (impl_window->implicit_paint == NULL)
2730 paint = impl_window->implicit_paint;
2731 paint->flushed = TRUE;
2732 region = cairo_region_copy (window->clip_region_with_children);
2734 /* Don't flush active double buffers, as that may show partially done
2736 for (list = window->paint_stack; list != NULL; list = list->next)
2738 GdkWindowPaint *tmp_paint = list->data;
2740 cairo_region_subtract (region, tmp_paint->region);
2743 cairo_region_translate (region, -window->abs_x, -window->abs_y);
2744 cairo_region_intersect (region, paint->region);
2746 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2750 /* Remove flushed region from the implicit paint */
2751 cairo_region_subtract (paint->region, region);
2753 /* Some regions are valid, push these to window now */
2754 cr = gdk_cairo_create_for_impl (window);
2755 gdk_cairo_region (cr, region);
2757 cairo_set_source_surface (cr, paint->surface, 0, 0);
2758 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2763 cairo_region_destroy (region);
2766 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2768 gdk_window_end_implicit_paint (GdkWindow *window)
2770 GdkWindowPaint *paint;
2772 g_assert (gdk_window_has_impl (window));
2774 g_assert (window->implicit_paint != NULL);
2776 paint = window->implicit_paint;
2778 window->implicit_paint = NULL;
2780 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2784 /* Some regions are valid, push these to window now */
2785 cr = gdk_cairo_create_for_impl (window);
2786 gdk_cairo_region (cr, paint->region);
2788 cairo_set_source_surface (cr, paint->surface, 0, 0);
2789 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2794 cairo_region_destroy (paint->region);
2796 cairo_surface_destroy (paint->surface);
2801 * gdk_window_begin_paint_rect:
2802 * @window: a #GdkWindow
2803 * @rectangle: rectangle you intend to draw to
2805 * A convenience wrapper around gdk_window_begin_paint_region() which
2806 * creates a rectangular region for you. See
2807 * gdk_window_begin_paint_region() for details.
2811 gdk_window_begin_paint_rect (GdkWindow *window,
2812 const GdkRectangle *rectangle)
2814 cairo_region_t *region;
2816 g_return_if_fail (GDK_IS_WINDOW (window));
2818 region = cairo_region_create_rectangle (rectangle);
2819 gdk_window_begin_paint_region (window, region);
2820 cairo_region_destroy (region);
2824 * gdk_window_begin_paint_region:
2825 * @window: a #GdkWindow
2826 * @region: region you intend to draw to
2828 * Indicates that you are beginning the process of redrawing @region.
2829 * A backing store (offscreen buffer) large enough to contain @region
2830 * will be created. The backing store will be initialized with the
2831 * background color or background surface for @window. Then, all
2832 * drawing operations performed on @window will be diverted to the
2833 * backing store. When you call gdk_window_end_paint(), the backing
2834 * store will be copied to @window, making it visible onscreen. Only
2835 * the part of @window contained in @region will be modified; that is,
2836 * drawing operations are clipped to @region.
2838 * The net result of all this is to remove flicker, because the user
2839 * sees the finished product appear all at once when you call
2840 * gdk_window_end_paint(). If you draw to @window directly without
2841 * calling gdk_window_begin_paint_region(), the user may see flicker
2842 * as individual drawing operations are performed in sequence. The
2843 * clipping and background-initializing features of
2844 * gdk_window_begin_paint_region() are conveniences for the
2845 * programmer, so you can avoid doing that work yourself.
2847 * When using GTK+, the widget system automatically places calls to
2848 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2849 * emissions of the expose_event signal. That is, if you're writing an
2850 * expose event handler, you can assume that the exposed area in
2851 * #GdkEventExpose has already been cleared to the window background,
2852 * is already set as the clip region, and already has a backing store.
2853 * Therefore in most cases, application code need not call
2854 * gdk_window_begin_paint_region(). (You can disable the automatic
2855 * calls around expose events on a widget-by-widget basis by calling
2856 * gtk_widget_set_double_buffered().)
2858 * If you call this function multiple times before calling the
2859 * matching gdk_window_end_paint(), the backing stores are pushed onto
2860 * a stack. gdk_window_end_paint() copies the topmost backing store
2861 * onscreen, subtracts the topmost region from all other regions in
2862 * the stack, and pops the stack. All drawing operations affect only
2863 * the topmost backing store in the stack. One matching call to
2864 * gdk_window_end_paint() is required for each call to
2865 * gdk_window_begin_paint_region().
2869 gdk_window_begin_paint_region (GdkWindow *window,
2870 const cairo_region_t *region)
2872 #ifdef USE_BACKING_STORE
2873 GdkRectangle clip_box;
2874 GdkWindowPaint *paint, *implicit_paint;
2875 GdkWindow *impl_window;
2878 g_return_if_fail (GDK_IS_WINDOW (window));
2880 if (GDK_WINDOW_DESTROYED (window))
2883 if (GDK_IS_PAINTABLE (window->impl))
2885 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
2887 if (iface->begin_paint_region)
2888 iface->begin_paint_region ((GdkPaintable*)window->impl, window, region);
2893 impl_window = gdk_window_get_impl_window (window);
2894 implicit_paint = impl_window->implicit_paint;
2896 paint = g_new (GdkWindowPaint, 1);
2897 paint->region = cairo_region_copy (region);
2898 paint->region_tag = new_region_tag ();
2900 cairo_region_intersect (paint->region, window->clip_region_with_children);
2901 cairo_region_get_extents (paint->region, &clip_box);
2903 cairo_region_translate (paint->region, window->abs_x, window->abs_y);
2905 /* Mark the region as valid on the implicit paint */
2908 cairo_region_union (implicit_paint->region, paint->region);
2910 /* Convert back to normal coords */
2911 cairo_region_translate (paint->region, -window->abs_x, -window->abs_y);
2915 paint->uses_implicit = TRUE;
2916 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
2917 window->abs_x + clip_box.x,
2918 window->abs_y + clip_box.y,
2919 MAX (clip_box.width, 1),
2920 MAX (clip_box.height, 1));
2924 paint->uses_implicit = FALSE;
2925 paint->surface = gdk_window_create_similar_surface (window,
2926 gdk_window_get_content (window),
2927 MAX (clip_box.width, 1),
2928 MAX (clip_box.height, 1));
2930 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
2932 for (list = window->paint_stack; list != NULL; list = list->next)
2934 GdkWindowPaint *tmp_paint = list->data;
2936 cairo_region_subtract (tmp_paint->region, paint->region);
2939 window->paint_stack = g_slist_prepend (window->paint_stack, paint);
2941 if (!cairo_region_is_empty (paint->region))
2943 gdk_window_clear_backing_region (window,
2947 #endif /* USE_BACKING_STORE */
2951 * gdk_window_end_paint:
2952 * @window: a #GdkWindow
2954 * Indicates that the backing store created by the most recent call to
2955 * gdk_window_begin_paint_region() should be copied onscreen and
2956 * deleted, leaving the next-most-recent backing store or no backing
2957 * store at all as the active paint region. See
2958 * gdk_window_begin_paint_region() for full details. It is an error to
2959 * call this function without a matching
2960 * gdk_window_begin_paint_region() first.
2964 gdk_window_end_paint (GdkWindow *window)
2966 #ifdef USE_BACKING_STORE
2967 GdkWindow *composited;
2968 GdkWindowPaint *paint;
2969 GdkRectangle clip_box;
2970 cairo_region_t *full_clip;
2972 g_return_if_fail (GDK_IS_WINDOW (window));
2974 if (GDK_WINDOW_DESTROYED (window))
2977 if (GDK_IS_PAINTABLE (window->impl))
2979 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
2981 if (iface->end_paint)
2982 iface->end_paint ((GdkPaintable*)window->impl);
2986 if (window->paint_stack == NULL)
2988 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
2992 paint = window->paint_stack->data;
2994 window->paint_stack = g_slist_delete_link (window->paint_stack,
2995 window->paint_stack);
2997 cairo_region_get_extents (paint->region, &clip_box);
2999 if (!paint->uses_implicit)
3003 gdk_window_flush_outstanding_moves (window);
3005 full_clip = cairo_region_copy (window->clip_region_with_children);
3006 cairo_region_intersect (full_clip, paint->region);
3008 cr = gdk_cairo_create (window);
3009 cairo_set_source_surface (cr, paint->surface, 0, 0);
3010 gdk_cairo_region (cr, full_clip);
3014 cairo_region_destroy (full_clip);
3017 cairo_surface_destroy (paint->surface);
3018 cairo_region_destroy (paint->region);
3021 /* find a composited window in our hierarchy to signal its
3022 * parent to redraw, calculating the clip box as we go...
3024 * stop if parent becomes NULL since then we'd have nowhere
3025 * to draw (ie: 'composited' will always be non-NULL here).
3027 for (composited = window;
3029 composited = composited->parent)
3031 clip_box.x += composited->x;
3032 clip_box.y += composited->y;
3033 clip_box.width = MIN (clip_box.width, composited->parent->width - clip_box.x);
3034 clip_box.height = MIN (clip_box.height, composited->parent->height - clip_box.y);
3036 if (composited->composited)
3038 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3043 #endif /* USE_BACKING_STORE */
3047 gdk_window_free_paint_stack (GdkWindow *window)
3049 if (window->paint_stack)
3051 GSList *tmp_list = window->paint_stack;
3055 GdkWindowPaint *paint = tmp_list->data;
3057 if (tmp_list == window->paint_stack)
3058 cairo_surface_destroy (paint->surface);
3060 cairo_region_destroy (paint->region);
3063 tmp_list = tmp_list->next;
3066 g_slist_free (window->paint_stack);
3067 window->paint_stack = NULL;
3072 do_move_region_bits_on_impl (GdkWindow *impl_window,
3073 cairo_region_t *dest_region, /* In impl window coords */
3076 GdkWindowImplClass *impl_class;
3078 impl_class = GDK_WINDOW_IMPL_GET_CLASS (impl_window->impl);
3080 impl_class->translate (impl_window, dest_region, dx, dy);
3083 static GdkWindowRegionMove *
3084 gdk_window_region_move_new (cairo_region_t *region,
3087 GdkWindowRegionMove *move;
3089 move = g_slice_new (GdkWindowRegionMove);
3090 move->dest_region = cairo_region_copy (region);
3098 gdk_window_region_move_free (GdkWindowRegionMove *move)
3100 cairo_region_destroy (move->dest_region);
3101 g_slice_free (GdkWindowRegionMove, move);
3105 append_move_region (GdkWindow *impl_window,
3106 cairo_region_t *new_dest_region,
3109 GdkWindowRegionMove *move, *old_move;
3110 cairo_region_t *new_total_region, *old_total_region;
3111 cairo_region_t *source_overlaps_destination;
3112 cairo_region_t *non_overwritten;
3113 gboolean added_move;
3116 if (cairo_region_is_empty (new_dest_region))
3119 /* In principle this could just append the move to the list of outstanding
3120 moves that will be replayed before drawing anything when we're handling
3121 exposes. However, we'd like to do a bit better since its commonly the case
3122 that we get multiple copies where A is copied to B and then B is copied
3123 to C, and we'd like to express this as a simple copy A to C operation. */
3125 /* We approach this by taking the new move and pushing it ahead of moves
3126 starting at the end of the list and stopping when its not safe to do so.
3127 It's not safe to push past a move if either the source of the new move
3128 is in the destination of the old move, or if the destination of the new
3129 move is in the source of the new move, or if the destination of the new
3130 move overlaps the destination of the old move. We simplify this by
3131 just comparing the total regions (src + dest) */
3132 new_total_region = cairo_region_copy (new_dest_region);
3133 cairo_region_translate (new_total_region, -dx, -dy);
3134 cairo_region_union (new_total_region, new_dest_region);
3137 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3142 old_total_region = cairo_region_copy (old_move->dest_region);
3143 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3144 cairo_region_union (old_total_region, old_move->dest_region);
3146 cairo_region_intersect (old_total_region, new_total_region);
3147 /* If these regions intersect then its not safe to push the
3148 new region before the old one */
3149 if (!cairo_region_is_empty (old_total_region))
3151 /* The area where the new moves source overlaps the old ones
3153 source_overlaps_destination = cairo_region_copy (new_dest_region);
3154 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3155 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3156 cairo_region_translate (source_overlaps_destination, dx, dy);
3158 /* We can do all sort of optimizations here, but to do things safely it becomes
3159 quite complicated. However, a very common case is that you copy something first,
3160 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3161 in the same direction). We'd like to detect this case and optimize it to one
3163 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3165 /* This means we might be able to replace the old move and the new one
3166 with the new one read from the old ones source, and a second copy of
3167 the non-overwritten parts of the old move. However, such a split
3168 is only valid if the source in the old move isn't overwritten
3169 by the destination of the new one */
3171 /* the new destination of old move if split is ok: */
3172 non_overwritten = cairo_region_copy (old_move->dest_region);
3173 cairo_region_subtract (non_overwritten, new_dest_region);
3174 /* move to source region */
3175 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3177 cairo_region_intersect (non_overwritten, new_dest_region);
3178 if (cairo_region_is_empty (non_overwritten))
3181 move = gdk_window_region_move_new (new_dest_region,
3185 impl_window->outstanding_moves =
3186 g_list_insert_before (impl_window->outstanding_moves,
3188 cairo_region_subtract (old_move->dest_region, new_dest_region);
3190 cairo_region_destroy (non_overwritten);
3193 cairo_region_destroy (source_overlaps_destination);
3194 cairo_region_destroy (old_total_region);
3197 cairo_region_destroy (old_total_region);
3200 cairo_region_destroy (new_total_region);
3204 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3207 impl_window->outstanding_moves =
3208 g_list_prepend (impl_window->outstanding_moves,
3211 impl_window->outstanding_moves =
3212 g_list_insert_before (impl_window->outstanding_moves,
3217 /* Moves bits and update area by dx/dy in impl window.
3218 Takes ownership of region to avoid copy (because we may change it) */
3220 move_region_on_impl (GdkWindow *impl_window,
3221 cairo_region_t *region, /* In impl window coords */
3224 if ((dx == 0 && dy == 0) ||
3225 cairo_region_is_empty (region))
3227 cairo_region_destroy (region);
3231 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3233 /* Move any old invalid regions in the copy source area by dx/dy */
3234 if (impl_window->update_area)
3236 cairo_region_t *update_area;
3238 update_area = cairo_region_copy (region);
3240 /* Convert from target to source */
3241 cairo_region_translate (update_area, -dx, -dy);
3242 cairo_region_intersect (update_area, impl_window->update_area);
3243 /* We only copy the area, so keep the old update area invalid.
3244 It would be safe to remove it too, as code that uses
3245 move_region_on_impl generally also invalidate the source
3246 area. However, it would just use waste cycles. */
3249 cairo_region_translate (update_area, dx, dy);
3250 cairo_region_union (impl_window->update_area, update_area);
3252 /* This area of the destination is now invalid,
3253 so no need to copy to it. */
3254 cairo_region_subtract (region, update_area);
3256 cairo_region_destroy (update_area);
3259 /* If we're currently exposing this window, don't copy to this
3260 destination, as it will be overdrawn when the expose is done,
3261 instead invalidate it and repaint later. */
3262 if (impl_window->implicit_paint)
3264 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3265 cairo_region_t *exposing;
3267 exposing = cairo_region_copy (implicit_paint->region);
3268 cairo_region_intersect (exposing, region);
3269 cairo_region_subtract (region, exposing);
3271 impl_window_add_update_area (impl_window, exposing);
3272 cairo_region_destroy (exposing);
3275 append_move_region (impl_window, region, dx, dy);
3277 cairo_region_destroy (region);
3280 /* Flushes all outstanding changes to the window, call this
3281 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3284 gdk_window_flush_outstanding_moves (GdkWindow *window)
3286 GdkWindow *impl_window;
3287 GList *l, *outstanding;
3288 GdkWindowRegionMove *move;
3290 impl_window = gdk_window_get_impl_window (window);
3291 outstanding = impl_window->outstanding_moves;
3292 impl_window->outstanding_moves = NULL;
3294 for (l = outstanding; l != NULL; l = l->next)
3298 do_move_region_bits_on_impl (impl_window,
3299 move->dest_region, move->dx, move->dy);
3301 gdk_window_region_move_free (move);
3304 g_list_free (outstanding);
3309 * @window: a #GdkWindow
3311 * Flush all outstanding cached operations on a window, leaving the
3312 * window in a state which reflects all that has been drawn before.
3314 * Gdk uses multiple kinds of caching to get better performance and
3315 * nicer drawing. For instance, during exposes all paints to a window
3316 * using double buffered rendering are keep on a surface until the last
3317 * window has been exposed. It also delays window moves/scrolls until
3318 * as long as possible until next update to avoid tearing when moving
3321 * Normally this should be completely invisible to applications, as
3322 * we automatically flush the windows when required, but this might
3323 * be needed if you for instance mix direct native drawing with
3324 * gdk drawing. For Gtk widgets that don't use double buffering this
3325 * will be called automatically before sending the expose event.
3330 gdk_window_flush (GdkWindow *window)
3332 gdk_window_flush_outstanding_moves (window);
3333 gdk_window_flush_implicit_paint (window);
3336 /* If we're about to move/resize or otherwise change the
3337 * hierarchy of a client side window in an impl and we're
3338 * called from an expose event handler then we need to
3339 * flush any already painted parts of the implicit paint
3340 * that are not part of the current paint, as these may
3341 * be used when scrolling or may overdraw the changes
3342 * caused by the hierarchy change.
3345 gdk_window_flush_if_exposing (GdkWindow *window)
3347 GdkWindow *impl_window;
3349 impl_window = gdk_window_get_impl_window (window);
3351 /* If we're in an implicit paint (i.e. in an expose handler, flush
3352 all the already finished exposes to get things to an uptodate state. */
3353 if (impl_window->implicit_paint)
3354 gdk_window_flush (window);
3359 gdk_window_flush_recursive_helper (GdkWindow *window,
3360 GdkWindowImpl *impl)
3365 for (l = window->children; l != NULL; l = l->next)
3369 if (child->impl == impl)
3370 /* Same impl, ignore */
3371 gdk_window_flush_recursive_helper (child, impl);
3373 gdk_window_flush_recursive (child);
3378 gdk_window_flush_recursive (GdkWindow *window)
3380 gdk_window_flush (window);
3381 gdk_window_flush_recursive_helper (window, window->impl);
3385 * gdk_window_get_clip_region:
3386 * @window: a #GdkWindow
3388 * Computes the region of a window that potentially can be written
3389 * to by drawing primitives. This region may not take into account
3390 * other factors such as if the window is obscured by other windows,
3391 * but no area outside of this region will be affected by drawing
3394 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3395 * when you are done.
3398 gdk_window_get_clip_region (GdkWindow *window)
3400 cairo_region_t *result;
3402 g_return_val_if_fail (GDK_WINDOW (window), NULL);
3404 result = cairo_region_copy (window->clip_region);
3406 if (window->paint_stack)
3408 cairo_region_t *paint_region = cairo_region_create ();
3409 GSList *tmp_list = window->paint_stack;
3413 GdkWindowPaint *paint = tmp_list->data;
3415 cairo_region_union (paint_region, paint->region);
3417 tmp_list = tmp_list->next;
3420 cairo_region_intersect (result, paint_region);
3421 cairo_region_destroy (paint_region);
3428 * gdk_window_get_visible_region:
3429 * @window: a #GdkWindow
3431 * Computes the region of the @window that is potentially visible.
3432 * This does not necessarily take into account if the window is
3433 * obscured by other windows, but no area outside of this region
3436 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3437 * when you are done.
3440 gdk_window_get_visible_region (GdkWindow *window)
3442 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3444 return cairo_region_copy (window->clip_region);
3448 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3450 GdkWindow *bg_window;
3451 cairo_pattern_t *pattern = NULL;
3452 int x_offset = 0, y_offset = 0;
3455 cr = cairo_create (paint->surface);
3457 for (bg_window = window; bg_window; bg_window = bg_window->parent)
3459 pattern = gdk_window_get_background_pattern (bg_window);
3463 x_offset += bg_window->x;
3464 y_offset += bg_window->y;
3469 cairo_translate (cr, -x_offset, -y_offset);
3470 cairo_set_source (cr, pattern);
3471 cairo_translate (cr, x_offset, y_offset);
3474 cairo_set_source_rgb (cr, 0, 0, 0);
3480 gdk_window_clear_backing_region (GdkWindow *window,
3481 cairo_region_t *region)
3483 GdkWindowPaint *paint = window->paint_stack->data;
3484 cairo_region_t *clip;
3485 GdkRectangle clipbox;
3488 if (GDK_WINDOW_DESTROYED (window))
3491 cr = setup_backing_rect (window, paint, 0, 0);
3493 clip = cairo_region_copy (paint->region);
3494 cairo_region_intersect (clip, region);
3495 cairo_region_get_extents (clip, &clipbox);
3497 gdk_cairo_region (cr, clip);
3502 cairo_region_destroy (clip);
3506 gdk_window_clear_backing_region_direct (GdkWindow *window,
3507 cairo_region_t *region)
3509 GdkWindowPaint paint;
3510 cairo_region_t *clip;
3511 GdkRectangle clipbox;
3514 if (GDK_WINDOW_DESTROYED (window))
3517 paint.surface = _gdk_window_ref_cairo_surface (window);
3519 cr = setup_backing_rect (window, &paint, 0, 0);
3521 clip = cairo_region_copy (window->clip_region_with_children);
3522 cairo_region_intersect (clip, region);
3523 cairo_region_get_extents (clip, &clipbox);
3525 gdk_cairo_region (cr, clip);
3530 cairo_region_destroy (clip);
3531 cairo_surface_destroy (paint.surface);
3536 gdk_window_clear_region_internal (GdkWindow *window,
3537 cairo_region_t *region)
3539 if (window->paint_stack)
3540 gdk_window_clear_backing_region (window, region);
3542 gdk_window_clear_backing_region_direct (window, region);
3546 gdk_window_drop_cairo_surface (GdkWindow *window)
3548 if (window->cairo_surface)
3550 cairo_surface_finish (window->cairo_surface);
3551 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3553 window->cairo_surface = NULL;
3558 gdk_window_cairo_surface_destroy (void *data)
3560 GdkWindow *window = data;
3562 window->cairo_surface = NULL;
3565 static cairo_surface_t *
3566 gdk_window_create_cairo_surface (GdkWindow *window,
3570 cairo_surface_t *surface, *subsurface;
3572 surface = gdk_window_ref_impl_surface (window);
3573 if (gdk_window_has_impl (window))
3576 subsurface = cairo_surface_create_for_rectangle (surface,
3581 cairo_surface_destroy (surface);
3587 _gdk_window_ref_cairo_surface (GdkWindow *window)
3589 cairo_surface_t *surface;
3591 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3593 if (window->paint_stack)
3595 GdkWindowPaint *paint = window->paint_stack->data;
3597 surface = paint->surface;
3598 cairo_surface_reference (surface);
3603 /* This will be drawing directly to the window, so flush implicit paint */
3604 gdk_window_flush (window);
3606 if (!window->cairo_surface)
3608 window->cairo_surface = gdk_window_create_cairo_surface (window,
3612 if (window->cairo_surface)
3614 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3615 window, gdk_window_cairo_surface_destroy);
3619 cairo_surface_reference (window->cairo_surface);
3621 surface = window->cairo_surface;
3629 * @window: a #GdkWindow
3631 * Creates a Cairo context for drawing to @window.
3634 * Note that calling cairo_reset_clip() on the resulting #cairo_t will
3635 * produce undefined results, so avoid it at all costs.
3638 * Return value: A newly created Cairo context. Free with
3639 * cairo_destroy() when you are done drawing.
3644 gdk_cairo_create (GdkWindow *window)
3646 cairo_surface_t *surface;
3649 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3651 surface = _gdk_window_ref_cairo_surface (window);
3652 cr = cairo_create (surface);
3654 if (!window->paint_stack)
3656 gdk_cairo_region (cr, window->clip_region_with_children);
3661 GdkWindowPaint *paint = window->paint_stack->data;
3663 /* Only needs to clip to region if piggybacking
3664 on an implicit paint */
3665 if (paint->uses_implicit)
3667 gdk_cairo_region (cr, paint->region);
3672 cairo_surface_destroy (surface);
3677 /* Code for dirty-region queueing
3679 static GSList *update_windows = NULL;
3680 static guint update_idle = 0;
3681 static gboolean debug_updates = FALSE;
3683 static inline gboolean
3684 gdk_window_is_ancestor (GdkWindow *window,
3685 GdkWindow *ancestor)
3689 GdkWindow *parent = window->parent;
3691 if (parent == ancestor)
3701 gdk_window_add_update_window (GdkWindow *window)
3704 GSList *prev = NULL;
3705 gboolean has_ancestor_in_list = FALSE;
3707 for (tmp = update_windows; tmp; tmp = tmp->next)
3709 GdkWindow *parent = window->parent;
3711 /* check if tmp is an ancestor of "window"; if it is, set a
3712 * flag indicating that all following windows are either
3713 * children of "window" or from a differen hierarchy
3715 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3716 has_ancestor_in_list = TRUE;
3718 /* insert in reverse stacking order when adding around siblings,
3719 * so processing updates properly paints over lower stacked windows
3721 if (parent == GDK_WINDOW (tmp->data)->parent)
3723 gint index = g_list_index (parent->children, window);
3724 for (; tmp && parent == GDK_WINDOW (tmp->data)->parent; tmp = tmp->next)
3726 gint sibling_index = g_list_index (parent->children, tmp->data);
3727 if (index > sibling_index)
3731 /* here, tmp got advanced past all lower stacked siblings */
3732 tmp = g_slist_prepend (tmp, window);
3736 update_windows = tmp;
3740 /* if "window" has an ancestor in the list and tmp is one of
3741 * "window's" children, insert "window" before tmp
3743 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3745 tmp = g_slist_prepend (tmp, window);
3750 update_windows = tmp;
3754 /* if we're at the end of the list and had an ancestor it it,
3755 * append to the list
3757 if (! tmp->next && has_ancestor_in_list)
3759 tmp = g_slist_append (tmp, window);
3766 /* if all above checks failed ("window" is from a different
3767 * hierarchy than what is already in the list) or the list is
3770 update_windows = g_slist_prepend (update_windows, window);
3774 gdk_window_remove_update_window (GdkWindow *window)
3776 update_windows = g_slist_remove (update_windows, window);
3780 gdk_window_update_idle (gpointer data)
3782 gdk_window_process_all_updates ();
3788 gdk_window_is_toplevel_frozen (GdkWindow *window)
3790 GdkWindow *toplevel;
3792 toplevel = gdk_window_get_toplevel (window);
3794 return toplevel->update_and_descendants_freeze_count > 0;
3798 gdk_window_schedule_update (GdkWindow *window)
3801 (window->update_freeze_count ||
3802 gdk_window_is_toplevel_frozen (window)))
3807 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
3808 gdk_window_update_idle,
3813 _gdk_window_process_updates_recurse (GdkWindow *window,
3814 cairo_region_t *expose_region)
3817 cairo_region_t *child_region;
3819 GList *l, *children;
3821 if (cairo_region_is_empty (expose_region))
3824 if (gdk_window_is_offscreen (window->impl_window) &&
3825 window == window->impl_window)
3826 _gdk_window_add_damage ((GdkWindow *) window->impl_window, expose_region);
3828 /* Make this reentrancy safe for expose handlers freeing windows */
3829 children = g_list_copy (window->children);
3830 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3832 /* Iterate over children, starting at topmost */
3833 for (l = children; l != NULL; l = l->next)
3837 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3840 /* Ignore offscreen children, as they don't draw in their parent and
3841 * don't take part in the clipping */
3842 if (gdk_window_is_offscreen (child))
3847 r.width = child->width;
3848 r.height = child->height;
3850 child_region = cairo_region_create_rectangle (&r);
3853 /* Adjust shape region to parent window coords */
3854 cairo_region_translate (child->shape, child->x, child->y);
3855 cairo_region_intersect (child_region, child->shape);
3856 cairo_region_translate (child->shape, -child->x, -child->y);
3859 if (child->impl == window->impl)
3861 /* Client side child, expose */
3862 cairo_region_intersect (child_region, expose_region);
3863 cairo_region_subtract (expose_region, child_region);
3864 cairo_region_translate (child_region, -child->x, -child->y);
3865 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
3869 /* Native child, just remove area from expose region */
3870 cairo_region_subtract (expose_region, child_region);
3872 cairo_region_destroy (child_region);
3875 g_list_foreach (children, (GFunc)g_object_unref, NULL);
3876 g_list_free (children);
3878 if (!cairo_region_is_empty (expose_region) &&
3881 if (window->event_mask & GDK_EXPOSURE_MASK)
3885 event.expose.type = GDK_EXPOSE;
3886 event.expose.window = g_object_ref (window);
3887 event.expose.send_event = FALSE;
3888 event.expose.count = 0;
3889 event.expose.region = expose_region;
3890 cairo_region_get_extents (expose_region, &event.expose.area);
3892 _gdk_event_emit (&event);
3894 g_object_unref (window);
3896 else if (window->window_type != GDK_WINDOW_FOREIGN)
3898 /* No exposure mask set, so nothing will be drawn, the
3899 * app relies on the background being what it specified
3900 * for the window. So, we need to clear this manually.
3902 * For foreign windows if expose is not set that generally
3903 * means some other client paints them, so don't clear
3906 * We use begin/end_paint around the clear so that we can
3907 * piggyback on the implicit paint */
3909 gdk_window_begin_paint_region (window, expose_region);
3910 gdk_window_clear_region_internal (window, expose_region);
3911 gdk_window_end_paint (window);
3916 /* Process and remove any invalid area on the native window by creating
3917 * expose events for the window and all non-native descendants.
3918 * Also processes any outstanding moves on the window before doing
3919 * any drawing. Note that its possible to have outstanding moves without
3920 * any invalid area as we use the update idle mechanism to coalesce
3921 * multiple moves as well as multiple invalidations.
3924 gdk_window_process_updates_internal (GdkWindow *window)
3926 GdkWindowImplClass *impl_class;
3927 gboolean save_region = FALSE;
3928 GdkRectangle clip_box;
3930 /* Ensure the window lives while updating it */
3931 g_object_ref (window);
3933 /* If an update got queued during update processing, we can get a
3934 * window in the update queue that has an empty update_area.
3937 if (window->update_area)
3939 cairo_region_t *update_area = window->update_area;
3940 window->update_area = NULL;
3942 if (gdk_window_is_viewable (window))
3944 cairo_region_t *expose_region;
3945 gboolean end_implicit;
3947 /* Clip to part visible in toplevel */
3948 cairo_region_intersect (update_area, window->clip_region);
3952 /* Make sure we see the red invalid area before redrawing. */
3953 gdk_display_sync (gdk_window_get_display (window));
3957 /* At this point we will be completely redrawing all of update_area.
3958 * If we have any outstanding moves that end up moving stuff inside
3959 * this area we don't actually need to move that as that part would
3960 * be overdrawn by the expose anyway. So, in order to copy less data
3961 * we remove these areas from the outstanding moves.
3963 if (window->outstanding_moves)
3965 GdkWindowRegionMove *move;
3966 cairo_region_t *remove;
3969 remove = cairo_region_copy (update_area);
3970 /* We iterate backwards, starting from the state that would be
3971 if we had applied all the moves. */
3972 for (l = g_list_last (window->outstanding_moves); l != NULL; l = prev)
3977 /* Don't need this area */
3978 cairo_region_subtract (move->dest_region, remove);
3980 /* However if any of the destination we do need has a source
3981 in the updated region we do need that as a destination for
3982 the earlier moves */
3983 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
3984 cairo_region_subtract (remove, move->dest_region);
3986 if (cairo_region_is_empty (move->dest_region))
3988 gdk_window_region_move_free (move);
3989 window->outstanding_moves =
3990 g_list_delete_link (window->outstanding_moves, l);
3992 else /* move back */
3993 cairo_region_translate (move->dest_region, move->dx, move->dy);
3995 cairo_region_destroy (remove);
3998 /* By now we a set of window moves that should be applied, and then
3999 * an update region that should be repainted. A trivial implementation
4000 * would just do that in order, however in order to get nicer drawing
4001 * we do some tricks:
4003 * First of all, each subwindow expose may be double buffered by
4004 * itself (depending on widget setting) via
4005 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
4006 * creating a single surface the size of the invalid area on the
4007 * native window which all the individual normal paints will draw
4008 * into. This way in the normal case there will be only one surface
4009 * allocated and only once surface draw done for all the windows
4010 * in this native window.
4011 * There are a couple of reasons this may fail, for instance, some
4012 * backends (like quartz) do its own double buffering, so we disable
4013 * gdk double buffering there. Secondly, some subwindow could be
4014 * non-double buffered and draw directly to the window outside a
4015 * begin/end_paint pair. That will be lead to a gdk_window_flush
4016 * which immediately executes all outstanding moves and paints+removes
4017 * the implicit paint (further paints will allocate their own surfaces).
4019 * Secondly, in the case of implicit double buffering we expose all
4020 * the child windows into the implicit surface before we execute
4021 * the outstanding moves. This way we minimize the time between
4022 * doing the moves and rendering the new update area, thus minimizing
4023 * flashing. Of course, if any subwindow is non-double buffered we
4024 * well flush earlier than that.
4026 * Thirdly, after having done the outstanding moves we queue an
4027 * "antiexpose" on the area that will be drawn by the expose, which
4028 * means that any invalid region on the native window side before
4029 * the first expose drawing operation will be discarded, as it
4030 * has by then been overdrawn with valid data. This means we can
4031 * avoid doing the unnecessary repaint any outstanding expose events.
4034 cairo_region_get_extents (update_area, &clip_box);
4035 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
4036 expose_region = cairo_region_copy (update_area);
4039 /* Rendering is not double buffered by gdk, do outstanding
4040 * moves and queue antiexposure immediately. No need to do
4042 gdk_window_flush_outstanding_moves (window);
4043 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
4044 save_region = impl_class->queue_antiexpose (window, update_area);
4047 /* Render the invalid areas to the implicit paint, by sending exposes.
4048 * May flush if non-double buffered widget draw. */
4049 _gdk_windowing_window_process_updates_recurse (window, expose_region);
4053 /* Do moves right before exposes are rendered to the window */
4054 gdk_window_flush_outstanding_moves (window);
4056 /* By this time we know that any outstanding expose for this
4057 * area is invalid and we can avoid it, so queue an antiexpose.
4058 * However, it may be that due to an non-double buffered expose
4059 * we have already started drawing to the window, so it would
4060 * be to late to anti-expose now. Since this is merely an
4061 * optimization we just avoid doing it at all in that case.
4063 if (window->implicit_paint != NULL &&
4064 !window->implicit_paint->flushed)
4066 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
4067 save_region = impl_class->queue_antiexpose (window, update_area);
4070 gdk_window_end_implicit_paint (window);
4072 cairo_region_destroy (expose_region);
4075 cairo_region_destroy (update_area);
4078 if (window->outstanding_moves)
4080 /* Flush any outstanding moves, may happen if we moved a window but got
4081 no actual invalid area */
4082 gdk_window_flush_outstanding_moves (window);
4085 g_object_unref (window);
4089 flush_all_displays (void)
4091 GSList *displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4094 for (tmp_list = displays; tmp_list; tmp_list = tmp_list->next)
4095 gdk_display_flush (tmp_list->data);
4097 g_slist_free (displays);
4100 /* Currently it is not possible to override
4101 * gdk_window_process_all_updates in the same manner as
4102 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4103 * by implementing the GdkPaintable interface. If in the future a
4104 * backend would need this, the right solution would be to add a
4105 * method to GdkDisplay that can be optionally
4106 * NULL. gdk_window_process_all_updates can then walk the list of open
4107 * displays and call the mehod.
4111 * gdk_window_process_all_updates:
4113 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4114 * in the application.
4118 gdk_window_process_all_updates (void)
4120 GSList *old_update_windows = update_windows;
4121 GSList *tmp_list = update_windows;
4122 static gboolean in_process_all_updates = FALSE;
4123 static gboolean got_recursive_update = FALSE;
4125 if (in_process_all_updates)
4127 /* We can't do this now since that would recurse, so
4128 delay it until after the recursion is done. */
4129 got_recursive_update = TRUE;
4134 in_process_all_updates = TRUE;
4135 got_recursive_update = FALSE;
4138 g_source_remove (update_idle);
4140 update_windows = NULL;
4143 _gdk_windowing_before_process_all_updates ();
4145 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4149 GdkWindow *window = tmp_list->data;
4151 if (!GDK_WINDOW_DESTROYED (window))
4153 if (window->update_freeze_count ||
4154 gdk_window_is_toplevel_frozen (window))
4155 gdk_window_add_update_window (window);
4157 gdk_window_process_updates_internal (window);
4160 g_object_unref (window);
4161 tmp_list = tmp_list->next;
4164 g_slist_free (old_update_windows);
4166 flush_all_displays ();
4168 _gdk_windowing_after_process_all_updates ();
4170 in_process_all_updates = FALSE;
4172 /* If we ignored a recursive call, schedule a
4173 redraw now so that it eventually happens,
4174 otherwise we could miss an update if nothing
4175 else schedules an update. */
4176 if (got_recursive_update && !update_idle)
4178 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4179 gdk_window_update_idle,
4184 * gdk_window_process_updates:
4185 * @window: a #GdkWindow
4186 * @update_children: whether to also process updates for child windows
4188 * Sends one or more expose events to @window. The areas in each
4189 * expose event will cover the entire update area for the window (see
4190 * gdk_window_invalidate_region() for details). Normally GDK calls
4191 * gdk_window_process_all_updates() on your behalf, so there's no
4192 * need to call this function unless you want to force expose events
4193 * to be delivered immediately and synchronously (vs. the usual
4194 * case, where GDK delivers them in an idle handler). Occasionally
4195 * this is useful to produce nicer scrolling behavior, for example.
4199 gdk_window_process_updates (GdkWindow *window,
4200 gboolean update_children)
4202 GdkWindow *impl_window;
4204 g_return_if_fail (GDK_IS_WINDOW (window));
4206 if (GDK_WINDOW_DESTROYED (window))
4209 /* Make sure the window lives during the expose callouts */
4210 g_object_ref (window);
4212 impl_window = gdk_window_get_impl_window (window);
4213 if ((impl_window->update_area ||
4214 impl_window->outstanding_moves) &&
4215 !impl_window->update_freeze_count &&
4216 !gdk_window_is_toplevel_frozen (window) &&
4218 /* Don't recurse into process_updates_internal, we'll
4219 * do the update later when idle instead. */
4220 impl_window->implicit_paint == NULL)
4222 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4223 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4226 if (update_children)
4228 /* process updates in reverse stacking order so composition or
4229 * painting over achieves the desired effect for offscreen windows
4231 GList *node, *children;
4233 children = g_list_copy (window->children);
4234 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4236 for (node = g_list_last (children); node; node = node->prev)
4238 gdk_window_process_updates (node->data, TRUE);
4239 g_object_unref (node->data);
4242 g_list_free (children);
4245 g_object_unref (window);
4249 gdk_window_invalidate_rect_full (GdkWindow *window,
4250 const GdkRectangle *rect,
4251 gboolean invalidate_children,
4254 GdkRectangle window_rect;
4255 cairo_region_t *region;
4257 g_return_if_fail (GDK_IS_WINDOW (window));
4259 if (GDK_WINDOW_DESTROYED (window))
4262 if (window->input_only || !window->viewable)
4269 window_rect.width = window->width;
4270 window_rect.height = window->height;
4271 rect = &window_rect;
4274 region = cairo_region_create_rectangle (rect);
4275 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4276 cairo_region_destroy (region);
4280 * gdk_window_invalidate_rect:
4281 * @window: a #GdkWindow
4282 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4284 * @invalidate_children: whether to also invalidate child windows
4286 * A convenience wrapper around gdk_window_invalidate_region() which
4287 * invalidates a rectangular region. See
4288 * gdk_window_invalidate_region() for details.
4291 gdk_window_invalidate_rect (GdkWindow *window,
4292 const GdkRectangle *rect,
4293 gboolean invalidate_children)
4295 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4299 draw_ugly_color (GdkWindow *window,
4300 const cairo_region_t *region)
4304 cr = gdk_cairo_create (window);
4305 /* Draw ugly color all over the newly-invalid region */
4306 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4307 gdk_cairo_region (cr, region);
4314 impl_window_add_update_area (GdkWindow *impl_window,
4315 cairo_region_t *region)
4317 if (impl_window->update_area)
4318 cairo_region_union (impl_window->update_area, region);
4321 gdk_window_add_update_window (impl_window);
4322 impl_window->update_area = cairo_region_copy (region);
4323 gdk_window_schedule_update (impl_window);
4327 /* clear_bg controls if the region will be cleared to
4328 * the background pattern if the exposure mask is not
4329 * set for the window, whereas this might not otherwise be
4330 * done (unless necessary to emulate background settings).
4331 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4332 * need to clear the background, such as when exposing the area beneath a
4333 * hidden or moved window, but not when an app requests repaint or when the
4334 * windowing system exposes a newly visible area (because then the windowing
4335 * system has already cleared the area).
4338 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4339 const cairo_region_t *region,
4341 GdkWindowChildFunc child_func,
4344 GdkWindow *impl_window;
4345 cairo_region_t *visible_region;
4348 g_return_if_fail (GDK_IS_WINDOW (window));
4350 if (GDK_WINDOW_DESTROYED (window))
4353 if (window->input_only ||
4354 !window->viewable ||
4355 cairo_region_is_empty (region) ||
4356 window->window_type == GDK_WINDOW_ROOT)
4359 visible_region = gdk_window_get_visible_region (window);
4360 cairo_region_intersect (visible_region, region);
4362 tmp_list = window->children;
4365 GdkWindow *child = tmp_list->data;
4367 if (!child->input_only)
4369 cairo_region_t *child_region;
4370 GdkRectangle child_rect;
4372 child_rect.x = child->x;
4373 child_rect.y = child->y;
4374 child_rect.width = child->width;
4375 child_rect.height = child->height;
4376 child_region = cairo_region_create_rectangle (&child_rect);
4378 /* remove child area from the invalid area of the parent */
4379 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4380 !child->composited &&
4381 !gdk_window_is_offscreen (child))
4382 cairo_region_subtract (visible_region, child_region);
4384 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4386 cairo_region_t *tmp = cairo_region_copy (region);
4388 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4389 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4390 cairo_region_intersect (child_region, tmp);
4392 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4393 child_region, clear_bg, child_func, user_data);
4395 cairo_region_destroy (tmp);
4398 cairo_region_destroy (child_region);
4401 tmp_list = tmp_list->next;
4404 impl_window = gdk_window_get_impl_window (window);
4406 if (!cairo_region_is_empty (visible_region) ||
4407 /* Even if we're not exposing anything, make sure we process
4408 idles for windows with outstanding moves */
4409 (impl_window->outstanding_moves != NULL &&
4410 impl_window->update_area == NULL))
4413 draw_ugly_color (window, region);
4415 /* Convert to impl coords */
4416 cairo_region_translate (visible_region, window->abs_x, window->abs_y);
4418 /* Only invalidate area if app requested expose events or if
4419 we need to clear the area (by request or to emulate background
4420 clearing for non-native windows or native windows with no support
4421 for window backgrounds */
4422 if (window->event_mask & GDK_EXPOSURE_MASK ||
4423 clear_bg == CLEAR_BG_ALL ||
4424 clear_bg == CLEAR_BG_WINCLEARED)
4425 impl_window_add_update_area (impl_window, visible_region);
4428 cairo_region_destroy (visible_region);
4432 * gdk_window_invalidate_maybe_recurse:
4433 * @window: a #GdkWindow
4434 * @region: a #cairo_region_t
4435 * @child_func: function to use to decide if to recurse to a child,
4436 * %NULL means never recurse.
4437 * @user_data: data passed to @child_func
4439 * Adds @region to the update area for @window. The update area is the
4440 * region that needs to be redrawn, or "dirty region." The call
4441 * gdk_window_process_updates() sends one or more expose events to the
4442 * window, which together cover the entire update area. An
4443 * application would normally redraw the contents of @window in
4444 * response to those expose events.
4446 * GDK will call gdk_window_process_all_updates() on your behalf
4447 * whenever your program returns to the main loop and becomes idle, so
4448 * normally there's no need to do that manually, you just need to
4449 * invalidate regions that you know should be redrawn.
4451 * The @child_func parameter controls whether the region of
4452 * each child window that intersects @region will also be invalidated.
4453 * Only children for which @child_func returns TRUE will have the area
4457 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4458 const cairo_region_t *region,
4459 GdkWindowChildFunc child_func,
4462 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4463 child_func, user_data);
4467 true_predicate (GdkWindow *window,
4474 gdk_window_invalidate_region_full (GdkWindow *window,
4475 const cairo_region_t *region,
4476 gboolean invalidate_children,
4479 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4480 invalidate_children ?
4481 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4486 * gdk_window_invalidate_region:
4487 * @window: a #GdkWindow
4488 * @region: a #cairo_region_t
4489 * @invalidate_children: %TRUE to also invalidate child windows
4491 * Adds @region to the update area for @window. The update area is the
4492 * region that needs to be redrawn, or "dirty region." The call
4493 * gdk_window_process_updates() sends one or more expose events to the
4494 * window, which together cover the entire update area. An
4495 * application would normally redraw the contents of @window in
4496 * response to those expose events.
4498 * GDK will call gdk_window_process_all_updates() on your behalf
4499 * whenever your program returns to the main loop and becomes idle, so
4500 * normally there's no need to do that manually, you just need to
4501 * invalidate regions that you know should be redrawn.
4503 * The @invalidate_children parameter controls whether the region of
4504 * each child window that intersects @region will also be invalidated.
4505 * If %FALSE, then the update area for child windows will remain
4506 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4507 * fine grained control over which children are invalidated.
4510 gdk_window_invalidate_region (GdkWindow *window,
4511 const cairo_region_t *region,
4512 gboolean invalidate_children)
4514 gdk_window_invalidate_maybe_recurse (window, region,
4515 invalidate_children ?
4516 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4521 * _gdk_window_invalidate_for_expose:
4522 * @window: a #GdkWindow
4523 * @region: a #cairo_region_t
4525 * Adds @region to the update area for @window. The update area is the
4526 * region that needs to be redrawn, or "dirty region." The call
4527 * gdk_window_process_updates() sends one or more expose events to the
4528 * window, which together cover the entire update area. An
4529 * application would normally redraw the contents of @window in
4530 * response to those expose events.
4532 * GDK will call gdk_window_process_all_updates() on your behalf
4533 * whenever your program returns to the main loop and becomes idle, so
4534 * normally there's no need to do that manually, you just need to
4535 * invalidate regions that you know should be redrawn.
4537 * This version of invalidation is used when you recieve expose events
4538 * from the native window system. It exposes the native window, plus
4539 * any non-native child windows (but not native child windows, as those would
4540 * have gotten their own expose events).
4543 _gdk_window_invalidate_for_expose (GdkWindow *window,
4544 cairo_region_t *region)
4546 GdkWindowRegionMove *move;
4547 cairo_region_t *move_region;
4550 /* Any invalidations comming from the windowing system will
4551 be in areas that may be moved by outstanding moves,
4552 so we need to modify the expose region correspondingly,
4553 otherwise we would expose in the wrong place, as the
4554 outstanding moves will be copied before we draw the
4556 for (l = window->outstanding_moves; l != NULL; l = l->next)
4560 /* covert to move source region */
4561 move_region = cairo_region_copy (move->dest_region);
4562 cairo_region_translate (move_region, -move->dx, -move->dy);
4564 /* Move area of region that intersects with move source
4565 by dx, dy of the move*/
4566 cairo_region_intersect (move_region, region);
4567 cairo_region_subtract (region, move_region);
4568 cairo_region_translate (move_region, move->dx, move->dy);
4569 cairo_region_union (region, move_region);
4571 cairo_region_destroy (move_region);
4574 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4575 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4581 * gdk_window_get_update_area:
4582 * @window: a #GdkWindow
4584 * Transfers ownership of the update area from @window to the caller
4585 * of the function. That is, after calling this function, @window will
4586 * no longer have an invalid/dirty region; the update area is removed
4587 * from @window and handed to you. If a window has no update area,
4588 * gdk_window_get_update_area() returns %NULL. You are responsible for
4589 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4591 * Return value: the update area for @window
4594 gdk_window_get_update_area (GdkWindow *window)
4596 GdkWindow *impl_window;
4597 cairo_region_t *tmp_region;
4599 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4601 impl_window = gdk_window_get_impl_window (window);
4603 if (impl_window->update_area)
4605 tmp_region = cairo_region_copy (window->clip_region_with_children);
4606 /* Convert to impl coords */
4607 cairo_region_translate (tmp_region, window->abs_x, window->abs_y);
4608 cairo_region_intersect (tmp_region, impl_window->update_area);
4610 if (cairo_region_is_empty (tmp_region))
4612 cairo_region_destroy (tmp_region);
4617 cairo_region_subtract (impl_window->update_area, tmp_region);
4619 if (cairo_region_is_empty (impl_window->update_area) &&
4620 impl_window->outstanding_moves == NULL)
4622 cairo_region_destroy (impl_window->update_area);
4623 impl_window->update_area = NULL;
4625 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4628 /* Convert from impl coords */
4629 cairo_region_translate (tmp_region, -window->abs_x, -window->abs_y);
4639 * _gdk_window_clear_update_area:
4640 * @window: a #GdkWindow.
4642 * Internal function to clear the update area for a window. This
4643 * is called when the window is hidden or destroyed.
4646 _gdk_window_clear_update_area (GdkWindow *window)
4648 g_return_if_fail (GDK_IS_WINDOW (window));
4650 if (window->update_area)
4652 gdk_window_remove_update_window (window);
4654 cairo_region_destroy (window->update_area);
4655 window->update_area = NULL;
4660 * gdk_window_freeze_updates:
4661 * @window: a #GdkWindow
4663 * Temporarily freezes a window such that it won't receive expose
4664 * events. The window will begin receiving expose events again when
4665 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4666 * has been called more than once, gdk_window_thaw_updates() must be called
4667 * an equal number of times to begin processing exposes.
4670 gdk_window_freeze_updates (GdkWindow *window)
4672 GdkWindow *impl_window;
4674 g_return_if_fail (GDK_IS_WINDOW (window));
4676 impl_window = gdk_window_get_impl_window (window);
4677 impl_window->update_freeze_count++;
4681 * gdk_window_thaw_updates:
4682 * @window: a #GdkWindow
4684 * Thaws a window frozen with gdk_window_freeze_updates().
4687 gdk_window_thaw_updates (GdkWindow *window)
4689 GdkWindow *impl_window;
4691 g_return_if_fail (GDK_IS_WINDOW (window));
4693 impl_window = gdk_window_get_impl_window (window);
4695 g_return_if_fail (impl_window->update_freeze_count > 0);
4697 if (--impl_window->update_freeze_count == 0)
4698 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4702 * gdk_window_freeze_toplevel_updates_libgtk_only:
4703 * @window: a #GdkWindow
4705 * Temporarily freezes a window and all its descendants such that it won't
4706 * receive expose events. The window will begin receiving expose events
4707 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4708 * gdk_window_freeze_toplevel_updates_libgtk_only()
4709 * has been called more than once,
4710 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4711 * an equal number of times to begin processing exposes.
4713 * This function is not part of the GDK public API and is only
4717 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4719 g_return_if_fail (GDK_IS_WINDOW (window));
4720 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4722 window->update_and_descendants_freeze_count++;
4726 * gdk_window_thaw_toplevel_updates_libgtk_only:
4727 * @window: a #GdkWindow
4729 * Thaws a window frozen with
4730 * gdk_window_freeze_toplevel_updates_libgtk_only().
4732 * This function is not part of the GDK public API and is only
4736 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4738 g_return_if_fail (GDK_IS_WINDOW (window));
4739 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4740 g_return_if_fail (window->update_and_descendants_freeze_count > 0);
4742 window->update_and_descendants_freeze_count--;
4744 gdk_window_schedule_update (window);
4748 * gdk_window_set_debug_updates:
4749 * @setting: %TRUE to turn on update debugging
4751 * With update debugging enabled, calls to
4752 * gdk_window_invalidate_region() clear the invalidated region of the
4753 * screen to a noticeable color, and GDK pauses for a short time
4754 * before sending exposes to windows during
4755 * gdk_window_process_updates(). The net effect is that you can see
4756 * the invalid region for each window and watch redraws as they
4757 * occur. This allows you to diagnose inefficiencies in your application.
4759 * In essence, because the GDK rendering model prevents all flicker,
4760 * if you are redrawing the same region 400 times you may never
4761 * notice, aside from noticing a speed problem. Enabling update
4762 * debugging causes GTK to flicker slowly and noticeably, so you can
4763 * see exactly what's being redrawn when, in what order.
4765 * The --gtk-debug=updates command line option passed to GTK+ programs
4766 * enables this debug option at application startup time. That's
4767 * usually more useful than calling gdk_window_set_debug_updates()
4768 * yourself, though you might want to use this function to enable
4769 * updates sometime after application startup time.
4773 gdk_window_set_debug_updates (gboolean setting)
4775 debug_updates = setting;
4779 * gdk_window_constrain_size:
4780 * @geometry: a #GdkGeometry structure
4781 * @flags: a mask indicating what portions of @geometry are set
4782 * @width: desired width of window
4783 * @height: desired height of the window
4784 * @new_width: location to store resulting width
4785 * @new_height: location to store resulting height
4787 * Constrains a desired width and height according to a
4788 * set of geometry hints (such as minimum and maximum size).
4791 gdk_window_constrain_size (GdkGeometry *geometry,
4798 /* This routine is partially borrowed from fvwm.
4800 * Copyright 1993, Robert Nation
4801 * You may use this code for any purpose, as long as the original
4802 * copyright remains in the source code and all documentation
4804 * which in turn borrows parts of the algorithm from uwm
4807 gint min_height = 0;
4808 gint base_width = 0;
4809 gint base_height = 0;
4812 gint max_width = G_MAXINT;
4813 gint max_height = G_MAXINT;
4815 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4817 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4819 base_width = geometry->base_width;
4820 base_height = geometry->base_height;
4821 min_width = geometry->min_width;
4822 min_height = geometry->min_height;
4824 else if (flags & GDK_HINT_BASE_SIZE)
4826 base_width = geometry->base_width;
4827 base_height = geometry->base_height;
4828 min_width = geometry->base_width;
4829 min_height = geometry->base_height;
4831 else if (flags & GDK_HINT_MIN_SIZE)
4833 base_width = geometry->min_width;
4834 base_height = geometry->min_height;
4835 min_width = geometry->min_width;
4836 min_height = geometry->min_height;
4839 if (flags & GDK_HINT_MAX_SIZE)
4841 max_width = geometry->max_width ;
4842 max_height = geometry->max_height;
4845 if (flags & GDK_HINT_RESIZE_INC)
4847 xinc = MAX (xinc, geometry->width_inc);
4848 yinc = MAX (yinc, geometry->height_inc);
4851 /* clamp width and height to min and max values
4853 width = CLAMP (width, min_width, max_width);
4854 height = CLAMP (height, min_height, max_height);
4856 /* shrink to base + N * inc
4858 width = base_width + FLOOR (width - base_width, xinc);
4859 height = base_height + FLOOR (height - base_height, yinc);
4861 /* constrain aspect ratio, according to:
4864 * min_aspect <= -------- <= max_aspect
4868 if (flags & GDK_HINT_ASPECT &&
4869 geometry->min_aspect > 0 &&
4870 geometry->max_aspect > 0)
4874 if (geometry->min_aspect * height > width)
4876 delta = FLOOR (height - width / geometry->min_aspect, yinc);
4877 if (height - delta >= min_height)
4881 delta = FLOOR (height * geometry->min_aspect - width, xinc);
4882 if (width + delta <= max_width)
4887 if (geometry->max_aspect * height < width)
4889 delta = FLOOR (width - height * geometry->max_aspect, xinc);
4890 if (width - delta >= min_width)
4894 delta = FLOOR (width / geometry->max_aspect - height, yinc);
4895 if (height + delta <= max_height)
4904 *new_height = height;
4908 * gdk_window_get_pointer:
4909 * @window: a #GdkWindow
4910 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
4911 * return the X coordinate
4912 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
4913 * return the Y coordinate
4914 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
4917 * Obtains the current pointer position and modifier state.
4918 * The position is given in coordinates relative to the upper left
4919 * corner of @window.
4921 * Return value: (transfer none): the window containing the pointer (as with
4922 * gdk_window_at_pointer()), or %NULL if the window containing the
4923 * pointer isn't known to GDK
4925 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
4928 gdk_window_get_pointer (GdkWindow *window,
4931 GdkModifierType *mask)
4933 GdkDisplay *display;
4935 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4937 display = gdk_window_get_display (window);
4939 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
4943 * gdk_window_get_device_position:
4944 * @window: a #GdkWindow.
4945 * @device: #GdkDevice to query to.
4946 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
4947 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
4948 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
4950 * Obtains the current device position and modifier state.
4951 * The position is given in coordinates relative to the upper left
4952 * corner of @window.
4954 * Return value: (transfer none): The window underneath @device (as with
4955 * gdk_display_get_window_at_device_position()), or %NULL if the
4956 * window is not known to GDK.
4961 gdk_window_get_device_position (GdkWindow *window,
4965 GdkModifierType *mask)
4967 GdkDisplay *display;
4969 GdkModifierType tmp_mask;
4972 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4973 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
4978 display = gdk_window_get_display (window);
4979 child = display->device_hooks->window_get_device_position (display, device, window,
4980 &tmp_x, &tmp_y, &tmp_mask);
4989 _gdk_display_enable_motion_hints (display, device);
4995 * gdk_window_at_pointer:
4996 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
4997 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
4999 * Obtains the window underneath the mouse pointer, returning the
5000 * location of that window in @win_x, @win_y. Returns %NULL if the
5001 * window under the mouse pointer is not known to GDK (if the window
5002 * belongs to another application and a #GdkWindow hasn't been created
5003 * for it with gdk_window_foreign_new())
5005 * NOTE: For multihead-aware widgets or applications use
5006 * gdk_display_get_window_at_pointer() instead.
5008 * Return value: (transfer none): window under the mouse pointer
5010 * Deprecated: 3.0: Use gdk_display_get_window_at_device_position() instead.
5013 gdk_window_at_pointer (gint *win_x,
5016 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
5020 * gdk_get_default_root_window:
5022 * Obtains the root window (parent all other windows are inside)
5023 * for the default display and screen.
5025 * Return value: (transfer none): the default root window
5028 gdk_get_default_root_window (void)
5030 return gdk_screen_get_root_window (gdk_screen_get_default ());
5034 * gdk_window_foreign_new:
5035 * @anid: a native window handle.
5037 * Wraps a native window for the default display in a #GdkWindow.
5038 * This may fail if the window has been destroyed.
5040 * For example in the X backend, a native window handle is an Xlib
5043 * Return value: (transfer full): the newly-created #GdkWindow wrapper
5044 * for the native window, or %NULL if the window has been destroyed.
5047 gdk_window_foreign_new (GdkNativeWindow anid)
5049 return gdk_window_foreign_new_for_display (gdk_display_get_default (), anid);
5053 get_all_native_children (GdkWindow *window,
5059 for (l = window->children; l != NULL; l = l->next)
5063 if (gdk_window_has_impl (child))
5064 *native = g_list_prepend (*native, child);
5066 get_all_native_children (child, native);
5072 gdk_window_raise_internal (GdkWindow *window)
5074 GdkWindow *parent = window->parent;
5076 GList *native_children;
5078 GdkWindowImplClass *impl_class;
5082 parent->children = g_list_remove (parent->children, window);
5083 parent->children = g_list_prepend (parent->children, window);
5086 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5087 /* Just do native raise for toplevels */
5088 if (gdk_window_is_toplevel (window) ||
5089 /* The restack_under codepath should work correctly even if the parent
5090 is native, but it relies on the order of ->children to be correct,
5091 and some apps like SWT reorder the x windows without gdks knowledge,
5092 so we use raise directly in order to make these behave as before
5093 when using native windows */
5094 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5096 impl_class->raise (window);
5098 else if (gdk_window_has_impl (window))
5100 above = find_native_sibling_above (parent, window);
5103 listhead.data = window;
5104 listhead.next = NULL;
5105 listhead.prev = NULL;
5106 impl_class->restack_under ((GdkWindow *)above,
5110 impl_class->raise (window);
5114 native_children = NULL;
5115 get_all_native_children (window, &native_children);
5116 if (native_children != NULL)
5118 above = find_native_sibling_above (parent, window);
5121 impl_class->restack_under (above, native_children);
5124 /* Right order, since native_children is bottom-topmost first */
5125 for (l = native_children; l != NULL; l = l->next)
5126 impl_class->raise (l->data);
5129 g_list_free (native_children);
5135 /* Returns TRUE If the native window was mapped or unmapped */
5137 set_viewable (GdkWindow *w,
5141 GdkWindowImplClass *impl_class;
5144 if (w->viewable == val)
5150 recompute_visible_regions (w, FALSE, FALSE);
5152 for (l = w->children; l != NULL; l = l->next)
5156 if (GDK_WINDOW_IS_MAPPED (child) &&
5157 child->window_type != GDK_WINDOW_FOREIGN)
5158 set_viewable (child, val);
5161 if (!_gdk_native_windows &&
5162 gdk_window_has_impl (w) &&
5163 w->window_type != GDK_WINDOW_FOREIGN &&
5164 !gdk_window_is_toplevel (w))
5166 /* For most native windows we show/hide them not when they are
5167 * mapped/unmapped, because that may not produce the correct results.
5168 * For instance, if a native window have a non-native parent which is
5169 * hidden, but its native parent is viewable then showing the window
5170 * would make it viewable to X but its not viewable wrt the non-native
5171 * hierarchy. In order to handle this we track the gdk side viewability
5172 * and only map really viewable windows.
5174 * There are two exceptions though:
5176 * For foreign windows we don't want ever change the mapped state
5177 * except when explicitly done via gdk_window_show/hide, as this may
5178 * cause problems for client owning the foreign window when its window
5179 * is suddenly mapped or unmapped.
5181 * For toplevel windows embedded in a foreign window (e.g. a plug)
5182 * we sometimes synthesize a map of a window, but the native
5183 * window is really shown by the embedder, so we don't want to
5184 * do the show ourselves. We can't really tell this case from the normal
5185 * toplevel show as such toplevels are seen by gdk as parents of the
5186 * root window, so we make an exception for all toplevels.
5188 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
5189 * like this, so we just always show/hide directly.
5192 impl_class = GDK_WINDOW_IMPL_GET_CLASS (w->impl);
5194 impl_class->show ((GdkWindow *)w, FALSE);
5196 impl_class->hide ((GdkWindow *)w);
5204 /* Returns TRUE If the native window was mapped or unmapped */
5206 _gdk_window_update_viewable (GdkWindow *window)
5210 if (window->window_type == GDK_WINDOW_FOREIGN ||
5211 window->window_type == GDK_WINDOW_ROOT)
5213 else if (gdk_window_is_toplevel (window) ||
5214 window->parent->viewable)
5215 viewable = GDK_WINDOW_IS_MAPPED (window);
5219 return set_viewable (window, viewable);
5223 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5225 GdkWindowImplClass *impl_class;
5226 gboolean was_mapped, was_viewable;
5229 g_return_if_fail (GDK_IS_WINDOW (window));
5231 if (window->destroyed)
5234 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5235 was_viewable = window->viewable;
5238 /* Keep children in (reverse) stacking order */
5239 gdk_window_raise_internal (window);
5241 if (gdk_window_has_impl (window))
5244 gdk_synthesize_window_state (window,
5245 GDK_WINDOW_STATE_WITHDRAWN,
5253 did_show = _gdk_window_update_viewable (window);
5255 /* If it was already viewable the backend show op won't be called, call it
5256 again to ensure things happen right if the mapped tracking was not right
5257 for e.g. a foreign window.
5258 Dunno if this is strictly needed but its what happened pre-csw.
5259 Also show if not done by gdk_window_update_viewable. */
5260 if (gdk_window_has_impl (window) && (was_viewable || !did_show))
5262 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5263 impl_class->show (window, !did_show ? was_mapped : TRUE);
5266 if (!was_mapped && !gdk_window_has_impl (window))
5268 if (window->event_mask & GDK_STRUCTURE_MASK)
5269 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5271 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5272 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5275 if (!was_mapped || raise)
5277 recompute_visible_regions (window, TRUE, FALSE);
5279 /* If any decendants became visible we need to send visibility notify */
5280 gdk_window_update_visibility_recursively (window, NULL);
5282 if (gdk_window_is_viewable (window))
5284 _gdk_synthesize_crossing_events_for_geometry_change (window);
5285 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5291 * gdk_window_show_unraised:
5292 * @window: a #GdkWindow
5294 * Shows a #GdkWindow onscreen, but does not modify its stacking
5295 * order. In contrast, gdk_window_show() will raise the window
5296 * to the top of the window stack.
5298 * On the X11 platform, in Xlib terms, this function calls
5299 * XMapWindow() (it also updates some internal GDK state, which means
5300 * that you can't really use XMapWindow() directly on a GDK window).
5303 gdk_window_show_unraised (GdkWindow *window)
5305 gdk_window_show_internal (window, FALSE);
5310 * @window: a #GdkWindow
5312 * Raises @window to the top of the Z-order (stacking order), so that
5313 * other windows with the same parent window appear below @window.
5314 * This is true whether or not the windows are visible.
5316 * If @window is a toplevel, the window manager may choose to deny the
5317 * request to move the window in the Z-order, gdk_window_raise() only
5318 * requests the restack, does not guarantee it.
5321 gdk_window_raise (GdkWindow *window)
5323 cairo_region_t *old_region, *new_region;
5325 g_return_if_fail (GDK_IS_WINDOW (window));
5327 if (window->destroyed)
5330 gdk_window_flush_if_exposing (window);
5333 if (gdk_window_is_viewable (window) &&
5334 !window->input_only)
5335 old_region = cairo_region_copy (window->clip_region);
5337 /* Keep children in (reverse) stacking order */
5338 gdk_window_raise_internal (window);
5340 recompute_visible_regions (window, TRUE, FALSE);
5344 new_region = cairo_region_copy (window->clip_region);
5346 cairo_region_subtract (new_region, old_region);
5347 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5349 cairo_region_destroy (old_region);
5350 cairo_region_destroy (new_region);
5355 gdk_window_lower_internal (GdkWindow *window)
5357 GdkWindow *parent = window->parent;
5358 GdkWindowImplClass *impl_class;
5360 GList *native_children;
5365 parent->children = g_list_remove (parent->children, window);
5366 parent->children = g_list_append (parent->children, window);
5369 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5370 /* Just do native lower for toplevels */
5371 if (gdk_window_is_toplevel (window) ||
5372 /* The restack_under codepath should work correctly even if the parent
5373 is native, but it relies on the order of ->children to be correct,
5374 and some apps like SWT reorder the x windows without gdks knowledge,
5375 so we use lower directly in order to make these behave as before
5376 when using native windows */
5377 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5379 impl_class->lower (window);
5381 else if (gdk_window_has_impl (window))
5383 above = find_native_sibling_above (parent, window);
5386 listhead.data = window;
5387 listhead.next = NULL;
5388 listhead.prev = NULL;
5389 impl_class->restack_under ((GdkWindow *)above, &listhead);
5392 impl_class->raise (window);
5396 native_children = NULL;
5397 get_all_native_children (window, &native_children);
5398 if (native_children != NULL)
5400 above = find_native_sibling_above (parent, window);
5403 impl_class->restack_under ((GdkWindow *)above,
5407 /* Right order, since native_children is bottom-topmost first */
5408 for (l = native_children; l != NULL; l = l->next)
5409 impl_class->raise (l->data);
5412 g_list_free (native_children);
5419 gdk_window_invalidate_in_parent (GdkWindow *private)
5421 GdkRectangle r, child;
5423 if (gdk_window_is_toplevel (private))
5426 /* get the visible rectangle of the parent */
5428 r.width = private->parent->width;
5429 r.height = private->parent->height;
5431 child.x = private->x;
5432 child.y = private->y;
5433 child.width = private->width;
5434 child.height = private->height;
5435 gdk_rectangle_intersect (&r, &child, &r);
5437 gdk_window_invalidate_rect_full (private->parent, &r, TRUE, CLEAR_BG_ALL);
5443 * @window: a #GdkWindow
5445 * Lowers @window to the bottom of the Z-order (stacking order), so that
5446 * other windows with the same parent window appear above @window.
5447 * This is true whether or not the other windows are visible.
5449 * If @window is a toplevel, the window manager may choose to deny the
5450 * request to move the window in the Z-order, gdk_window_lower() only
5451 * requests the restack, does not guarantee it.
5453 * Note that gdk_window_show() raises the window again, so don't call this
5454 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5457 gdk_window_lower (GdkWindow *window)
5459 g_return_if_fail (GDK_IS_WINDOW (window));
5461 if (window->destroyed)
5464 gdk_window_flush_if_exposing (window);
5466 /* Keep children in (reverse) stacking order */
5467 gdk_window_lower_internal (window);
5469 recompute_visible_regions (window, TRUE, FALSE);
5471 _gdk_synthesize_crossing_events_for_geometry_change (window);
5472 gdk_window_invalidate_in_parent (window);
5476 * gdk_window_restack:
5477 * @window: a #GdkWindow
5478 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5481 * Changes the position of @window in the Z-order (stacking order), so that
5482 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5485 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5486 * lowers the window.
5488 * If @window is a toplevel, the window manager may choose to deny the
5489 * request to move the window in the Z-order, gdk_window_restack() only
5490 * requests the restack, does not guarantee it.
5495 gdk_window_restack (GdkWindow *window,
5499 GdkWindowImplClass *impl_class;
5501 GdkWindow *above_native;
5502 GList *sibling_link;
5503 GList *native_children;
5506 g_return_if_fail (GDK_IS_WINDOW (window));
5507 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5509 if (window->destroyed)
5512 if (sibling == NULL)
5515 gdk_window_raise (window);
5517 gdk_window_lower (window);
5521 gdk_window_flush_if_exposing (window);
5523 if (gdk_window_is_toplevel (window))
5525 g_return_if_fail (gdk_window_is_toplevel (sibling));
5526 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5527 impl_class->restack_toplevel (window, sibling, above);
5531 parent = window->parent;
5534 sibling_link = g_list_find (parent->children, sibling);
5535 g_return_if_fail (sibling_link != NULL);
5536 if (sibling_link == NULL)
5539 parent->children = g_list_remove (parent->children, window);
5541 parent->children = g_list_insert_before (parent->children,
5545 parent->children = g_list_insert_before (parent->children,
5549 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5550 if (gdk_window_has_impl (window))
5552 above_native = find_native_sibling_above (parent, window);
5555 listhead.data = window;
5556 listhead.next = NULL;
5557 listhead.prev = NULL;
5558 impl_class->restack_under (above_native, &listhead);
5561 impl_class->raise (window);
5565 native_children = NULL;
5566 get_all_native_children (window, &native_children);
5567 if (native_children != NULL)
5569 above_native = find_native_sibling_above (parent, window);
5571 impl_class->restack_under (above_native,
5575 /* Right order, since native_children is bottom-topmost first */
5576 for (l = native_children; l != NULL; l = l->next)
5577 impl_class->raise (l->data);
5580 g_list_free (native_children);
5585 recompute_visible_regions (window, TRUE, FALSE);
5587 _gdk_synthesize_crossing_events_for_geometry_change (window);
5588 gdk_window_invalidate_in_parent (window);
5594 * @window: a #GdkWindow
5596 * Like gdk_window_show_unraised(), but also raises the window to the
5597 * top of the window stack (moves the window to the front of the
5600 * This function maps a window so it's visible onscreen. Its opposite
5601 * is gdk_window_hide().
5603 * When implementing a #GtkWidget, you should call this function on the widget's
5604 * #GdkWindow as part of the "map" method.
5607 gdk_window_show (GdkWindow *window)
5609 gdk_window_show_internal (window, TRUE);
5614 * @window: a #GdkWindow
5616 * For toplevel windows, withdraws them, so they will no longer be
5617 * known to the window manager; for all windows, unmaps them, so
5618 * they won't be displayed. Normally done automatically as
5619 * part of gtk_widget_hide().
5622 gdk_window_hide (GdkWindow *window)
5624 GdkWindowImplClass *impl_class;
5625 gboolean was_mapped, did_hide;
5627 g_return_if_fail (GDK_IS_WINDOW (window));
5629 if (window->destroyed)
5632 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5634 if (gdk_window_has_impl (window))
5637 if (GDK_WINDOW_IS_MAPPED (window))
5638 gdk_synthesize_window_state (window,
5640 GDK_WINDOW_STATE_WITHDRAWN);
5642 else if (was_mapped)
5644 GdkDisplay *display;
5645 GdkDeviceManager *device_manager;
5648 /* May need to break grabs on children */
5649 display = gdk_window_get_display (window);
5650 device_manager = gdk_display_get_device_manager (display);
5652 /* Get all devices */
5653 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5654 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5655 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5657 for (d = devices; d; d = d->next)
5659 GdkDevice *device = d->data;
5661 if (_gdk_display_end_device_grab (display, device,
5662 _gdk_windowing_window_get_next_serial (display),
5665 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5668 window->state = GDK_WINDOW_STATE_WITHDRAWN;
5669 g_list_free (devices);
5672 did_hide = _gdk_window_update_viewable (window);
5674 /* Hide foreign window as those are not handled by update_viewable. */
5675 if (gdk_window_has_impl (window) && (!did_hide))
5677 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5678 impl_class->hide (window);
5681 recompute_visible_regions (window, TRUE, FALSE);
5683 /* all decendants became non-visible, we need to send visibility notify */
5684 gdk_window_update_visibility_recursively (window, NULL);
5686 if (was_mapped && !gdk_window_has_impl (window))
5688 if (window->event_mask & GDK_STRUCTURE_MASK)
5689 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5691 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5692 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5694 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5697 /* Invalidate the rect */
5699 gdk_window_invalidate_in_parent (window);
5703 * gdk_window_withdraw:
5704 * @window: a toplevel #GdkWindow
5706 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5707 * This function is not really useful as gdk_window_hide() automatically
5708 * withdraws toplevel windows before hiding them.
5711 gdk_window_withdraw (GdkWindow *window)
5713 GdkWindowImplClass *impl_class;
5714 gboolean was_mapped;
5716 g_return_if_fail (GDK_IS_WINDOW (window));
5718 if (window->destroyed)
5721 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5723 if (gdk_window_has_impl (window))
5725 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5726 impl_class->withdraw (window);
5730 if (window->event_mask & GDK_STRUCTURE_MASK)
5731 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5733 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5734 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5736 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5739 recompute_visible_regions (window, TRUE, FALSE);
5744 * gdk_window_set_events:
5745 * @window: a #GdkWindow
5746 * @event_mask: event mask for @window
5748 * The event mask for a window determines which events will be reported
5749 * for that window from all master input devices. For example, an event mask
5750 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5751 * press events. The event mask is the bitwise OR of values from the
5752 * #GdkEventMask enumeration.
5755 gdk_window_set_events (GdkWindow *window,
5756 GdkEventMask event_mask)
5758 GdkWindowImplClass *impl_class;
5759 GdkDisplay *display;
5761 g_return_if_fail (GDK_IS_WINDOW (window));
5763 if (window->destroyed)
5766 /* If motion hint is disabled, enable motion events again */
5767 display = gdk_window_get_display (window);
5768 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5769 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5771 GList *devices = window->devices_inside;
5775 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5776 devices = devices->next;
5780 window->event_mask = event_mask;
5782 if (gdk_window_has_impl (window))
5784 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5785 impl_class->set_events (window,
5786 get_native_event_mask (window));
5792 * gdk_window_get_events:
5793 * @window: a #GdkWindow
5795 * Gets the event mask for @window for all master input devices. See
5796 * gdk_window_set_events().
5798 * Return value: event mask for @window
5801 gdk_window_get_events (GdkWindow *window)
5803 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5805 if (window->destroyed)
5808 return window->event_mask;
5812 * gdk_window_set_device_events:
5813 * @window: a #GdkWindow
5814 * @device: #GdkDevice to enable events for.
5815 * @event_mask: event mask for @window
5817 * Sets the event mask for a given device (Normally a floating device, not
5818 * attached to any visible pointer) to @window. For example, an event mask
5819 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5820 * press events. The event mask is the bitwise OR of values from the
5821 * #GdkEventMask enumeration.
5826 gdk_window_set_device_events (GdkWindow *window,
5828 GdkEventMask event_mask)
5830 GdkEventMask device_mask;
5831 GdkDisplay *display;
5834 g_return_if_fail (GDK_IS_WINDOW (window));
5835 g_return_if_fail (GDK_IS_DEVICE (device));
5837 if (GDK_WINDOW_DESTROYED (window))
5840 /* If motion hint is disabled, enable motion events again */
5841 display = gdk_window_get_display (window);
5842 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5843 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5844 _gdk_display_enable_motion_hints (display, device);
5846 if (G_UNLIKELY (!window->device_events))
5847 window->device_events = g_hash_table_new (NULL, NULL);
5849 if (event_mask == 0)
5851 /* FIXME: unsetting events on a master device
5852 * would restore window->event_mask
5854 g_hash_table_remove (window->device_events, device);
5857 g_hash_table_insert (window->device_events, device,
5858 GINT_TO_POINTER (event_mask));
5860 if (_gdk_native_windows)
5863 native = gdk_window_get_toplevel (window);
5865 while (gdk_window_is_offscreen (native))
5867 native = gdk_offscreen_window_get_embedder (native);
5869 if (native == NULL ||
5870 (!_gdk_window_has_impl (native) &&
5871 !gdk_window_is_viewable (native)))
5874 native = gdk_window_get_toplevel (native);
5877 device_mask = get_native_device_event_mask (window, device);
5878 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
5882 * gdk_window_get_device_events:
5883 * @window: a #GdkWindow.
5884 * @device: a #GdkDevice.
5886 * Returns the event mask for @window corresponding to an specific device.
5888 * Returns: device event mask for @window
5893 gdk_window_get_device_events (GdkWindow *window,
5898 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5899 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
5901 if (GDK_WINDOW_DESTROYED (window))
5904 if (!window->device_events)
5907 mask = GPOINTER_TO_INT (g_hash_table_lookup (window->device_events, device));
5909 /* FIXME: device could be controlled by window->event_mask */
5915 gdk_window_move_resize_toplevel (GdkWindow *window,
5922 cairo_region_t *old_region, *new_region;
5923 GdkWindowImplClass *impl_class;
5925 int old_x, old_y, old_abs_x, old_abs_y;
5935 is_resize = (width != -1) || (height != -1);
5937 if (gdk_window_is_viewable (window) &&
5938 !window->input_only)
5941 old_region = cairo_region_copy (window->clip_region);
5944 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5945 impl_class->move_resize (window, with_move, x, y, width, height);
5947 dx = window->x - old_x;
5948 dy = window->y - old_y;
5950 old_abs_x = window->abs_x;
5951 old_abs_y = window->abs_y;
5953 /* Avoid recomputing for pure toplevel moves, for performance reasons */
5955 recompute_visible_regions (window, TRUE, FALSE);
5959 new_region = cairo_region_copy (window->clip_region);
5961 /* This is the newly exposed area (due to any resize),
5962 * X will expose it, but lets do that without the
5965 cairo_region_subtract (new_region, old_region);
5966 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
5968 cairo_region_destroy (old_region);
5969 cairo_region_destroy (new_region);
5972 _gdk_synthesize_crossing_events_for_geometry_change (window);
5977 move_native_children (GdkWindow *private)
5981 GdkWindowImplClass *impl_class;
5983 for (l = private->children; l; l = l->next)
5987 if (child->impl != private->impl)
5989 impl_class = GDK_WINDOW_IMPL_GET_CLASS (child->impl);
5990 impl_class->move_resize (child, TRUE,
5992 child->width, child->height);
5995 move_native_children (child);
6000 collect_native_child_region_helper (GdkWindow *window,
6001 GdkWindowImpl *impl,
6002 cairo_region_t **region,
6007 cairo_region_t *tmp;
6010 for (l = window->children; l != NULL; l = l->next)
6014 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
6017 if (child->impl != impl)
6019 tmp = cairo_region_copy (child->clip_region);
6020 cairo_region_translate (tmp,
6021 x_offset + child->x,
6022 y_offset + child->y);
6023 if (*region == NULL)
6027 cairo_region_union (*region, tmp);
6028 cairo_region_destroy (tmp);
6032 collect_native_child_region_helper (child, impl, region,
6033 x_offset + child->x,
6034 y_offset + child->y);
6040 static cairo_region_t *
6041 collect_native_child_region (GdkWindow *window,
6042 gboolean include_this)
6044 cairo_region_t *region;
6046 if (include_this && gdk_window_has_impl (window) && window->viewable)
6047 return cairo_region_copy (window->clip_region);
6051 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6058 gdk_window_move_resize_internal (GdkWindow *window,
6065 cairo_region_t *old_region, *new_region, *copy_area;
6066 cairo_region_t *old_native_child_region, *new_native_child_region;
6067 GdkWindow *impl_window;
6068 GdkWindowImplClass *impl_class;
6070 int old_x, old_y, old_abs_x, old_abs_y;
6073 g_return_if_fail (GDK_IS_WINDOW (window));
6075 if (window->destroyed)
6078 if (gdk_window_is_toplevel (window))
6080 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6084 /* Bail early if no change */
6085 if (window->width == width &&
6086 window->height == height &&
6092 gdk_window_flush_if_exposing (window);
6094 /* Handle child windows */
6099 impl_window = gdk_window_get_impl_window (window);
6104 old_native_child_region = NULL;
6105 if (gdk_window_is_viewable (window) &&
6106 !window->input_only)
6110 old_region = cairo_region_copy (window->clip_region);
6111 /* Adjust region to parent window coords */
6112 cairo_region_translate (old_region, window->x, window->y);
6114 old_native_child_region = collect_native_child_region (window, TRUE);
6115 if (old_native_child_region)
6117 /* Adjust region to parent window coords */
6118 cairo_region_translate (old_native_child_region, window->x, window->y);
6120 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6121 * source or destination for a delayed GdkWindowRegionMove. So, we need
6122 * to flush those here for the parent window and all overlapped subwindows
6123 * of it. And we need to do this before setting the new clips as those will be
6126 gdk_window_flush_recursive (window->parent);
6130 /* Set the new position and size */
6136 if (!(width < 0 && height < 0))
6140 window->width = width;
6143 window->height = height;
6146 dx = window->x - old_x;
6147 dy = window->y - old_y;
6149 old_abs_x = window->abs_x;
6150 old_abs_y = window->abs_y;
6152 recompute_visible_regions (window, TRUE, FALSE);
6154 new_native_child_region = NULL;
6155 if (old_native_child_region)
6157 new_native_child_region = collect_native_child_region (window, TRUE);
6158 /* Adjust region to parent window coords */
6159 cairo_region_translate (new_native_child_region, window->x, window->y);
6162 if (gdk_window_has_impl (window))
6164 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6166 /* Do the actual move after recomputing things, as this will have set the shape to
6167 the now correct one, thus avoiding copying regions that should not be copied. */
6168 impl_class->move_resize (window, TRUE,
6169 window->x, window->y,
6170 window->width, window->height);
6172 else if (old_abs_x != window->abs_x ||
6173 old_abs_y != window->abs_y)
6174 move_native_children (window);
6178 new_region = cairo_region_copy (window->clip_region);
6179 /* Adjust region to parent window coords */
6180 cairo_region_translate (new_region, window->x, window->y);
6183 * Part of the data at the new location can be copied from the
6184 * old location, this area is the intersection of the old region
6185 * moved as the copy will move it and then intersected with
6189 * Everything in the old and new regions that is not copied must be
6190 * invalidated (including children) as this is newly exposed
6192 copy_area = cairo_region_copy (new_region);
6194 cairo_region_union (new_region, old_region);
6196 if (old_native_child_region)
6198 /* Don't copy from inside native children, as this is copied by
6199 * the native window move.
6201 cairo_region_subtract (old_region, old_native_child_region);
6203 cairo_region_translate (old_region, dx, dy);
6205 cairo_region_intersect (copy_area, old_region);
6207 if (new_native_child_region)
6209 /* Don't copy any bits that would cause a read from the moved
6210 native windows, as we can't read that data */
6211 cairo_region_translate (new_native_child_region, dx, dy);
6212 cairo_region_subtract (copy_area, new_native_child_region);
6213 cairo_region_translate (new_native_child_region, -dx, -dy);
6216 cairo_region_subtract (new_region, copy_area);
6218 /* Convert old region to impl coords */
6219 cairo_region_translate (old_region, -dx + window->abs_x - window->x, -dy + window->abs_y - window->y);
6221 /* convert from parent coords to impl */
6222 cairo_region_translate (copy_area, window->abs_x - window->x, window->abs_y - window->y);
6224 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6226 /* Invalidate affected part in the parent window
6227 * (no higher window should be affected)
6228 * We also invalidate any children in that area, which could include
6229 * this window if it still overlaps that area.
6231 if (old_native_child_region)
6233 /* No need to expose the region that the native window move copies */
6234 cairo_region_translate (old_native_child_region, dx, dy);
6235 cairo_region_intersect (old_native_child_region, new_native_child_region);
6236 cairo_region_subtract (new_region, old_native_child_region);
6238 gdk_window_invalidate_region_full (window->parent, new_region, TRUE, CLEAR_BG_ALL);
6240 cairo_region_destroy (old_region);
6241 cairo_region_destroy (new_region);
6244 if (old_native_child_region)
6246 cairo_region_destroy (old_native_child_region);
6247 cairo_region_destroy (new_native_child_region);
6250 _gdk_synthesize_crossing_events_for_geometry_change (window);
6257 * @window: a #GdkWindow
6258 * @x: X coordinate relative to window's parent
6259 * @y: Y coordinate relative to window's parent
6261 * Repositions a window relative to its parent window.
6262 * For toplevel windows, window managers may ignore or modify the move;
6263 * you should probably use gtk_window_move() on a #GtkWindow widget
6264 * anyway, instead of using GDK functions. For child windows,
6265 * the move will reliably succeed.
6267 * If you're also planning to resize the window, use gdk_window_move_resize()
6268 * to both move and resize simultaneously, for a nicer visual effect.
6271 gdk_window_move (GdkWindow *window,
6275 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6279 * gdk_window_resize:
6280 * @window: a #GdkWindow
6281 * @width: new width of the window
6282 * @height: new height of the window
6284 * Resizes @window; for toplevel windows, asks the window manager to resize
6285 * the window. The window manager may not allow the resize. When using GTK+,
6286 * use gtk_window_resize() instead of this low-level GDK function.
6288 * Windows may not be resized below 1x1.
6290 * If you're also planning to move the window, use gdk_window_move_resize()
6291 * to both move and resize simultaneously, for a nicer visual effect.
6294 gdk_window_resize (GdkWindow *window,
6298 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6303 * gdk_window_move_resize:
6304 * @window: a #GdkWindow
6305 * @x: new X position relative to window's parent
6306 * @y: new Y position relative to window's parent
6308 * @height: new height
6310 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6311 * except that both operations are performed at once, avoiding strange
6312 * visual effects. (i.e. the user may be able to see the window first
6313 * move, then resize, if you don't use gdk_window_move_resize().)
6316 gdk_window_move_resize (GdkWindow *window,
6322 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6327 * gdk_window_scroll:
6328 * @window: a #GdkWindow
6329 * @dx: Amount to scroll in the X direction
6330 * @dy: Amount to scroll in the Y direction
6332 * Scroll the contents of @window, both pixels and children, by the
6333 * given amount. @window itself does not move. Portions of the window
6334 * that the scroll operation brings in from offscreen areas are
6335 * invalidated. The invalidated region may be bigger than what would
6336 * strictly be necessary.
6338 * For X11, a minimum area will be invalidated if the window has no
6339 * subwindows, or if the edges of the window's parent do not extend
6340 * beyond the edges of the window. In other cases, a multi-step process
6341 * is used to scroll the window which may produce temporary visual
6342 * artifacts and unnecessary invalidations.
6345 gdk_window_scroll (GdkWindow *window,
6349 GdkWindow *impl_window;
6350 cairo_region_t *copy_area, *noncopy_area;
6351 cairo_region_t *old_native_child_region, *new_native_child_region;
6354 g_return_if_fail (GDK_IS_WINDOW (window));
6356 if (dx == 0 && dy == 0)
6359 if (window->destroyed)
6362 gdk_window_flush_if_exposing (window);
6364 old_native_child_region = collect_native_child_region (window, FALSE);
6365 if (old_native_child_region)
6367 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6368 * source or destination for a delayed GdkWindowRegionMove. So, we need
6369 * to flush those here for the window and all overlapped subwindows
6370 * of it. And we need to do this before setting the new clips as those will be
6373 gdk_window_flush_recursive (window);
6377 /* First move all child windows, without causing invalidation */
6379 tmp_list = window->children;
6382 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6384 /* Just update the positions, the bits will move with the copy */
6388 tmp_list = tmp_list->next;
6391 recompute_visible_regions (window, FALSE, TRUE);
6393 new_native_child_region = NULL;
6394 if (old_native_child_region)
6395 new_native_child_region = collect_native_child_region (window, FALSE);
6397 move_native_children (window);
6399 /* Then copy the actual bits of the window w/ child windows */
6401 impl_window = gdk_window_get_impl_window (window);
6403 /* Calculate the area that can be gotten by copying the old area */
6404 copy_area = cairo_region_copy (window->clip_region);
6405 if (old_native_child_region)
6407 /* Don't copy from inside native children, as this is copied by
6408 * the native window move.
6410 cairo_region_subtract (copy_area, old_native_child_region);
6412 /* Don't copy any bits that would cause a read from the moved
6413 native windows, as we can't read that data */
6414 cairo_region_subtract (copy_area, new_native_child_region);
6416 cairo_region_translate (copy_area, dx, dy);
6417 cairo_region_intersect (copy_area, window->clip_region);
6419 /* And the rest need to be invalidated */
6420 noncopy_area = cairo_region_copy (window->clip_region);
6421 cairo_region_subtract (noncopy_area, copy_area);
6423 /* convert from window coords to impl */
6424 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6426 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6428 /* Invalidate not copied regions */
6429 if (old_native_child_region)
6431 /* No need to expose the region that the native window move copies */
6432 cairo_region_translate (old_native_child_region, dx, dy);
6433 cairo_region_intersect (old_native_child_region, new_native_child_region);
6434 cairo_region_subtract (noncopy_area, old_native_child_region);
6436 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6438 cairo_region_destroy (noncopy_area);
6440 if (old_native_child_region)
6442 cairo_region_destroy (old_native_child_region);
6443 cairo_region_destroy (new_native_child_region);
6446 _gdk_synthesize_crossing_events_for_geometry_change (window);
6450 * gdk_window_move_region:
6451 * @window: a #GdkWindow
6452 * @region: The #cairo_region_t to move
6453 * @dx: Amount to move in the X direction
6454 * @dy: Amount to move in the Y direction
6456 * Move the part of @window indicated by @region by @dy pixels in the Y
6457 * direction and @dx pixels in the X direction. The portions of @region
6458 * that not covered by the new position of @region are invalidated.
6460 * Child windows are not moved.
6465 gdk_window_move_region (GdkWindow *window,
6466 const cairo_region_t *region,
6470 GdkWindow *impl_window;
6471 cairo_region_t *nocopy_area;
6472 cairo_region_t *copy_area;
6474 g_return_if_fail (GDK_IS_WINDOW (window));
6475 g_return_if_fail (region != NULL);
6477 if (dx == 0 && dy == 0)
6480 if (window->destroyed)
6483 impl_window = gdk_window_get_impl_window (window);
6485 /* compute source regions */
6486 copy_area = cairo_region_copy (region);
6487 cairo_region_intersect (copy_area, window->clip_region_with_children);
6489 /* compute destination regions */
6490 cairo_region_translate (copy_area, dx, dy);
6491 cairo_region_intersect (copy_area, window->clip_region_with_children);
6493 /* Invalidate parts of the region (source and dest) not covered
6495 nocopy_area = cairo_region_copy (region);
6496 cairo_region_translate (nocopy_area, dx, dy);
6497 cairo_region_union (nocopy_area, region);
6498 cairo_region_subtract (nocopy_area, copy_area);
6500 /* convert from window coords to impl */
6501 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6502 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6504 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6505 cairo_region_destroy (nocopy_area);
6509 * gdk_window_set_background:
6510 * @window: a #GdkWindow
6511 * @color: a #GdkColor
6513 * Sets the background color of @window. (However, when using GTK+,
6514 * set the background of a widget with gtk_widget_modify_bg() - if
6515 * you're an application - or gtk_style_set_background() - if you're
6516 * implementing a custom widget.)
6518 * See also gdk_window_set_background_pattern().
6521 gdk_window_set_background (GdkWindow *window,
6522 const GdkColor *color)
6524 cairo_pattern_t *pattern;
6526 g_return_if_fail (GDK_IS_WINDOW (window));
6528 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6529 color->green / 65535.,
6530 color->blue / 65535.);
6532 gdk_window_set_background_pattern (window, pattern);
6534 cairo_pattern_destroy (pattern);
6538 * gdk_window_set_background_rgba:
6539 * @window: a #GdkWindow
6540 * @rgba: a #GdkRGBA color
6542 * Sets the background color of @window.
6544 * See also gdk_window_set_background_pattern().
6547 gdk_window_set_background_rgba (GdkWindow *window,
6550 cairo_pattern_t *pattern;
6552 g_return_if_fail (GDK_IS_WINDOW (window));
6553 g_return_if_fail (rgba != NULL);
6555 pattern = cairo_pattern_create_rgba (rgba->red, rgba->green,
6556 rgba->blue, rgba->alpha);
6558 gdk_window_set_background_pattern (window, pattern);
6560 cairo_pattern_destroy (pattern);
6564 * gdk_window_set_background_pattern:
6565 * @window: a #GdkWindow
6566 * @pattern: (allow-none): a pattern to use, or %NULL
6568 * Sets the background of @window.
6570 * A background of %NULL means that the window will inherit its
6571 * background form its parent window.
6573 * The windowing system will normally fill a window with its background
6574 * when the window is obscured then exposed.
6577 gdk_window_set_background_pattern (GdkWindow *window,
6578 cairo_pattern_t *pattern)
6580 g_return_if_fail (GDK_IS_WINDOW (window));
6583 cairo_pattern_reference (pattern);
6584 if (window->background)
6585 cairo_pattern_destroy (window->background);
6586 window->background = pattern;
6588 if (gdk_window_has_impl (window) &&
6589 !window->input_only)
6591 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6592 impl_class->set_background (window, pattern);
6597 * gdk_window_get_background_pattern:
6600 * Gets the pattern used to clear the background on @window. If @window
6601 * does not have its own background and reuses the parent's, %NULL is
6602 * returned and you'll have to query it yourself.
6604 * Returns: The pattern to use for the background or %NULL to use the
6605 * parent's background.
6610 gdk_window_get_background_pattern (GdkWindow *window)
6612 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6614 return window->background;
6618 update_cursor_foreach (GdkDisplay *display,
6620 GdkPointerWindowInfo *pointer_info,
6623 GdkWindow *window = user_data;
6625 if (_gdk_native_windows ||
6626 window->window_type == GDK_WINDOW_ROOT ||
6627 window->window_type == GDK_WINDOW_FOREIGN)
6628 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_device_cursor (window, device, window->cursor);
6629 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6630 update_cursor (display, device);
6634 * gdk_window_get_cursor:
6635 * @window: a #GdkWindow
6637 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6638 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6639 * there is no custom cursor set on the specified window, and it is
6640 * using the cursor for its parent window.
6642 * Return value: a #GdkCursor, or %NULL. The returned object is owned
6643 * by the #GdkWindow and should not be unreferenced directly. Use
6644 * gdk_window_set_cursor() to unset the cursor of the window
6649 gdk_window_get_cursor (GdkWindow *window)
6651 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6653 return window->cursor;
6657 * gdk_window_set_cursor:
6658 * @window: a #GdkWindow
6659 * @cursor: (allow-none): a cursor
6661 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6662 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6663 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6664 * to gdk_window_set_cursor() means that @window will use the cursor of its
6665 * parent window. Most windows should use this default.
6668 gdk_window_set_cursor (GdkWindow *window,
6671 GdkDisplay *display;
6673 g_return_if_fail (GDK_IS_WINDOW (window));
6675 display = gdk_window_get_display (window);
6679 gdk_cursor_unref (window->cursor);
6680 window->cursor = NULL;
6683 if (!GDK_WINDOW_DESTROYED (window))
6686 window->cursor = gdk_cursor_ref (cursor);
6688 _gdk_display_pointer_info_foreach (display,
6689 update_cursor_foreach,
6692 g_object_notify (G_OBJECT (window), "cursor");
6697 * gdk_window_get_device_cursor:
6698 * @window: a #GdkWindow.
6699 * @device: a #GdkDevice.
6701 * Retrieves a #GdkCursor pointer for the @device currently set on the
6702 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6703 * there is no custom cursor set on the specified window, and it is
6704 * using the cursor for its parent window.
6706 * Returns: a #GdkCursor, or %NULL. The returned object is owned
6707 * by the #GdkWindow and should not be unreferenced directly. Use
6708 * gdk_window_set_cursor() to unset the cursor of the window
6713 gdk_window_get_device_cursor (GdkWindow *window,
6716 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6717 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6719 return g_hash_table_lookup (window->device_cursor, device);
6723 * gdk_window_set_device_cursor:
6724 * @window: a #Gdkwindow
6725 * @device: a #GdkDevice
6726 * @cursor: a #GdkCursor
6728 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6729 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6730 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6731 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6732 * @window will use the cursor of its parent window. Most windows should
6738 gdk_window_set_device_cursor (GdkWindow *window,
6742 GdkDisplay *display;
6744 g_return_if_fail (GDK_IS_WINDOW (window));
6745 g_return_if_fail (GDK_IS_DEVICE (device));
6747 display = gdk_window_get_display (window);
6750 g_hash_table_remove (window->device_cursor, device);
6752 g_hash_table_replace (window->device_cursor, device, gdk_cursor_ref (cursor));
6754 if (!GDK_WINDOW_DESTROYED (window))
6756 GdkPointerWindowInfo *pointer_info;
6758 pointer_info = _gdk_display_get_pointer_info (display, device);
6760 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6761 update_cursor (display, device);
6766 * gdk_window_get_geometry:
6767 * @window: a #GdkWindow
6768 * @x: (out) (allow-none): return location for X coordinate of window (relative to its parent)
6769 * @y: (out) (allow-none): return location for Y coordinate of window (relative to its parent)
6770 * @width: (out) (allow-none): return location for width of window
6771 * @height: (out) (allow-none): return location for height of window
6773 * Any of the return location arguments to this function may be %NULL,
6774 * if you aren't interested in getting the value of that field.
6776 * The X and Y coordinates returned are relative to the parent window
6777 * of @window, which for toplevels usually means relative to the
6778 * window decorations (titlebar, etc.) rather than relative to the
6779 * root window (screen-size background window).
6781 * On the X11 platform, the geometry is obtained from the X server,
6782 * so reflects the latest position of @window; this may be out-of-sync
6783 * with the position of @window delivered in the most-recently-processed
6784 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6785 * position from the most recent configure event.
6788 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6789 * to call gdk_window_get_position(), gdk_window_get_width() and
6790 * gdk_window_get_height() instead, because it avoids the roundtrip to
6791 * the X server and because these functions support the full 32-bit
6792 * coordinate space, whereas gdk_window_get_geometry() is restricted to
6793 * the 16-bit coordinates of X11.
6797 gdk_window_get_geometry (GdkWindow *window,
6804 GdkWindowImplClass *impl_class;
6808 GDK_NOTE (MULTIHEAD,
6809 g_message ("gdk_window_get_geometry(): Window needs "
6810 "to be non-NULL to be multi head safe"));
6811 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
6814 g_return_if_fail (GDK_IS_WINDOW (window));
6816 if (!GDK_WINDOW_DESTROYED (window))
6818 if (gdk_window_has_impl (window))
6820 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6821 impl_class->get_geometry (window, x, y,
6823 /* This reports the position wrt to the native parent, we need to convert
6824 it to be relative to the client side parent */
6825 parent = window->parent;
6826 if (parent && !gdk_window_has_impl (parent))
6829 *x -= parent->abs_x;
6831 *y -= parent->abs_y;
6841 *width = window->width;
6843 *height = window->height;
6849 * gdk_window_get_width:
6850 * @window: a #GdkWindow
6852 * Returns the width of the given @window.
6854 * On the X11 platform the returned size is the size reported in the
6855 * most-recently-processed configure event, rather than the current
6856 * size on the X server.
6858 * Returns: The width of @window
6863 gdk_window_get_width (GdkWindow *window)
6865 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6867 return window->width;
6871 * gdk_window_get_height:
6872 * @window: a #GdkWindow
6874 * Returns the height of the given @window.
6876 * On the X11 platform the returned size is the size reported in the
6877 * most-recently-processed configure event, rather than the current
6878 * size on the X server.
6880 * Returns: The height of @window
6885 gdk_window_get_height (GdkWindow *window)
6887 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6889 return window->height;
6893 * gdk_window_get_origin:
6894 * @window: a #GdkWindow
6895 * @x: (out) (allow-none): return location for X coordinate
6896 * @y: (out) (allow-none): return location for Y coordinate
6898 * Obtains the position of a window in root window coordinates.
6899 * (Compare with gdk_window_get_position() and
6900 * gdk_window_get_geometry() which return the position of a window
6901 * relative to its parent window.)
6903 * Return value: not meaningful, ignore
6906 gdk_window_get_origin (GdkWindow *window,
6910 GdkWindowImplClass *impl_class;
6912 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6914 if (GDK_WINDOW_DESTROYED (window))
6923 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6924 impl_class->get_root_coords (window,
6933 * gdk_window_get_root_coords:
6934 * @window: a #GdkWindow
6935 * @x: X coordinate in window
6936 * @y: Y coordinate in window
6937 * @root_x: return location for X coordinate
6938 * @root_y: return location for Y coordinate
6940 * Obtains the position of a window position in root
6941 * window coordinates. This is similar to
6942 * gdk_window_get_origin() but allows you go pass
6943 * in any position in the window, not just the origin.
6948 gdk_window_get_root_coords (GdkWindow *window,
6954 GdkWindowImplClass *impl_class;
6956 g_return_if_fail (GDK_IS_WINDOW (window));
6958 if (GDK_WINDOW_DESTROYED (window))
6967 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6968 impl_class->get_root_coords (window,
6975 * gdk_window_coords_to_parent:
6976 * @window: a child window
6977 * @x: X coordinate in child's coordinate system
6978 * @y: Y coordinate in child's coordinate system
6979 * @parent_x: (out) (allow-none): return location for X coordinate
6980 * in parent's coordinate system, or %NULL
6981 * @parent_y: (out) (allow-none): return location for Y coordinate
6982 * in parent's coordinate system, or %NULL
6984 * Transforms window coordinates from a child window to its parent
6985 * window, where the parent window is the normal parent as returned by
6986 * gdk_window_get_parent() for normal windows, and the window's
6987 * embedder as returned by gdk_offscreen_window_get_embedder() for
6988 * offscreen windows.
6990 * For normal windows, calling this function is equivalent to adding
6991 * the return values of gdk_window_get_position() to the child coordinates.
6992 * For offscreen windows however (which can be arbitrarily transformed),
6993 * this function calls the GdkWindow::to-embedder: signal to translate
6996 * You should always use this function when writing generic code that
6997 * walks up a window hierarchy.
6999 * See also: gdk_window_coords_from_parent()
7004 gdk_window_coords_to_parent (GdkWindow *window,
7010 g_return_if_fail (GDK_IS_WINDOW (window));
7012 if (gdk_window_is_offscreen (window))
7016 to_embedder (window, x, y, &px, &py);
7027 *parent_x = x + window->x;
7030 *parent_y = y + window->y;
7035 * gdk_window_coords_from_parent:
7036 * @window: a child window
7037 * @parent_x: X coordinate in parent's coordinate system
7038 * @parent_y: Y coordinate in parent's coordinate system
7039 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7040 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7042 * Transforms window coordinates from a parent window to a child
7043 * window, where the parent window is the normal parent as returned by
7044 * gdk_window_get_parent() for normal windows, and the window's
7045 * embedder as returned by gdk_offscreen_window_get_embedder() for
7046 * offscreen windows.
7048 * For normal windows, calling this function is equivalent to subtracting
7049 * the return values of gdk_window_get_position() from the parent coordinates.
7050 * For offscreen windows however (which can be arbitrarily transformed),
7051 * this function calls the GdkWindow::from-embedder: signal to translate
7054 * You should always use this function when writing generic code that
7055 * walks down a window hierarchy.
7057 * See also: gdk_window_coords_to_parent()
7062 gdk_window_coords_from_parent (GdkWindow *window,
7068 g_return_if_fail (GDK_IS_WINDOW (window));
7070 if (gdk_window_is_offscreen (window))
7074 from_embedder (window, parent_x, parent_y, &cx, &cy);
7085 *x = parent_x - window->x;
7088 *y = parent_y - window->y;
7093 * gdk_window_shape_combine_region:
7094 * @window: a #GdkWindow
7095 * @shape_region: region of window to be non-transparent
7096 * @offset_x: X position of @shape_region in @window coordinates
7097 * @offset_y: Y position of @shape_region in @window coordinates
7099 * Makes pixels in @window outside @shape_region be transparent,
7100 * so that the window may be nonrectangular.
7102 * If @shape_region is %NULL, the shape will be unset, so the whole
7103 * window will be opaque again. @offset_x and @offset_y are ignored
7104 * if @shape_region is %NULL.
7106 * On the X11 platform, this uses an X server extension which is
7107 * widely available on most common platforms, but not available on
7108 * very old X servers, and occasionally the implementation will be
7109 * buggy. On servers without the shape extension, this function
7112 * This function works on both toplevel and child windows.
7115 gdk_window_shape_combine_region (GdkWindow *window,
7116 const cairo_region_t *shape_region,
7120 cairo_region_t *old_region, *new_region, *diff;
7122 g_return_if_fail (GDK_IS_WINDOW (window));
7124 if (GDK_WINDOW_DESTROYED (window))
7127 if (!window->shape && shape_region == NULL)
7130 window->shaped = (shape_region != NULL);
7133 cairo_region_destroy (window->shape);
7136 if (GDK_WINDOW_IS_MAPPED (window))
7137 old_region = cairo_region_copy (window->clip_region);
7141 window->shape = cairo_region_copy (shape_region);
7142 cairo_region_translate (window->shape, offset_x, offset_y);
7145 window->shape = NULL;
7147 recompute_visible_regions (window, TRUE, FALSE);
7149 if (gdk_window_has_impl (window) &&
7150 !should_apply_clip_as_shape (window))
7151 apply_shape (window, window->shape);
7155 new_region = cairo_region_copy (window->clip_region);
7157 /* New area in the window, needs invalidation */
7158 diff = cairo_region_copy (new_region);
7159 cairo_region_subtract (diff, old_region);
7161 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7163 cairo_region_destroy (diff);
7165 if (!gdk_window_is_toplevel (window))
7167 /* New area in the non-root parent window, needs invalidation */
7168 diff = cairo_region_copy (old_region);
7169 cairo_region_subtract (diff, new_region);
7171 /* Adjust region to parent window coords */
7172 cairo_region_translate (diff, window->x, window->y);
7174 gdk_window_invalidate_region_full (window->parent, diff, TRUE, CLEAR_BG_ALL);
7176 cairo_region_destroy (diff);
7179 cairo_region_destroy (new_region);
7180 cairo_region_destroy (old_region);
7185 do_child_shapes (GdkWindow *window,
7189 cairo_region_t *region;
7193 r.width = window->width;
7194 r.height = window->height;
7196 region = cairo_region_create_rectangle (&r);
7197 remove_child_area (window, NULL, FALSE, region);
7199 if (merge && window->shape)
7200 cairo_region_subtract (region, window->shape);
7202 gdk_window_shape_combine_region (window, region, 0, 0);
7206 * gdk_window_set_child_shapes:
7207 * @window: a #GdkWindow
7209 * Sets the shape mask of @window to the union of shape masks
7210 * for all children of @window, ignoring the shape mask of @window
7211 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7212 * the shape mask of @window in the masks to be merged.
7215 gdk_window_set_child_shapes (GdkWindow *window)
7217 g_return_if_fail (GDK_IS_WINDOW (window));
7219 do_child_shapes (window, FALSE);
7223 * gdk_window_merge_child_shapes:
7224 * @window: a #GdkWindow
7226 * Merges the shape masks for any child windows into the
7227 * shape mask for @window. i.e. the union of all masks
7228 * for @window and its children will become the new mask
7229 * for @window. See gdk_window_shape_combine_region().
7231 * This function is distinct from gdk_window_set_child_shapes()
7232 * because it includes @window's shape mask in the set of shapes to
7236 gdk_window_merge_child_shapes (GdkWindow *window)
7238 g_return_if_fail (GDK_IS_WINDOW (window));
7240 do_child_shapes (window, TRUE);
7244 * gdk_window_input_shape_combine_region:
7245 * @window: a #GdkWindow
7246 * @shape_region: region of window to be non-transparent
7247 * @offset_x: X position of @shape_region in @window coordinates
7248 * @offset_y: Y position of @shape_region in @window coordinates
7250 * Like gdk_window_shape_combine_region(), but the shape applies
7251 * only to event handling. Mouse events which happen while
7252 * the pointer position corresponds to an unset bit in the
7253 * mask will be passed on the window below @window.
7255 * An input shape is typically used with RGBA windows.
7256 * The alpha channel of the window defines which pixels are
7257 * invisible and allows for nicely antialiased borders,
7258 * and the input shape controls where the window is
7261 * On the X11 platform, this requires version 1.1 of the
7264 * On the Win32 platform, this functionality is not present and the
7265 * function does nothing.
7270 gdk_window_input_shape_combine_region (GdkWindow *window,
7271 const cairo_region_t *shape_region,
7275 GdkWindowImplClass *impl_class;
7277 g_return_if_fail (GDK_IS_WINDOW (window));
7279 if (GDK_WINDOW_DESTROYED (window))
7282 if (window->input_shape)
7283 cairo_region_destroy (window->input_shape);
7287 window->input_shape = cairo_region_copy (shape_region);
7288 cairo_region_translate (window->input_shape, offset_x, offset_y);
7291 window->input_shape = NULL;
7293 if (gdk_window_has_impl (window))
7295 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7296 impl_class->input_shape_combine_region (window, window->input_shape, 0, 0);
7299 /* Pointer may have e.g. moved outside window due to the input mask change */
7300 _gdk_synthesize_crossing_events_for_geometry_change (window);
7304 do_child_input_shapes (GdkWindow *window,
7308 cairo_region_t *region;
7312 r.width = window->width;
7313 r.height = window->height;
7315 region = cairo_region_create_rectangle (&r);
7316 remove_child_area (window, NULL, TRUE, region);
7318 if (merge && window->shape)
7319 cairo_region_subtract (region, window->shape);
7320 if (merge && window->input_shape)
7321 cairo_region_subtract (region, window->input_shape);
7323 gdk_window_input_shape_combine_region (window, region, 0, 0);
7328 * gdk_window_set_child_input_shapes:
7329 * @window: a #GdkWindow
7331 * Sets the input shape mask of @window to the union of input shape masks
7332 * for all children of @window, ignoring the input shape mask of @window
7333 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7334 * the input shape mask of @window in the masks to be merged.
7339 gdk_window_set_child_input_shapes (GdkWindow *window)
7341 g_return_if_fail (GDK_IS_WINDOW (window));
7343 do_child_input_shapes (window, FALSE);
7347 * gdk_window_merge_child_input_shapes:
7348 * @window: a #GdkWindow
7350 * Merges the input shape masks for any child windows into the
7351 * input shape mask for @window. i.e. the union of all input masks
7352 * for @window and its children will become the new input mask
7353 * for @window. See gdk_window_input_shape_combine_region().
7355 * This function is distinct from gdk_window_set_child_input_shapes()
7356 * because it includes @window's input shape mask in the set of
7357 * shapes to be merged.
7362 gdk_window_merge_child_input_shapes (GdkWindow *window)
7364 g_return_if_fail (GDK_IS_WINDOW (window));
7366 do_child_input_shapes (window, TRUE);
7371 * gdk_window_set_static_gravities:
7372 * @window: a #GdkWindow
7373 * @use_static: %TRUE to turn on static gravity
7375 * Set the bit gravity of the given window to static, and flag it so
7376 * all children get static subwindow gravity. This is used if you are
7377 * implementing scary features that involve deep knowledge of the
7378 * windowing system. Don't worry about it unless you have to.
7380 * Return value: %TRUE if the server supports static gravity
7383 gdk_window_set_static_gravities (GdkWindow *window,
7384 gboolean use_static)
7386 GdkWindowImplClass *impl_class;
7388 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7390 if (gdk_window_has_impl (window))
7392 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7393 return impl_class->set_static_gravities (window, use_static);
7400 * gdk_window_get_composited:
7401 * @window: a #GdkWindow
7403 * Determines whether @window is composited.
7405 * See gdk_window_set_composited().
7407 * Returns: %TRUE if the window is composited.
7412 gdk_window_get_composited (GdkWindow *window)
7414 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7416 return window->composited;
7420 * gdk_window_set_composited:
7421 * @window: a #GdkWindow
7422 * @composited: %TRUE to set the window as composited
7424 * Sets a #GdkWindow as composited, or unsets it. Composited
7425 * windows do not automatically have their contents drawn to
7426 * the screen. Drawing is redirected to an offscreen buffer
7427 * and an expose event is emitted on the parent of the composited
7428 * window. It is the responsibility of the parent's expose handler
7429 * to manually merge the off-screen content onto the screen in
7430 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7433 * It only makes sense for child windows to be composited; see
7434 * gdk_window_set_opacity() if you need translucent toplevel
7437 * An additional effect of this call is that the area of this
7438 * window is no longer clipped from regions marked for
7439 * invalidation on its parent. Draws done on the parent
7440 * window are also no longer clipped by the child.
7442 * This call is only supported on some systems (currently,
7443 * only X11 with new enough Xcomposite and Xdamage extensions).
7444 * You must call gdk_display_supports_composite() to check if
7445 * setting a window as composited is supported before
7446 * attempting to do so.
7451 gdk_window_set_composited (GdkWindow *window,
7452 gboolean composited)
7454 GdkDisplay *display;
7456 g_return_if_fail (GDK_IS_WINDOW (window));
7458 composited = composited != FALSE;
7460 if (window->composited == composited)
7464 gdk_window_ensure_native (window);
7466 display = gdk_window_get_display (window);
7468 if (!gdk_display_supports_composite (display) && composited)
7470 g_warning ("gdk_window_set_composited called but "
7471 "compositing is not supported");
7475 _gdk_windowing_window_set_composited (window, composited);
7477 recompute_visible_regions (window, TRUE, FALSE);
7479 if (GDK_WINDOW_IS_MAPPED (window))
7480 gdk_window_invalidate_in_parent (window);
7482 window->composited = composited;
7486 * gdk_window_get_modal_hint:
7487 * @window: A toplevel #GdkWindow.
7489 * Determines whether or not the window manager is hinted that @window
7490 * has modal behaviour.
7492 * Return value: whether or not the window has the modal hint set.
7497 gdk_window_get_modal_hint (GdkWindow *window)
7499 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7501 return window->modal_hint;
7505 * gdk_window_get_accept_focus:
7506 * @window: a toplevel #GdkWindow.
7508 * Determines whether or not the desktop environment shuld be hinted that
7509 * the window does not want to receive input focus.
7511 * Return value: whether or not the window should receive input focus.
7516 gdk_window_get_accept_focus (GdkWindow *window)
7518 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7520 return window->accept_focus;
7524 * gdk_window_get_focus_on_map:
7525 * @window: a toplevel #GdkWindow.
7527 * Determines whether or not the desktop environment should be hinted that the
7528 * window does not want to receive input focus when it is mapped.
7530 * Return value: whether or not the window wants to receive input focus when
7536 gdk_window_get_focus_on_map (GdkWindow *window)
7538 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7540 return window->focus_on_map;
7544 * gdk_window_is_input_only:
7545 * @window: a toplevel #GdkWindow
7547 * Determines whether or not the window is an input only window.
7549 * Return value: %TRUE if @window is input only
7554 gdk_window_is_input_only (GdkWindow *window)
7556 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7558 return window->input_only;
7562 * gdk_window_is_shaped:
7563 * @window: a toplevel #GdkWindow
7565 * Determines whether or not the window is shaped.
7567 * Return value: %TRUE if @window is shaped
7572 gdk_window_is_shaped (GdkWindow *window)
7574 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7576 return window->shaped;
7580 window_get_size_rectangle (GdkWindow *window,
7583 rect->x = rect->y = 0;
7584 rect->width = window->width;
7585 rect->height = window->height;
7588 /* Calculates the real clipping region for a window, in window coordinates,
7589 * taking into account other windows, gc clip region and gc clip mask.
7592 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7593 GdkWindow *base_window,
7594 gboolean do_children,
7595 gint *base_x_offset,
7596 gint *base_y_offset)
7598 GdkRectangle visible_rect;
7599 cairo_region_t *real_clip_region;
7600 gint x_offset, y_offset;
7601 GdkWindow *parentwin, *lastwin;
7608 if (!window->viewable || window->input_only)
7609 return cairo_region_create ();
7611 window_get_size_rectangle (window, &visible_rect);
7613 /* real_clip_region is in window coordinates */
7614 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7616 x_offset = y_offset = 0;
7620 parentwin = lastwin;
7622 parentwin = lastwin->parent;
7624 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7625 for (; parentwin != NULL &&
7626 (parentwin == window || lastwin != base_window);
7627 lastwin = parentwin, parentwin = lastwin->parent)
7630 GdkRectangle real_clip_rect;
7632 if (parentwin != window)
7634 x_offset += lastwin->x;
7635 y_offset += lastwin->y;
7638 /* children is ordered in reverse stack order */
7639 for (cur = parentwin->children;
7640 cur && cur->data != lastwin;
7643 GdkWindow *child = cur->data;
7645 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
7648 /* Ignore offscreen children, as they don't draw in their parent and
7649 * don't take part in the clipping */
7650 if (gdk_window_is_offscreen (child))
7653 window_get_size_rectangle (child, &visible_rect);
7655 /* Convert rect to "window" coords */
7656 visible_rect.x += child->x - x_offset;
7657 visible_rect.y += child->y - y_offset;
7659 /* This shortcut is really necessary for performance when there are a lot of windows */
7660 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7661 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7662 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7663 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7664 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7667 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7670 /* Clip to the parent */
7671 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7672 /* Convert rect to "window" coords */
7673 visible_rect.x += - x_offset;
7674 visible_rect.y += - y_offset;
7676 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7680 *base_x_offset = x_offset;
7682 *base_y_offset = y_offset;
7684 return real_clip_region;
7688 _gdk_window_add_damage (GdkWindow *toplevel,
7689 cairo_region_t *damaged_region)
7691 GdkDisplay *display;
7692 GdkEvent event = { 0, };
7693 event.expose.type = GDK_DAMAGE;
7694 event.expose.window = toplevel;
7695 event.expose.send_event = FALSE;
7696 event.expose.region = damaged_region;
7697 cairo_region_get_extents (event.expose.region, &event.expose.area);
7698 display = gdk_window_get_display (event.expose.window);
7699 _gdk_event_queue_append (display, gdk_event_copy (&event));
7702 /* Gets the toplevel for a window as used for events,
7703 i.e. including offscreen parents */
7705 get_event_parent (GdkWindow *window)
7707 if (gdk_window_is_offscreen (window))
7708 return gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7710 return window->parent;
7713 /* Gets the toplevel for a window as used for events,
7714 i.e. including offscreen parents going up to the native
7717 get_event_toplevel (GdkWindow *window)
7721 while ((parent = get_event_parent (window)) != NULL &&
7722 (parent->window_type != GDK_WINDOW_ROOT))
7729 _gdk_window_event_parent_of (GdkWindow *parent,
7740 w = get_event_parent (w);
7747 update_cursor (GdkDisplay *display,
7750 GdkWindow *cursor_window, *parent, *toplevel;
7751 GdkWindow *pointer_window;
7752 GdkWindowImplClass *impl_class;
7753 GdkPointerWindowInfo *pointer_info;
7754 GdkDeviceGrabInfo *grab;
7757 pointer_info = _gdk_display_get_pointer_info (display, device);
7758 pointer_window = pointer_info->window_under_pointer;
7760 /* We ignore the serials here and just pick the last grab
7761 we've sent, as that would shortly be used anyway. */
7762 grab = _gdk_display_get_last_device_grab (display, device);
7765 /* the pointer is not in a descendant of the grab window */
7766 !_gdk_window_event_parent_of (grab->window, pointer_window))
7768 /* use the cursor from the grab window */
7769 cursor_window = grab->window;
7773 /* otherwise use the cursor from the pointer window */
7774 cursor_window = pointer_window;
7777 /* Find the first window with the cursor actually set, as
7778 the cursor is inherited from the parent */
7779 while (cursor_window->cursor == NULL &&
7780 (parent = get_event_parent (cursor_window)) != NULL &&
7781 parent->window_type != GDK_WINDOW_ROOT)
7782 cursor_window = parent;
7784 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
7787 cursor = cursor_window->cursor;
7789 /* Set all cursors on toplevel, otherwise its tricky to keep track of
7790 * which native window has what cursor set. */
7791 toplevel = get_event_toplevel (pointer_window);
7792 impl_class = GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl);
7793 impl_class->set_device_cursor (toplevel, device, cursor);
7797 point_in_window (GdkWindow *window,
7802 x >= 0 && x < window->width &&
7803 y >= 0 && y < window->height &&
7804 (window->shape == NULL ||
7805 cairo_region_contains_point (window->shape,
7807 (window->input_shape == NULL ||
7808 cairo_region_contains_point (window->input_shape,
7813 convert_native_coords_to_toplevel (GdkWindow *window,
7816 gdouble *toplevel_x,
7817 gdouble *toplevel_y)
7824 while (!gdk_window_is_toplevel (window))
7828 window = window->parent;
7838 convert_toplevel_coords_to_window (GdkWindow *window,
7846 GList *children, *l;
7852 while ((parent = get_event_parent (window)) != NULL &&
7853 (parent->window_type != GDK_WINDOW_ROOT))
7855 children = g_list_prepend (children, window);
7859 for (l = children; l != NULL; l = l->next)
7860 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
7862 g_list_free (children);
7869 pick_embedded_child (GdkWindow *window,
7876 g_signal_emit (window,
7877 signals[PICK_EMBEDDED_CHILD], 0,
7884 _gdk_window_find_child_at (GdkWindow *window,
7889 double child_x, child_y;
7892 if (point_in_window (window, x, y))
7894 /* Children is ordered in reverse stack order, i.e. first is topmost */
7895 for (l = window->children; l != NULL; l = l->next)
7899 if (!GDK_WINDOW_IS_MAPPED (sub))
7902 gdk_window_coords_from_parent ((GdkWindow *)sub,
7904 &child_x, &child_y);
7905 if (point_in_window (sub, child_x, child_y))
7906 return (GdkWindow *)sub;
7909 if (window->num_offscreen_children > 0)
7911 sub = pick_embedded_child (window,
7914 return (GdkWindow *)sub;
7922 _gdk_window_find_descendant_at (GdkWindow *window,
7929 gdouble child_x, child_y;
7933 if (point_in_window (window, x, y))
7938 /* Children is ordered in reverse stack order, i.e. first is topmost */
7939 for (l = window->children; l != NULL; l = l->next)
7943 if (!GDK_WINDOW_IS_MAPPED (sub))
7946 gdk_window_coords_from_parent ((GdkWindow *)sub,
7948 &child_x, &child_y);
7949 if (point_in_window (sub, child_x, child_y))
7959 window->num_offscreen_children > 0)
7961 sub = pick_embedded_child (window,
7967 from_embedder (sub, x, y, &x, &y);
7975 /* Not in window at all */
7989 * @window: a toplevel #GdkWindow
7991 * Emits a short beep associated to @window in the appropriate
7992 * display, if supported. Otherwise, emits a short beep on
7993 * the display just as gdk_display_beep().
7998 gdk_window_beep (GdkWindow *window)
8000 GdkDisplay *display;
8001 GdkWindow *toplevel;
8003 g_return_if_fail (GDK_IS_WINDOW (window));
8005 if (GDK_WINDOW_DESTROYED (window))
8008 toplevel = get_event_toplevel (window);
8009 display = gdk_window_get_display (window);
8013 if (GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl)->beep (window))
8017 /* If windows fail to beep, we beep the display. */
8018 gdk_display_beep (display);
8022 * gdk_window_set_support_multidevice:
8023 * @window: a #GdkWindow.
8024 * @support_multidevice: %TRUE to enable multidevice support in @window.
8026 * This function will enable multidevice features in @window.
8028 * Multidevice aware windows will need to handle properly multiple,
8029 * per device enter/leave events, device grabs and grab ownerships.
8034 gdk_window_set_support_multidevice (GdkWindow *window,
8035 gboolean support_multidevice)
8037 g_return_if_fail (GDK_IS_WINDOW (window));
8039 if (GDK_WINDOW_DESTROYED (window))
8042 if (window->support_multidevice == support_multidevice)
8045 window->support_multidevice = support_multidevice;
8047 /* FIXME: What to do if called when some pointers are inside the window ? */
8051 * gdk_window_get_support_multidevice:
8052 * @window: a #GdkWindow.
8054 * Returns %TRUE if the window is aware of the existence of multiple
8057 * Returns: %TRUE if the window handles multidevice features.
8062 gdk_window_get_support_multidevice (GdkWindow *window)
8064 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8066 if (GDK_WINDOW_DESTROYED (window))
8069 return window->support_multidevice;
8072 static const guint type_masks[] = {
8073 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8074 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8075 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8076 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8077 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8078 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8079 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8080 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8081 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8082 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8083 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8084 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8085 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8086 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8087 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8088 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8089 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8090 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8091 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8092 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8093 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8094 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8095 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8096 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8097 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8098 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8099 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8100 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8101 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8102 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8103 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8104 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8105 0, /* GDK_WINDOW_STATE = 32 */
8106 0, /* GDK_SETTING = 33 */
8107 0, /* GDK_OWNER_CHANGE = 34 */
8108 0, /* GDK_GRAB_BROKEN = 35 */
8109 0, /* GDK_DAMAGE = 36 */
8111 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8113 /* send motion events if the right buttons are down */
8115 update_evmask_for_button_motion (guint evmask,
8116 GdkModifierType mask)
8118 if (evmask & GDK_BUTTON_MOTION_MASK &&
8119 mask & (GDK_BUTTON1_MASK |
8124 evmask |= GDK_POINTER_MOTION_MASK;
8126 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8127 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8128 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8129 evmask |= GDK_POINTER_MOTION_MASK;
8135 is_button_type (GdkEventType type)
8137 return type == GDK_BUTTON_PRESS ||
8138 type == GDK_2BUTTON_PRESS ||
8139 type == GDK_3BUTTON_PRESS ||
8140 type == GDK_BUTTON_RELEASE ||
8145 is_motion_type (GdkEventType type)
8147 return type == GDK_MOTION_NOTIFY ||
8148 type == GDK_ENTER_NOTIFY ||
8149 type == GDK_LEAVE_NOTIFY;
8153 find_common_ancestor (GdkWindow *win1,
8157 GList *path1 = NULL, *path2 = NULL;
8158 GList *list1, *list2;
8161 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8163 path1 = g_list_prepend (path1, tmp);
8164 tmp = get_event_parent (tmp);
8168 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8170 path2 = g_list_prepend (path2, tmp);
8171 tmp = get_event_parent (tmp);
8177 while (list1 && list2 && (list1->data == list2->data))
8180 list1 = g_list_next (list1);
8181 list2 = g_list_next (list2);
8183 g_list_free (path1);
8184 g_list_free (path2);
8190 _gdk_make_event (GdkWindow *window,
8192 GdkEvent *event_in_queue,
8193 gboolean before_event)
8195 GdkEvent *event = gdk_event_new (type);
8197 GdkModifierType the_state;
8199 the_time = gdk_event_get_time (event_in_queue);
8200 gdk_event_get_state (event_in_queue, &the_state);
8202 event->any.window = g_object_ref (window);
8203 event->any.send_event = FALSE;
8204 if (event_in_queue && event_in_queue->any.send_event)
8205 event->any.send_event = TRUE;
8209 case GDK_MOTION_NOTIFY:
8210 event->motion.time = the_time;
8211 event->motion.axes = NULL;
8212 event->motion.state = the_state;
8215 case GDK_BUTTON_PRESS:
8216 case GDK_2BUTTON_PRESS:
8217 case GDK_3BUTTON_PRESS:
8218 case GDK_BUTTON_RELEASE:
8219 event->button.time = the_time;
8220 event->button.axes = NULL;
8221 event->button.state = the_state;
8225 event->scroll.time = the_time;
8226 event->scroll.state = the_state;
8230 case GDK_KEY_RELEASE:
8231 event->key.time = the_time;
8232 event->key.state = the_state;
8235 case GDK_ENTER_NOTIFY:
8236 case GDK_LEAVE_NOTIFY:
8237 event->crossing.time = the_time;
8238 event->crossing.state = the_state;
8241 case GDK_PROPERTY_NOTIFY:
8242 event->property.time = the_time;
8243 event->property.state = the_state;
8246 case GDK_SELECTION_CLEAR:
8247 case GDK_SELECTION_REQUEST:
8248 case GDK_SELECTION_NOTIFY:
8249 event->selection.time = the_time;
8252 case GDK_PROXIMITY_IN:
8253 case GDK_PROXIMITY_OUT:
8254 event->proximity.time = the_time;
8257 case GDK_DRAG_ENTER:
8258 case GDK_DRAG_LEAVE:
8259 case GDK_DRAG_MOTION:
8260 case GDK_DRAG_STATUS:
8261 case GDK_DROP_START:
8262 case GDK_DROP_FINISHED:
8263 event->dnd.time = the_time;
8266 case GDK_FOCUS_CHANGE:
8270 case GDK_CLIENT_EVENT:
8271 case GDK_VISIBILITY_NOTIFY:
8282 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8284 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8287 _gdk_event_queue_append (gdk_window_get_display (window), event);
8293 send_crossing_event (GdkDisplay *display,
8294 GdkWindow *toplevel,
8297 GdkCrossingMode mode,
8298 GdkNotifyType notify_type,
8299 GdkWindow *subwindow,
8301 GdkDevice *source_device,
8304 GdkModifierType mask,
8306 GdkEvent *event_in_queue,
8310 guint32 window_event_mask, type_event_mask;
8311 GdkDeviceGrabInfo *grab;
8312 gboolean block_event = FALSE;
8314 grab = _gdk_display_has_device_grab (display, device, serial);
8317 !grab->owner_events)
8319 /* !owner_event => only report events wrt grab window, ignore rest */
8320 if ((GdkWindow *)window != grab->window)
8322 window_event_mask = grab->event_mask;
8325 window_event_mask = window->event_mask;
8327 if (type == GDK_LEAVE_NOTIFY)
8329 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8330 window->devices_inside = g_list_remove (window->devices_inside, device);
8332 if (!window->support_multidevice && window->devices_inside)
8334 /* Block leave events unless it's the last pointer */
8340 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8342 if (!window->support_multidevice && window->devices_inside)
8344 /* Only emit enter events for the first device */
8348 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8349 gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
8350 !g_list_find (window->devices_inside, device))
8351 window->devices_inside = g_list_prepend (window->devices_inside, device);
8357 if (window_event_mask & type_event_mask)
8359 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8360 gdk_event_set_device (event, device);
8363 gdk_event_set_source_device (event, source_device);
8365 event->crossing.time = time_;
8366 event->crossing.subwindow = subwindow;
8368 g_object_ref (subwindow);
8369 convert_toplevel_coords_to_window ((GdkWindow *)window,
8370 toplevel_x, toplevel_y,
8371 &event->crossing.x, &event->crossing.y);
8372 event->crossing.x_root = toplevel_x + toplevel->x;
8373 event->crossing.y_root = toplevel_y + toplevel->y;
8374 event->crossing.mode = mode;
8375 event->crossing.detail = notify_type;
8376 event->crossing.focus = FALSE;
8377 event->crossing.state = mask;
8382 /* The coordinates are in the toplevel window that src/dest are in.
8383 * src and dest are always (if != NULL) in the same toplevel, as
8384 * we get a leave-notify and set the window_under_pointer to null
8385 * before crossing to another toplevel.
8388 _gdk_synthesize_crossing_events (GdkDisplay *display,
8392 GdkDevice *source_device,
8393 GdkCrossingMode mode,
8396 GdkModifierType mask,
8398 GdkEvent *event_in_queue,
8400 gboolean non_linear)
8403 GdkWindow *win, *last, *next;
8407 GdkWindow *toplevel;
8408 GdkNotifyType notify_type;
8410 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8415 return; /* No crossings generated between src and dest */
8417 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8419 if (a && gdk_window_get_device_events (src, device) == 0)
8422 if (b && gdk_window_get_device_events (dest, device) == 0)
8429 c = find_common_ancestor (a, b);
8431 non_linear |= (c != a) && (c != b);
8433 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8435 toplevel = gdk_window_get_toplevel (a);
8437 /* Traverse up from a to (excluding) c sending leave events */
8439 notify_type = GDK_NOTIFY_NONLINEAR;
8441 notify_type = GDK_NOTIFY_INFERIOR;
8443 notify_type = GDK_NOTIFY_ANCESTOR;
8444 send_crossing_event (display, toplevel,
8445 a, GDK_LEAVE_NOTIFY,
8448 NULL, device, source_device,
8449 toplevel_x, toplevel_y,
8457 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8459 notify_type = GDK_NOTIFY_VIRTUAL;
8462 win = get_event_parent (a);
8463 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8465 send_crossing_event (display, toplevel,
8466 win, GDK_LEAVE_NOTIFY,
8470 device, source_device,
8471 toplevel_x, toplevel_y,
8477 win = get_event_parent (win);
8482 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8484 toplevel = gdk_window_get_toplevel ((GdkWindow *)b);
8486 /* Traverse down from c to b */
8490 win = get_event_parent (b);
8491 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8493 path = g_list_prepend (path, win);
8494 win = get_event_parent (win);
8498 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8500 notify_type = GDK_NOTIFY_VIRTUAL;
8506 list = g_list_next (list);
8512 send_crossing_event (display, toplevel,
8513 win, GDK_ENTER_NOTIFY,
8517 device, source_device,
8518 toplevel_x, toplevel_y,
8528 notify_type = GDK_NOTIFY_NONLINEAR;
8530 notify_type = GDK_NOTIFY_ANCESTOR;
8532 notify_type = GDK_NOTIFY_INFERIOR;
8534 send_crossing_event (display, toplevel,
8535 b, GDK_ENTER_NOTIFY,
8539 device, source_device,
8540 toplevel_x, toplevel_y,
8547 /* Returns the window inside the event window with the pointer in it
8548 * at the specified coordinates, or NULL if its not in any child of
8549 * the toplevel. It also takes into account !owner_events grabs.
8552 get_pointer_window (GdkDisplay *display,
8553 GdkWindow *event_window,
8559 GdkWindow *pointer_window;
8560 GdkDeviceGrabInfo *grab;
8561 GdkPointerWindowInfo *pointer_info;
8563 pointer_info = _gdk_display_get_pointer_info (display, device);
8565 if (event_window == pointer_info->toplevel_under_pointer)
8567 _gdk_window_find_descendant_at (event_window,
8568 toplevel_x, toplevel_y,
8571 pointer_window = NULL;
8573 grab = _gdk_display_has_device_grab (display, device, serial);
8575 !grab->owner_events &&
8576 pointer_window != grab->window)
8577 pointer_window = NULL;
8579 return pointer_window;
8583 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8587 GdkPointerWindowInfo *device_info;
8589 /* We don't track this if all native, and it can cause issues
8590 with the update_cursor call below */
8591 if (_gdk_native_windows)
8594 device_info = _gdk_display_get_pointer_info (display, device);
8596 if (device_info->window_under_pointer)
8597 g_object_unref (device_info->window_under_pointer);
8598 device_info->window_under_pointer = window;
8602 g_object_ref (window);
8603 update_cursor (display, device);
8606 _gdk_display_enable_motion_hints (display, device);
8611 * @window: the #GdkWindow which will own the grab (the grab window).
8612 * @owner_events: if %FALSE then all pointer events are reported with respect to
8613 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8614 * events for this application are reported as normal, but pointer events outside
8615 * this application are reported with respect to @window and only if selected by
8616 * @event_mask. In either mode, unreported events are discarded.
8617 * @event_mask: specifies the event mask, which is used in accordance with
8618 * @owner_events. Note that only pointer events (i.e. button and motion events)
8620 * @confine_to: If non-%NULL, the pointer will be confined to this
8621 * window during the grab. If the pointer is outside @confine_to, it will
8622 * automatically be moved to the closest edge of @confine_to and enter
8623 * and leave events will be generated as necessary.
8624 * @cursor: the cursor to display while the grab is active. If this is %NULL then
8625 * the normal cursors are used for @window and its descendants, and the cursor
8626 * for @window is used for all other windows.
8627 * @time_: the timestamp of the event which led to this pointer grab. This usually
8628 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8629 * the time isn't known.
8631 * Grabs the pointer (usually a mouse) so that all events are passed to this
8632 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8633 * the grab window becomes unviewable.
8634 * This overrides any previous pointer grab by this client.
8636 * Pointer grabs are used for operations which need complete control over mouse
8637 * events, even if the mouse leaves the application.
8638 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8639 * the #GtkHPaned and #GtkVPaned widgets.
8641 * Note that if the event mask of an X window has selected both button press and
8642 * button release events, then a button press event will cause an automatic
8643 * pointer grab until the button is released.
8644 * X does this automatically since most applications expect to receive button
8645 * press and release events in pairs.
8646 * It is equivalent to a pointer grab on the window with @owner_events set to
8649 * If you set up anything at the time you take the grab that needs to be cleaned
8650 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8651 * are emitted when the grab ends unvoluntarily.
8653 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8655 * Deprecated: 3.0: Use gdk_device_grab() instead.
8658 gdk_pointer_grab (GdkWindow * window,
8659 gboolean owner_events,
8660 GdkEventMask event_mask,
8661 GdkWindow * confine_to,
8666 GdkDisplay *display;
8667 GdkDeviceManager *device_manager;
8669 GdkGrabStatus res = 0;
8671 GList *devices, *dev;
8673 g_return_val_if_fail (window != NULL, 0);
8674 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8675 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8677 /* We need a native window for confine to to work, ensure we have one */
8680 if (!gdk_window_ensure_native (confine_to))
8682 g_warning ("Can't confine to grabbed window, not native");
8687 /* Non-viewable client side window => fail */
8688 if (!_gdk_window_has_impl (window) &&
8689 !gdk_window_is_viewable (window))
8690 return GDK_GRAB_NOT_VIEWABLE;
8692 if (_gdk_native_windows)
8695 native = gdk_window_get_toplevel (window);
8696 while (gdk_window_is_offscreen (native))
8698 native = gdk_offscreen_window_get_embedder (native);
8700 if (native == NULL ||
8701 (!_gdk_window_has_impl (native) &&
8702 !gdk_window_is_viewable (native)))
8703 return GDK_GRAB_NOT_VIEWABLE;
8705 native = gdk_window_get_toplevel (native);
8708 display = gdk_window_get_display (window);
8710 serial = _gdk_windowing_window_get_next_serial (display);
8711 device_manager = gdk_display_get_device_manager (display);
8712 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8714 /* FIXME: Should this be generic to all backends? */
8715 /* FIXME: What happens with extended devices? */
8716 for (dev = devices; dev; dev = dev->next)
8720 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
8723 res = _gdk_windowing_device_grab (device,
8727 get_native_grab_event_mask (event_mask),
8732 if (res == GDK_GRAB_SUCCESS)
8733 _gdk_display_add_device_grab (display,
8745 /* FIXME: handle errors when grabbing */
8747 g_list_free (devices);
8753 * gdk_keyboard_grab:
8754 * @window: the #GdkWindow which will own the grab (the grab window).
8755 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8756 * @window. If %TRUE then keyboard events for this application are
8757 * reported as normal, but keyboard events outside this application
8758 * are reported with respect to @window. Both key press and key
8759 * release events are always reported, independant of the event mask
8760 * set by the application.
8761 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8764 * Grabs the keyboard so that all events are passed to this
8765 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8766 * This overrides any previous keyboard grab by this client.
8768 * If you set up anything at the time you take the grab that needs to be cleaned
8769 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8770 * are emitted when the grab ends unvoluntarily.
8772 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8774 * Deprecated: 3.0: Use gdk_device_grab() instead.
8777 gdk_keyboard_grab (GdkWindow *window,
8778 gboolean owner_events,
8782 GdkDisplay *display;
8783 GdkDeviceManager *device_manager;
8785 GdkGrabStatus res = 0;
8787 GList *devices, *dev;
8789 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8791 /* Non-viewable client side window => fail */
8792 if (!_gdk_window_has_impl (window) &&
8793 !gdk_window_is_viewable (window))
8794 return GDK_GRAB_NOT_VIEWABLE;
8796 if (_gdk_native_windows)
8799 native = gdk_window_get_toplevel (window);
8801 while (gdk_window_is_offscreen (native))
8803 native = gdk_offscreen_window_get_embedder (native);
8805 if (native == NULL ||
8806 (!_gdk_window_has_impl (native) &&
8807 !gdk_window_is_viewable (native)))
8808 return GDK_GRAB_NOT_VIEWABLE;
8810 native = gdk_window_get_toplevel (native);
8813 display = gdk_window_get_display (window);
8815 serial = _gdk_windowing_window_get_next_serial (display);
8816 device_manager = gdk_display_get_device_manager (display);
8817 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8819 /* FIXME: Should this be generic to all backends? */
8820 /* FIXME: What happens with extended devices? */
8821 for (dev = devices; dev; dev = dev->next)
8825 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
8828 res = _gdk_windowing_device_grab (device,
8832 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
8837 if (res == GDK_GRAB_SUCCESS)
8838 _gdk_display_add_device_grab (display,
8849 /* FIXME: handle errors when grabbing */
8851 g_list_free (devices);
8857 * gdk_window_geometry_changed:
8858 * @window: an embedded offscreen #GdkWindow
8860 * This function informs GDK that the geometry of an embedded
8861 * offscreen window has changed. This is necessary for GDK to keep
8862 * track of which offscreen window the pointer is in.
8867 gdk_window_geometry_changed (GdkWindow *window)
8869 _gdk_synthesize_crossing_events_for_geometry_change (window);
8873 source_events_device_added (GdkDeviceManager *device_manager,
8878 GdkEventMask event_mask;
8879 GdkInputSource source;
8881 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_FLOATING)
8885 source = gdk_device_get_source (device);
8887 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
8888 GINT_TO_POINTER (source)));
8890 gdk_window_set_device_events (window, device, event_mask);
8894 source_events_device_changed (GdkDeviceManager *device_manager,
8899 GdkInputSource source;
8900 GdkEventMask event_mask;
8904 type = gdk_device_get_device_type (device);
8905 source = gdk_device_get_source (device);
8907 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
8908 GINT_TO_POINTER (source)));
8913 if (type == GDK_DEVICE_TYPE_FLOATING)
8915 /* The device was just floated, enable its event mask */
8916 gdk_window_set_device_events (window, device, event_mask);
8918 else if (type == GDK_DEVICE_TYPE_SLAVE)
8919 gdk_window_set_device_events (window, device, 0);
8923 * gdk_window_set_source_events:
8924 * @window: a #GdkWindow
8925 * @source: a #GdkInputSource to define the source class.
8926 * @event_mask: event mask for @window
8928 * Sets the event mask for any floating device (i.e. not attached to any
8929 * visible pointer) that has the source defined as @source. This event
8930 * mask will be applied both to currently existing, newly added devices
8931 * after this call, and devices being attached/detached.
8936 gdk_window_set_source_events (GdkWindow *window,
8937 GdkInputSource source,
8938 GdkEventMask event_mask)
8940 GdkDeviceManager *device_manager;
8941 GdkDisplay *display;
8945 g_return_if_fail (GDK_IS_WINDOW (window));
8947 display = gdk_window_get_display (window);
8948 device_manager = gdk_display_get_device_manager (display);
8950 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
8952 /* Set event mask for existing devices */
8953 for (d = devices; d; d = d->next)
8955 GdkDevice *device = d->data;
8957 if (source == gdk_device_get_source (device))
8958 gdk_window_set_device_events (window, device, event_mask);
8961 /* Update accounting */
8962 if (G_UNLIKELY (!window->source_event_masks))
8963 window->source_event_masks = g_hash_table_new (NULL, NULL);
8966 g_hash_table_insert (window->source_event_masks,
8967 GUINT_TO_POINTER (source),
8968 GUINT_TO_POINTER (event_mask));
8970 g_hash_table_remove (window->source_event_masks,
8971 GUINT_TO_POINTER (source));
8973 size = g_hash_table_size (window->source_event_masks);
8975 /* Update handler if needed */
8976 if (!window->device_added_handler_id && size > 0)
8978 window->device_added_handler_id =
8979 g_signal_connect (device_manager, "device-added",
8980 G_CALLBACK (source_events_device_added), window);
8981 window->device_changed_handler_id =
8982 g_signal_connect (device_manager, "device-changed",
8983 G_CALLBACK (source_events_device_changed), window);
8985 else if (window->device_added_handler_id && size == 0)
8986 g_signal_handler_disconnect (device_manager, window->device_added_handler_id);
8990 * gdk_window_get_source_events:
8991 * @window: a #GdkWindow
8992 * @source: a #GdkInputSource to define the source class.
8994 * Returns the event mask for @window corresponding to the device class specified
8997 * Returns: source event mask for @window
9000 gdk_window_get_source_events (GdkWindow *window,
9001 GdkInputSource source)
9003 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
9005 return GPOINTER_TO_UINT (g_hash_table_lookup (window->source_event_masks,
9006 GUINT_TO_POINTER (source)));
9010 do_synthesize_crossing_event (gpointer data)
9012 GdkDisplay *display;
9013 GdkWindow *changed_toplevel;
9014 GHashTableIter iter;
9015 gpointer key, value;
9018 changed_toplevel = data;
9020 changed_toplevel->synthesize_crossing_event_queued = FALSE;
9022 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9025 display = gdk_window_get_display (changed_toplevel);
9026 serial = _gdk_windowing_window_get_next_serial (display);
9027 g_hash_table_iter_init (&iter, display->pointers_info);
9029 while (g_hash_table_iter_next (&iter, &key, &value))
9031 GdkWindow *new_window_under_pointer;
9032 GdkPointerWindowInfo *pointer_info = value;
9033 GdkDevice *device = key;
9035 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9037 new_window_under_pointer =
9038 get_pointer_window (display, changed_toplevel,
9040 pointer_info->toplevel_x,
9041 pointer_info->toplevel_y,
9043 if (new_window_under_pointer != pointer_info->window_under_pointer)
9045 _gdk_synthesize_crossing_events (display,
9046 pointer_info->window_under_pointer,
9047 new_window_under_pointer,
9049 GDK_CROSSING_NORMAL,
9050 pointer_info->toplevel_x,
9051 pointer_info->toplevel_y,
9052 pointer_info->state,
9057 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9066 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9068 GdkDisplay *display;
9069 GdkWindow *toplevel;
9071 if (_gdk_native_windows)
9072 return; /* We use the native crossing events if all native */
9074 display = gdk_window_get_display (changed_window);
9076 toplevel = get_event_toplevel (changed_window);
9078 if (!toplevel->synthesize_crossing_event_queued)
9080 toplevel->synthesize_crossing_event_queued = TRUE;
9082 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9083 do_synthesize_crossing_event,
9084 g_object_ref (toplevel),
9089 /* Don't use for crossing events */
9091 get_event_window (GdkDisplay *display,
9093 GdkWindow *pointer_window,
9095 GdkModifierType mask,
9100 GdkWindow *grab_window;
9101 GdkDeviceGrabInfo *grab;
9103 grab = _gdk_display_has_device_grab (display, device, serial);
9105 if (grab != NULL && !grab->owner_events)
9107 evmask = grab->event_mask;
9108 evmask = update_evmask_for_button_motion (evmask, mask);
9110 grab_window = grab->window;
9112 if (evmask & type_masks[type])
9115 *evmask_out = evmask;
9122 while (pointer_window != NULL)
9124 evmask = pointer_window->event_mask;
9125 evmask = update_evmask_for_button_motion (evmask, mask);
9127 if (evmask & type_masks[type])
9130 *evmask_out = evmask;
9131 return pointer_window;
9134 pointer_window = get_event_parent (pointer_window);
9140 evmask = grab->event_mask;
9141 evmask = update_evmask_for_button_motion (evmask, mask);
9143 if (evmask & type_masks[type])
9146 *evmask_out = evmask;
9147 return grab->window;
9157 proxy_pointer_event (GdkDisplay *display,
9158 GdkEvent *source_event,
9161 GdkWindow *toplevel_window, *event_window;
9162 GdkWindow *pointer_window;
9163 GdkPointerWindowInfo *pointer_info;
9164 GdkDevice *device, *source_device;
9167 gdouble toplevel_x, toplevel_y;
9169 gboolean non_linear;
9171 event_window = source_event->any.window;
9172 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9173 gdk_event_get_state (source_event, &state);
9174 time_ = gdk_event_get_time (source_event);
9175 device = gdk_event_get_device (source_event);
9176 source_device = gdk_event_get_source_device (source_event);
9177 pointer_info = _gdk_display_get_pointer_info (display, device);
9178 toplevel_window = convert_native_coords_to_toplevel (event_window,
9179 toplevel_x, toplevel_y,
9180 &toplevel_x, &toplevel_y);
9183 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9184 source_event->type == GDK_ENTER_NOTIFY) &&
9185 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9186 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9189 /* If we get crossing events with subwindow unexpectedly being NULL
9190 that means there is a native subwindow that gdk doesn't know about.
9191 We track these and forward them, with the correct virtual window
9193 This is important to get right, as metacity uses gdk for the frame
9194 windows, but gdk doesn't know about the client windows reparented
9196 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9197 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9198 (source_event->type == GDK_ENTER_NOTIFY &&
9199 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9200 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9201 source_event->crossing.subwindow == NULL)
9203 /* Left for an unknown (to gdk) subwindow */
9205 /* Send leave events from window under pointer to event window
9206 that will get the subwindow == NULL window */
9207 _gdk_synthesize_crossing_events (display,
9208 pointer_info->window_under_pointer,
9210 device, source_device,
9211 source_event->crossing.mode,
9212 toplevel_x, toplevel_y,
9218 /* Send subwindow == NULL event */
9219 send_crossing_event (display,
9223 source_event->crossing.mode,
9224 source_event->crossing.detail,
9226 device, source_device,
9227 toplevel_x, toplevel_y,
9232 _gdk_display_set_window_under_pointer (display, device, NULL);
9236 pointer_window = get_pointer_window (display, toplevel_window, device,
9237 toplevel_x, toplevel_y, serial);
9239 if (((source_event->type == GDK_ENTER_NOTIFY &&
9240 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9241 (source_event->type == GDK_LEAVE_NOTIFY &&
9242 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9243 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9244 source_event->crossing.subwindow == NULL)
9246 /* Entered from an unknown (to gdk) subwindow */
9248 /* Send subwindow == NULL event */
9249 send_crossing_event (display,
9253 source_event->crossing.mode,
9254 source_event->crossing.detail,
9256 device, source_device,
9257 toplevel_x, toplevel_y,
9262 /* Send enter events from event window to pointer_window */
9263 _gdk_synthesize_crossing_events (display,
9266 device, source_device,
9267 source_event->crossing.mode,
9268 toplevel_x, toplevel_y,
9271 serial, non_linear);
9272 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9276 if (pointer_info->window_under_pointer != pointer_window)
9278 /* Either a toplevel crossing notify that ended up inside a child window,
9279 or a motion notify that got into another child window */
9281 /* Different than last time, send crossing events */
9282 _gdk_synthesize_crossing_events (display,
9283 pointer_info->window_under_pointer,
9285 device, source_device,
9286 GDK_CROSSING_NORMAL,
9287 toplevel_x, toplevel_y,
9290 serial, non_linear);
9291 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9293 else if (source_event->type == GDK_MOTION_NOTIFY)
9295 GdkWindow *event_win;
9299 event_win = get_event_window (display,
9308 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9309 gdk_window_get_device_events (event_win, device) == 0)
9315 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9317 gulong *device_serial;
9319 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9321 if (!device_serial ||
9322 (*device_serial != 0 &&
9323 serial < *device_serial))
9324 event_win = NULL; /* Ignore event */
9328 *device_serial = G_MAXULONG;
9332 if (event_win && !display->ignore_core_events)
9334 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9335 event->motion.time = time_;
9336 convert_toplevel_coords_to_window (event_win,
9337 toplevel_x, toplevel_y,
9338 &event->motion.x, &event->motion.y);
9339 event->motion.x_root = source_event->motion.x_root;
9340 event->motion.y_root = source_event->motion.y_root;
9341 event->motion.state = state;
9342 event->motion.is_hint = is_hint;
9343 event->motion.device = source_event->motion.device;
9344 event->motion.axes = g_memdup (source_event->motion.axes,
9345 sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
9346 gdk_event_set_source_device (event, source_device);
9350 /* unlink all move events from queue.
9351 We handle our own, including our emulated masks. */
9355 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9356 GDK_BUTTON2_MASK | \
9357 GDK_BUTTON3_MASK | \
9358 GDK_BUTTON4_MASK | \
9362 proxy_button_event (GdkEvent *source_event,
9365 GdkWindow *toplevel_window, *event_window;
9366 GdkWindow *event_win;
9367 GdkWindow *pointer_window;
9373 gdouble toplevel_x, toplevel_y;
9374 GdkDisplay *display;
9376 GdkDevice *device, *source_device;
9378 type = source_event->any.type;
9379 event_window = source_event->any.window;
9380 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9381 gdk_event_get_state (source_event, &state);
9382 time_ = gdk_event_get_time (source_event);
9383 device = gdk_event_get_device (source_event);
9384 source_device = gdk_event_get_source_device (source_event);
9385 display = gdk_window_get_display (source_event->any.window);
9386 toplevel_window = convert_native_coords_to_toplevel (event_window,
9387 toplevel_x, toplevel_y,
9388 &toplevel_x, &toplevel_y);
9390 if (type == GDK_BUTTON_PRESS &&
9391 !source_event->any.send_event &&
9392 _gdk_display_has_device_grab (display, device, serial) == NULL)
9395 _gdk_window_find_descendant_at (toplevel_window,
9396 toplevel_x, toplevel_y,
9399 /* Find the event window, that gets the grab */
9402 (parent = get_event_parent (w)) != NULL &&
9403 parent->window_type != GDK_WINDOW_ROOT)
9405 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9409 pointer_window = (GdkWindow *)w;
9411 _gdk_display_add_device_grab (display,
9417 gdk_window_get_events (pointer_window),
9421 _gdk_display_device_grab_update (display, device, source_device, serial);
9424 pointer_window = get_pointer_window (display, toplevel_window, device,
9425 toplevel_x, toplevel_y,
9428 event_win = get_event_window (display,
9434 if (event_win == NULL || display->ignore_core_events)
9437 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9438 gdk_window_get_device_events (event_win, device) == 0)
9441 event = _gdk_make_event (event_win, type, source_event, FALSE);
9445 case GDK_BUTTON_PRESS:
9446 case GDK_BUTTON_RELEASE:
9447 event->button.button = source_event->button.button;
9448 convert_toplevel_coords_to_window (event_win,
9449 toplevel_x, toplevel_y,
9450 &event->button.x, &event->button.y);
9451 event->button.x_root = source_event->button.x_root;
9452 event->button.y_root = source_event->button.y_root;
9453 event->button.state = state;
9454 event->button.device = source_event->button.device;
9455 event->button.axes = g_memdup (source_event->button.axes,
9456 sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
9458 gdk_event_set_source_device (event, source_device);
9460 if (type == GDK_BUTTON_PRESS)
9461 _gdk_event_button_generate (display, event);
9465 event->scroll.direction = source_event->scroll.direction;
9466 convert_toplevel_coords_to_window (event_win,
9467 toplevel_x, toplevel_y,
9468 &event->scroll.x, &event->scroll.y);
9469 event->scroll.x_root = source_event->scroll.x_root;
9470 event->scroll.y_root = source_event->scroll.y_root;
9471 event->scroll.state = state;
9472 event->scroll.device = source_event->scroll.device;
9473 gdk_event_set_source_device (event, source_device);
9480 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9483 #ifdef DEBUG_WINDOW_PRINTING
9485 gdk_window_print (GdkWindow *window,
9489 const char *window_types[] = {
9499 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9500 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9501 window->x, window->y,
9502 window->width, window->height
9505 if (gdk_window_has_impl (window))
9507 #ifdef GDK_WINDOWING_X11
9508 g_print (" impl(0x%lx)", gdk_x11_window_get_xid (window));
9512 if (window->window_type != GDK_WINDOW_CHILD)
9513 g_print (" %s", window_types[window->window_type]);
9515 if (window->input_only)
9516 g_print (" input-only");
9519 g_print (" shaped");
9521 if (!gdk_window_is_visible ((GdkWindow *)window))
9522 g_print (" hidden");
9524 g_print (" abs[%d,%d]",
9525 window->abs_x, window->abs_y);
9527 cairo_region_get_extents (window->clip_region, &r);
9528 if (cairo_region_is_empty (window->clip_region))
9529 g_print (" clipbox[empty]");
9531 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9538 gdk_window_print_tree (GdkWindow *window,
9540 gboolean include_input_only)
9544 if (window->input_only && !include_input_only)
9547 gdk_window_print (window, indent);
9549 for (l = window->children; l != NULL; l = l->next)
9550 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9553 #endif /* DEBUG_WINDOW_PRINTING */
9556 _gdk_windowing_got_event (GdkDisplay *display,
9561 GdkWindow *event_window;
9563 gboolean unlink_event;
9564 guint old_state, old_button;
9565 GdkDeviceGrabInfo *button_release_grab;
9566 GdkPointerWindowInfo *pointer_info;
9567 GdkDevice *device, *source_device;
9568 gboolean is_toplevel;
9570 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9571 display->last_event_time = gdk_event_get_time (event);
9573 device = gdk_event_get_device (event);
9574 source_device = gdk_event_get_source_device (event);
9580 g_object_get (device, "input-mode", &mode, NULL);
9581 _gdk_display_device_grab_update (display, device, source_device, serial);
9583 if (mode == GDK_MODE_DISABLED ||
9584 !_gdk_display_check_grab_ownership (display, device, serial))
9586 /* Device events are blocked by another
9587 * device grab, or the device is disabled
9589 unlink_event = TRUE;
9594 event_window = event->any.window;
9598 pointer_info = _gdk_display_get_pointer_info (display, device);
9600 #ifdef DEBUG_WINDOW_PRINTING
9601 if (event->type == GDK_KEY_PRESS &&
9602 (event->key.keyval == 0xa7 ||
9603 event->key.keyval == 0xbd))
9605 gdk_window_print_tree (event_window, 0,
9606 event->key.keyval == 0xbd);
9610 if (_gdk_native_windows)
9612 if (event->type == GDK_BUTTON_PRESS &&
9613 !event->any.send_event &&
9614 _gdk_display_has_device_grab (display, device, serial) == NULL)
9616 _gdk_display_add_device_grab (display,
9622 gdk_window_get_events (event_window),
9624 gdk_event_get_time (event),
9626 _gdk_display_device_grab_update (display, device, source_device, serial);
9628 if (event->type == GDK_BUTTON_RELEASE &&
9629 !event->any.send_event)
9631 button_release_grab =
9632 _gdk_display_has_device_grab (display, device, serial);
9633 if (button_release_grab &&
9634 button_release_grab->implicit &&
9635 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9637 button_release_grab->serial_end = serial;
9638 button_release_grab->implicit_ungrab = FALSE;
9639 _gdk_display_device_grab_update (display, device, source_device, serial);
9643 if (event->type == GDK_BUTTON_PRESS)
9644 _gdk_event_button_generate (display, event);
9649 if (event->type == GDK_VISIBILITY_NOTIFY)
9651 event_window->native_visibility = event->visibility.state;
9652 gdk_window_update_visibility_recursively (event_window,
9657 if (!(is_button_type (event->type) ||
9658 is_motion_type (event->type)) ||
9659 event_window->window_type == GDK_WINDOW_ROOT)
9662 is_toplevel = gdk_window_is_toplevel (event_window);
9664 if ((event->type == GDK_ENTER_NOTIFY ||
9665 event->type == GDK_LEAVE_NOTIFY) &&
9666 (event->crossing.mode == GDK_CROSSING_GRAB ||
9667 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9668 (_gdk_display_has_device_grab (display, device, serial) ||
9669 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9671 /* We synthesize all crossing events due to grabs ourselves,
9672 * so we ignore the native ones caused by our native pointer_grab
9673 * calls. Otherwise we would proxy these crossing event and cause
9674 * multiple copies of crossing events for grabs.
9676 * We do want to handle grabs from other clients though, as for
9677 * instance alt-tab in metacity causes grabs like these and
9678 * we want to handle those. Thus the has_pointer_grab check.
9680 * Implicit grabs on child windows create some grabbing events
9681 * that are sent before the button press. This means we can't
9682 * detect these with the has_pointer_grab check (as the implicit
9683 * grab is only noticed when we get button press event), so we
9684 * detect these events by checking for INFERIOR enter or leave
9685 * events. These should never be a problem to filter out.
9688 /* We ended up in this window after some (perhaps other clients)
9689 grab, so update the toplevel_under_window state */
9691 event->type == GDK_ENTER_NOTIFY &&
9692 event->crossing.mode == GDK_CROSSING_UNGRAB)
9694 if (pointer_info->toplevel_under_pointer)
9695 g_object_unref (pointer_info->toplevel_under_pointer);
9696 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9699 unlink_event = TRUE;
9703 /* Track toplevel_under_pointer */
9706 if (event->type == GDK_ENTER_NOTIFY &&
9707 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9709 if (pointer_info->toplevel_under_pointer)
9710 g_object_unref (pointer_info->toplevel_under_pointer);
9711 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9713 else if (event->type == GDK_LEAVE_NOTIFY &&
9714 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9715 pointer_info->toplevel_under_pointer == event_window)
9717 if (pointer_info->toplevel_under_pointer)
9718 g_object_unref (pointer_info->toplevel_under_pointer);
9719 pointer_info->toplevel_under_pointer = NULL;
9723 /* Store last pointer window and position/state */
9724 old_state = pointer_info->state;
9725 old_button = pointer_info->button;
9727 gdk_event_get_coords (event, &x, &y);
9728 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9729 pointer_info->toplevel_x = x;
9730 pointer_info->toplevel_y = y;
9731 gdk_event_get_state (event, &pointer_info->state);
9732 if (event->type == GDK_BUTTON_PRESS ||
9733 event->type == GDK_BUTTON_RELEASE)
9734 pointer_info->button = event->button.button;
9737 (pointer_info->state != old_state ||
9738 pointer_info->button != old_button))
9739 _gdk_display_enable_motion_hints (display, device);
9741 unlink_event = FALSE;
9742 if (is_motion_type (event->type))
9743 unlink_event = proxy_pointer_event (display,
9746 else if (is_button_type (event->type))
9747 unlink_event = proxy_button_event (event,
9750 if (event->type == GDK_BUTTON_RELEASE &&
9751 !event->any.send_event)
9753 button_release_grab =
9754 _gdk_display_has_device_grab (display, device, serial);
9755 if (button_release_grab &&
9756 button_release_grab->implicit &&
9757 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9759 button_release_grab->serial_end = serial;
9760 button_release_grab->implicit_ungrab = FALSE;
9761 _gdk_display_device_grab_update (display, device, source_device, serial);
9768 _gdk_event_queue_remove_link (display, event_link);
9769 g_list_free_1 (event_link);
9770 gdk_event_free (event);
9775 * gdk_window_create_similar_surface:
9776 * @window: window to make new surface similar to
9777 * @content: the content for the new surface
9778 * @width: width of the new surface
9779 * @height: height of the new surface
9781 * Create a new surface that is as compatible as possible with the
9782 * given @window. For example the new surface will have the same
9783 * fallback resolution and font options as @window. Generally, the new
9784 * surface will also use the same backend as @window, unless that is
9785 * not possible for some reason. The type of the returned surface may
9786 * be examined with cairo_surface_get_type().
9788 * Initially the surface contents are all 0 (transparent if contents
9789 * have transparency, black otherwise.)
9791 * Returns: a pointer to the newly allocated surface. The caller
9792 * owns the surface and should call cairo_surface_destroy() when done
9795 * This function always returns a valid pointer, but it will return a
9796 * pointer to a "nil" surface if @other is already in an error state
9797 * or any other error occurs.
9802 gdk_window_create_similar_surface (GdkWindow * window,
9803 cairo_content_t content,
9807 cairo_surface_t *window_surface, *surface;
9809 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9811 window_surface = _gdk_window_ref_cairo_surface (window);
9813 surface = cairo_surface_create_similar (window_surface,
9817 cairo_surface_destroy (window_surface);