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 #include "gdkrectangle.h"
35 #include "gdkinternals.h"
37 #include "gdkscreenprivate.h"
38 #include "gdkdisplayprivate.h"
39 #include "gdkdeviceprivate.h"
40 #include "gdkvisualprivate.h"
41 #include "gdkmarshalers.h"
42 #include "gdkwindowimpl.h"
46 #undef DEBUG_WINDOW_PRINTING
51 * @Short_description: Onscreen display areas in the target window system
54 * A #GdkWindow is a rectangular region on the screen. It's a low-level object,
55 * used to implement high-level objects such as #GtkWidget and #GtkWindow on the
56 * GTK+ level. A #GtkWindow is a toplevel window, the thing a user might think
57 * of as a "window" with a titlebar and so on; a #GtkWindow may contain many
58 * #GdkWindow<!-- -->s. For example, each #GtkButton has a #GdkWindow associated
61 * <refsect2 id="COMPOSITED-WINDOWS">
62 * <title>Composited Windows</title>
64 * Normally, the windowing system takes care of rendering the contents of a
65 * child window onto its parent window. This mechanism can be intercepted by
66 * calling gdk_window_set_composited() on the child window. For a
67 * <firstterm>composited</firstterm> window it is the responsibility of the
68 * application to render the window contents at the right spot.
70 * <example id="composited-window-example">
71 * <title>Composited windows</title>
73 * <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>
74 * </programlisting></example>
76 * In the example <xref linkend="composited-window-example"/>, a button is
77 * placed inside of an event box inside of a window. The event box is set as
78 * composited and therefore is no longer automatically drawn to the screen.
80 * When the contents of the event box change, an expose event is generated on
81 * it's parent window (which, in this case, belongs to the toplevel #GtkWindow).
82 * The expose handler for this widget is responsible for merging the changes
83 * back on the screen in the way that it wishes.
85 * In our case, we merge the contents with a 50% transparency. We also set the
86 * background colour of the window to red. The effect is that the background
87 * shows through the button.
90 * <refsect2 id="OFFSCREEN-WINDOWS">
91 * <title>Offscreen Windows</title>
93 * Offscreen windows are more general than composited windows, since they allow
94 * not only to modify the rendering of the child window onto its parent, but
95 * also to apply coordinate transformations.
97 * To integrate an offscreen window into a window hierarchy, one has to call
98 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
99 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
100 * select an offscreen child at given coordinates, and the
101 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
102 * offscreen window are used to translate coordinates between the embedder and
103 * the offscreen window.
105 * For rendering an offscreen window onto its embedder, the contents of the
106 * offscreen window are available as a surface, via
107 * gdk_offscreen_window_get_surface().
113 /* Historically a GdkWindow always matches a platform native window,
114 * be it a toplevel window or a child window. In this setup the
115 * GdkWindow (and other GdkDrawables) were platform independent classes,
116 * and the actual platform specific implementation was in a delegate
117 * object availible as "impl" in the window object.
119 * With the addition of client side windows and offscreen windows this
120 * changes a bit. The application-visible GdkWindow object behaves as
121 * it did before, but not all such windows now have a corresponding native
122 * window. Instead windows that are "client side" are emulated by the gdk
123 * code such that clipping, drawing, moving, events etc work as expected.
125 * For GdkWindows that have a native window the "impl" object is the
126 * same as before. However, for all client side windows the impl object
127 * is shared with its parent (i.e. all client windows descendants of one
128 * native window has the same impl.
130 * Additionally there is a new type of platform independent impl object,
131 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
132 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
133 * windows). Such windows work by allocating a #cairo_surface_t as the backing
134 * store for drawing operations, which is resized with the window.
136 * GdkWindows have a pointer to the "impl window" they are in, i.e.
137 * the topmost GdkWindow which have the same "impl" value. This is stored
138 * in impl_window, which is different from the window itself only for client
140 * All GdkWindows (native or not) track the position of the window in the parent
141 * (x, y), the size of the window (width, height), the position of the window
142 * with respect to the impl window (abs_x, abs_y). We also track the clip
143 * region of the window wrt parent windows and siblings, in window-relative
144 * coordinates with and without child windows included (clip_region,
145 * clip_region_with_children).
147 * All toplevel windows are native windows, but also child windows can be
148 * native (although not children of offscreens). We always listen to
149 * a basic set of events (see get_native_event_mask) for these windows
150 * so that we can emulate events for any client side children.
152 * For native windows we apply the calculated clip region as a window shape
153 * so that eg. client side siblings that overlap the native child properly
154 * draws over the native child window.
156 * In order to minimize flicker and for performance we use a couple of cacheing
157 * tricks. First of all, every time we do a window to window copy area, for instance
158 * when moving a client side window or when scrolling/moving a region in a window
159 * we store this in outstanding_moves instead of applying immediately. We then
160 * delay this move until we really need it (because something depends on being
161 * able to read it), or until we're handing a redraw from an expose/invalidation
162 * (actually we delay it past redraw, but before blitting the double buffer
163 * to the window). This gives us two advantages. First of all it minimizes the time
164 * from the window is moved to the exposes related to that move, secondly it allows
165 * us to be smart about how to do the copy. We combine multiple moves into one (when
166 * possible) and we don't actually do copies to anything that is or will be
167 * invalidated and exposed anyway.
169 * Secondly, we use something called a "implicit paint" during repaint handling.
170 * An implicit paint is similar to a regular paint for the paint stack, but it is
171 * not put on the stack. Instead, it is set on the impl window, and later when
172 * regular gdk_window_begin_paint_region() happen on a window of this impl window
173 * we reuse the surface from the implicit paint. During repaint we create and at the
174 * end flush an implicit paint, which means we can collect all the paints on
175 * multiple client side windows in the same backing store.
178 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
180 /* This adds a local value to the GdkVisibilityState enum */
181 #define GDK_VISIBILITY_NOT_VIEWABLE 3
184 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
198 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
202 struct _GdkWindowPaint
204 cairo_region_t *region;
205 cairo_surface_t *surface;
206 guint uses_implicit : 1;
212 cairo_region_t *dest_region; /* The destination region */
213 int dx, dy; /* The amount that the source was moved to reach dest_region */
214 } GdkWindowRegionMove;
218 static void gdk_window_drop_cairo_surface (GdkWindow *private);
220 static void gdk_window_free_paint_stack (GdkWindow *window);
222 static void gdk_window_finalize (GObject *object);
224 static void gdk_window_set_property (GObject *object,
228 static void gdk_window_get_property (GObject *object,
233 static void gdk_window_clear_backing_region (GdkWindow *window,
234 cairo_region_t *region);
236 static void recompute_visible_regions (GdkWindow *private,
237 gboolean recalculate_siblings,
238 gboolean recalculate_children);
239 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
240 static void gdk_window_flush_recursive (GdkWindow *window);
241 static void do_move_region_bits_on_impl (GdkWindow *window,
242 cairo_region_t *region, /* In impl window coords */
244 static void gdk_window_invalidate_in_parent (GdkWindow *private);
245 static void move_native_children (GdkWindow *private);
246 static void update_cursor (GdkDisplay *display,
248 static void impl_window_add_update_area (GdkWindow *impl_window,
249 cairo_region_t *region);
250 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
251 static void gdk_window_invalidate_region_full (GdkWindow *window,
252 const cairo_region_t *region,
253 gboolean invalidate_children,
255 static void gdk_window_invalidate_rect_full (GdkWindow *window,
256 const GdkRectangle *rect,
257 gboolean invalidate_children,
260 static guint signals[LAST_SIGNAL] = { 0 };
262 static gpointer parent_class = NULL;
264 static const cairo_user_data_key_t gdk_window_cairo_key;
267 new_region_tag (void)
269 static guint32 tag = 0;
274 G_DEFINE_ABSTRACT_TYPE (GdkWindow, gdk_window, G_TYPE_OBJECT)
277 _gdk_paintable_get_type (void)
279 static GType paintable_type = 0;
283 const GTypeInfo paintable_info =
285 sizeof (GdkPaintableIface), /* class_size */
286 NULL, /* base_init */
287 NULL, /* base_finalize */
290 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
291 g_intern_static_string ("GdkPaintable"),
294 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
297 return paintable_type;
301 gdk_window_init (GdkWindow *window)
303 /* 0-initialization is good for all other fields. */
305 window->window_type = GDK_WINDOW_CHILD;
307 window->state = GDK_WINDOW_STATE_WITHDRAWN;
310 window->toplevel_window_type = -1;
312 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
313 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
314 /* Default to unobscured since some backends don't send visibility events */
315 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
318 /* Stop and return on the first non-NULL parent */
320 accumulate_get_window (GSignalInvocationHint *ihint,
322 const GValue *handler_return,
325 g_value_copy (handler_return, return_accu);
326 /* Continue while returning NULL */
327 return g_value_get_object (handler_return) == NULL;
331 create_surface_accumulator (GSignalInvocationHint *ihint,
333 const GValue *handler_return,
336 g_value_copy (handler_return, return_accu);
338 /* Stop on the first non-NULL return value */
339 return g_value_get_boxed (handler_return) == NULL;
342 static GQuark quark_pointer_window = 0;
345 gdk_window_class_init (GdkWindowClass *klass)
347 GObjectClass *object_class = G_OBJECT_CLASS (klass);
349 parent_class = g_type_class_peek_parent (klass);
351 object_class->finalize = gdk_window_finalize;
352 object_class->set_property = gdk_window_set_property;
353 object_class->get_property = gdk_window_get_property;
355 klass->create_surface = _gdk_offscreen_window_create_surface;
357 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
365 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
366 * gdk_window_get_cursor() for details.
370 g_object_class_install_property (object_class,
372 g_param_spec_object ("cursor",
379 * GdkWindow::pick-embedded-child:
380 * @window: the window on which the signal is emitted
381 * @x: x coordinate in the window
382 * @y: y coordinate in the window
384 * The ::pick-embedded-child signal is emitted to find an embedded
385 * child at the given position.
387 * Returns: (transfer none): the #GdkWindow of the embedded child at
392 signals[PICK_EMBEDDED_CHILD] =
393 g_signal_new (g_intern_static_string ("pick-embedded-child"),
394 G_OBJECT_CLASS_TYPE (object_class),
396 G_STRUCT_OFFSET (GdkWindowClass, pick_embedded_child),
397 accumulate_get_window, NULL,
398 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
405 * GdkWindow::to-embedder:
406 * @window: the offscreen window on which the signal is emitted
407 * @offscreen-x: x coordinate in the offscreen window
408 * @offscreen-y: y coordinate in the offscreen window
409 * @embedder-x: (out) (type double): return location for the x
410 * coordinate in the embedder window
411 * @embedder-y: (out) (type double): return location for the y
412 * coordinate in the embedder window
414 * The ::to-embedder signal is emitted to translate coordinates
415 * in an offscreen window to its embedder.
417 * See also #GtkWindow::from-embedder.
421 signals[TO_EMBEDDER] =
422 g_signal_new (g_intern_static_string ("to-embedder"),
423 G_OBJECT_CLASS_TYPE (object_class),
425 G_STRUCT_OFFSET (GdkWindowClass, to_embedder),
427 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
436 * GdkWindow::from-embedder:
437 * @window: the offscreen window on which the signal is emitted
438 * @embedder-x: x coordinate in the embedder window
439 * @embedder-y: y coordinate in the embedder window
440 * @offscreen-x: (out) (type double): return location for the x
441 * coordinate in the offscreen window
442 * @offscreen-y: (out) (type double): return location for the y
443 * coordinate in the offscreen window
445 * The ::from-embedder signal is emitted to translate coordinates
446 * in the embedder of an offscreen window to the offscreen window.
448 * See also #GtkWindow::to-embedder.
452 signals[FROM_EMBEDDER] =
453 g_signal_new (g_intern_static_string ("from-embedder"),
454 G_OBJECT_CLASS_TYPE (object_class),
456 G_STRUCT_OFFSET (GdkWindowClass, from_embedder),
458 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
467 * GdkWindow::create-surface:
468 * @window: the offscreen window on which the signal is emitted
469 * @width: the width of the offscreen surface to create
470 * @height: the height of the offscreen surface to create
472 * The ::create-surface signal is emitted when an offscreen window
473 * needs its surface (re)created, which happens either when the the
474 * window is first drawn to, or when the window is being
475 * resized. The first signal handler that returns a non-%NULL
476 * surface will stop any further signal emission, and its surface
479 * Note that it is not possible to access the window's previous
480 * surface from within any callback of this signal. Calling
481 * gdk_offscreen_window_get_surface() will lead to a crash.
483 * Returns: the newly created #cairo_surface_t for the offscreen window
487 signals[CREATE_SURFACE] =
488 g_signal_new (g_intern_static_string ("create-surface"),
489 G_OBJECT_CLASS_TYPE (object_class),
491 G_STRUCT_OFFSET (GdkWindowClass, create_surface),
492 create_surface_accumulator, NULL,
493 _gdk_marshal_BOXED__INT_INT,
494 CAIRO_GOBJECT_TYPE_SURFACE,
501 device_removed_cb (GdkDeviceManager *device_manager,
505 window->devices_inside = g_list_remove (window->devices_inside, device);
506 g_hash_table_remove (window->device_cursor, device);
508 if (window->device_events)
509 g_hash_table_remove (window->device_events, device);
513 gdk_window_finalize (GObject *object)
515 GdkWindow *window = GDK_WINDOW (object);
516 GdkDeviceManager *device_manager;
518 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
519 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
521 if (!GDK_WINDOW_DESTROYED (window))
523 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
525 g_warning ("losing last reference to undestroyed window\n");
526 _gdk_window_destroy (window, FALSE);
529 /* We use TRUE here, to keep us from actually calling
530 * XDestroyWindow() on the window
532 _gdk_window_destroy (window, TRUE);
535 gdk_window_drop_cairo_surface (window);
539 g_object_unref (window->impl);
543 if (window->impl_window != window)
545 g_object_unref (window->impl_window);
546 window->impl_window = NULL;
550 cairo_region_destroy (window->shape);
552 if (window->input_shape)
553 cairo_region_destroy (window->input_shape);
556 g_object_unref (window->cursor);
558 if (window->device_cursor)
559 g_hash_table_destroy (window->device_cursor);
561 if (window->device_events)
562 g_hash_table_destroy (window->device_events);
564 if (window->source_event_masks)
565 g_hash_table_destroy (window->source_event_masks);
567 if (window->devices_inside)
568 g_list_free (window->devices_inside);
570 G_OBJECT_CLASS (parent_class)->finalize (object);
574 gdk_window_set_property (GObject *object,
579 GdkWindow *window = (GdkWindow *)object;
584 gdk_window_set_cursor (window, g_value_get_object (value));
588 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
594 gdk_window_get_property (GObject *object,
599 GdkWindow *window = (GdkWindow *) object;
604 g_value_set_object (value, gdk_window_get_cursor (window));
608 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
614 gdk_window_is_offscreen (GdkWindow *window)
616 return window->window_type == GDK_WINDOW_OFFSCREEN;
620 gdk_window_get_impl_window (GdkWindow *window)
622 return window->impl_window;
626 _gdk_window_get_impl_window (GdkWindow *window)
628 return gdk_window_get_impl_window (window);
632 gdk_window_has_impl (GdkWindow *window)
634 return window->impl_window == window;
638 gdk_window_is_toplevel (GdkWindow *window)
641 window->parent == NULL ||
642 window->parent->window_type == GDK_WINDOW_ROOT;
646 _gdk_window_has_impl (GdkWindow *window)
648 return gdk_window_has_impl (window);
652 gdk_window_has_no_impl (GdkWindow *window)
654 return window->impl_window != window;
658 remove_child_area (GdkWindow *private,
661 cairo_region_t *region)
664 cairo_region_t *child_region;
667 cairo_region_t *shape;
669 for (l = private->children; l; l = l->next)
676 /* If region is empty already, no need to do
677 anything potentially costly */
678 if (cairo_region_is_empty (region))
681 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
684 /* Ignore offscreen children, as they don't draw in their parent and
685 * don't take part in the clipping */
686 if (gdk_window_is_offscreen (child))
691 r.width = child->width;
692 r.height = child->height;
694 /* Bail early if child totally outside region */
695 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
698 child_region = cairo_region_create_rectangle (&r);
702 /* Adjust shape region to parent window coords */
703 cairo_region_translate (child->shape, child->x, child->y);
704 cairo_region_intersect (child_region, child->shape);
705 cairo_region_translate (child->shape, -child->x, -child->y);
707 else if (private->window_type == GDK_WINDOW_FOREIGN)
709 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_shape (child);
712 cairo_region_intersect (child_region, shape);
713 cairo_region_destroy (shape);
719 if (child->input_shape)
720 cairo_region_intersect (child_region, child->input_shape);
721 else if (private->window_type == GDK_WINDOW_FOREIGN)
723 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_input_shape (child);
726 cairo_region_intersect (child_region, shape);
727 cairo_region_destroy (shape);
732 cairo_region_subtract (region, child_region);
733 cairo_region_destroy (child_region);
738 static GdkVisibilityState
739 effective_visibility (GdkWindow *window)
741 GdkVisibilityState native;
743 if (!gdk_window_is_viewable (window))
744 return GDK_VISIBILITY_NOT_VIEWABLE;
746 native = window->impl_window->native_visibility;
748 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
749 window->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
750 return GDK_VISIBILITY_FULLY_OBSCURED;
751 else if (native == GDK_VISIBILITY_UNOBSCURED)
752 return window->visibility;
753 else /* native PARTIAL, private partial or unobscured */
754 return GDK_VISIBILITY_PARTIAL;
758 gdk_window_update_visibility (GdkWindow *window)
760 GdkVisibilityState new_visibility;
763 new_visibility = effective_visibility (window);
765 if (new_visibility != window->effective_visibility)
767 window->effective_visibility = new_visibility;
769 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
770 window->event_mask & GDK_VISIBILITY_NOTIFY)
772 event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY,
774 event->visibility.state = new_visibility;
780 gdk_window_update_visibility_recursively (GdkWindow *window,
781 GdkWindow *only_for_impl)
786 gdk_window_update_visibility (window);
787 for (l = window->children; l != NULL; l = l->next)
790 if ((only_for_impl == NULL) ||
791 (only_for_impl == child->impl_window))
792 gdk_window_update_visibility_recursively (child, only_for_impl);
797 should_apply_clip_as_shape (GdkWindow *window)
800 gdk_window_has_impl (window) &&
801 /* Not for offscreens */
802 !gdk_window_is_offscreen (window) &&
803 /* or for toplevels */
804 !gdk_window_is_toplevel (window) &&
805 /* or for foreign windows */
806 window->window_type != GDK_WINDOW_FOREIGN &&
807 /* or for the root window */
808 window->window_type != GDK_WINDOW_ROOT;
812 apply_shape (GdkWindow *window,
813 cairo_region_t *region)
815 GdkWindowImplClass *impl_class;
817 /* We trash whether we applied a shape so that
818 we can avoid unsetting it many times, which
819 could happen in e.g. apply_clip_as_shape as
820 windows get resized */
821 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
823 impl_class->shape_combine_region (window,
825 else if (window->applied_shape)
826 impl_class->shape_combine_region (window,
829 window->applied_shape = region != NULL;
833 region_rect_equal (const cairo_region_t *region,
834 const GdkRectangle *rect)
836 GdkRectangle extents;
838 if (cairo_region_num_rectangles (region) != 1)
841 cairo_region_get_extents (region, &extents);
843 return extents.x == rect->x &&
844 extents.y == rect->y &&
845 extents.width == rect->width &&
846 extents.height == rect->height;
850 apply_clip_as_shape (GdkWindow *window)
855 r.width = window->width;
856 r.height = window->height;
858 /* We only apply the clip region if would differ
859 from the actual clip region implied by the size
860 of the window. This is to avoid unneccessarily
861 adding meaningless shapes to all native subwindows */
862 if (!region_rect_equal (window->clip_region, &r))
863 apply_shape (window, window->clip_region);
865 apply_shape (window, NULL);
869 recompute_visible_regions_internal (GdkWindow *private,
870 gboolean recalculate_clip,
871 gboolean recalculate_siblings,
872 gboolean recalculate_children)
877 cairo_region_t *new_clip, *old_clip_region_with_children;
878 gboolean clip_region_changed;
879 gboolean abs_pos_changed;
880 int old_abs_x, old_abs_y;
882 old_abs_x = private->abs_x;
883 old_abs_y = private->abs_y;
885 /* Update absolute position */
886 if (gdk_window_has_impl (private))
888 /* Native window starts here */
894 private->abs_x = private->parent->abs_x + private->x;
895 private->abs_y = private->parent->abs_y + private->y;
899 private->abs_x != old_abs_x ||
900 private->abs_y != old_abs_y;
902 /* Update clip region based on:
905 * siblings in parents above window
907 clip_region_changed = FALSE;
908 if (recalculate_clip)
910 if (private->viewable)
912 /* Calculate visible region (sans children) in parent window coords */
915 r.width = private->width;
916 r.height = private->height;
917 new_clip = cairo_region_create_rectangle (&r);
919 if (!gdk_window_is_toplevel (private))
921 cairo_region_intersect (new_clip, private->parent->clip_region);
923 /* Remove all overlapping children from parent.
924 * Unless we're all native, because then we don't need to take
925 * siblings into account since X does that clipping for us.
926 * This makes things like SWT that modify the raw X stacking
927 * order without GDKs knowledge work.
929 if (!_gdk_native_windows)
930 remove_child_area (private->parent, private, FALSE, new_clip);
933 /* Convert from parent coords to window coords */
934 cairo_region_translate (new_clip, -private->x, -private->y);
937 cairo_region_intersect (new_clip, private->shape);
940 new_clip = cairo_region_create ();
942 if (private->clip_region == NULL ||
943 !cairo_region_equal (private->clip_region, new_clip))
944 clip_region_changed = TRUE;
946 if (private->clip_region)
947 cairo_region_destroy (private->clip_region);
948 private->clip_region = new_clip;
950 old_clip_region_with_children = private->clip_region_with_children;
951 private->clip_region_with_children = cairo_region_copy (private->clip_region);
952 if (private->window_type != GDK_WINDOW_ROOT)
953 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
955 if (clip_region_changed ||
956 !cairo_region_equal (private->clip_region_with_children, old_clip_region_with_children))
957 private->clip_tag = new_region_tag ();
959 if (old_clip_region_with_children)
960 cairo_region_destroy (old_clip_region_with_children);
963 if (clip_region_changed)
965 GdkVisibilityState visibility;
966 gboolean fully_visible;
968 if (cairo_region_is_empty (private->clip_region))
969 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
974 fully_visible = cairo_region_equal (private->clip_region,
981 r.width = private->width;
982 r.height = private->height;
983 fully_visible = region_rect_equal (private->clip_region, &r);
987 visibility = GDK_VISIBILITY_UNOBSCURED;
989 visibility = GDK_VISIBILITY_PARTIAL;
992 if (private->visibility != visibility)
994 private->visibility = visibility;
995 gdk_window_update_visibility (private);
999 /* Update all children, recursively (except for root, where children are not exact). */
1000 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1001 private->window_type != GDK_WINDOW_ROOT)
1003 for (l = private->children; l; l = l->next)
1006 /* Only recalculate clip if the the clip region changed, otherwise
1007 * there is no way the child clip region could change (its has not e.g. moved)
1008 * Except if recalculate_children is set to force child updates
1010 recompute_visible_regions_internal (child,
1011 recalculate_clip && (clip_region_changed || recalculate_children),
1016 if (clip_region_changed &&
1017 should_apply_clip_as_shape (private))
1018 apply_clip_as_shape (private);
1020 if (recalculate_siblings &&
1021 !gdk_window_is_toplevel (private))
1023 /* If we moved a child window in parent or changed the stacking order, then we
1024 * need to recompute the visible area of all the other children in the parent
1026 for (l = private->parent->children; l; l = l->next)
1030 if (child != private)
1031 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1034 /* We also need to recompute the _with_children clip for the parent */
1035 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1038 if (private->cairo_surface && gdk_window_has_impl (private))
1040 GdkWindowImplClass *iface = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1042 private->cairo_surface = iface->resize_cairo_surface (private,
1043 private->cairo_surface,
1047 else if (private->cairo_surface)
1048 gdk_window_drop_cairo_surface (private);
1051 /* Call this when private has changed in one or more of these ways:
1055 * stacking order of window changed
1058 * It will recalculate abs_x/y and the clip regions
1060 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1061 * for recalculate_siblings. (Mostly used internally for the recursion)
1063 * If a child window was removed (and you can't use that child for
1064 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1067 recompute_visible_regions (GdkWindow *private,
1068 gboolean recalculate_siblings,
1069 gboolean recalculate_children)
1071 recompute_visible_regions_internal (private,
1073 recalculate_siblings,
1074 recalculate_children);
1078 _gdk_window_update_size (GdkWindow *window)
1080 recompute_visible_regions (window, TRUE, FALSE);
1083 /* Find the native window that would be just above "child"
1084 * in the native stacking order if "child" was a native window
1085 * (it doesn't have to be native). If there is no such native
1086 * window inside this native parent then NULL is returned.
1087 * If child is NULL, find lowest native window in parent.
1090 find_native_sibling_above_helper (GdkWindow *parent,
1098 l = g_list_find (parent->children, child);
1099 g_assert (l != NULL); /* Better be a child of its parent... */
1100 l = l->prev; /* Start looking at the one above the child */
1103 l = g_list_last (parent->children);
1105 for (; l != NULL; l = l->prev)
1109 if (gdk_window_has_impl (w))
1112 g_assert (parent != w);
1113 w = find_native_sibling_above_helper (w, NULL);
1123 find_native_sibling_above (GdkWindow *parent,
1128 w = find_native_sibling_above_helper (parent, child);
1132 if (gdk_window_has_impl (parent))
1135 return find_native_sibling_above (parent->parent, parent);
1139 get_native_device_event_mask (GdkWindow *private,
1142 GdkEventMask event_mask;
1145 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1147 event_mask = private->event_mask;
1149 if (_gdk_native_windows ||
1150 private->window_type == GDK_WINDOW_ROOT ||
1151 private->window_type == GDK_WINDOW_FOREIGN)
1157 /* Do whatever the app asks to, since the app
1158 * may be asking for weird things for native windows,
1159 * but don't use motion hints as that may affect non-native
1160 * child windows that don't want it. Also, we need to
1161 * set all the app-specified masks since they will be picked
1162 * up by any implicit grabs (i.e. if they were not set as
1163 * native we would not get the events we need). */
1164 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1166 /* We need thse for all native windows so we can
1167 emulate events on children: */
1170 GDK_VISIBILITY_NOTIFY_MASK |
1171 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1173 /* Additionally we select for pointer and button events
1174 * for toplevels as we need to get these to emulate
1175 * them for non-native subwindows. Even though we don't
1176 * select on them for all native windows we will get them
1177 * as the events are propagated out to the first window
1178 * that select for them.
1179 * Not selecting for button press on all windows is an
1180 * important thing, because in X only one client can do
1181 * so, and we don't want to unexpectedly prevent another
1182 * client from doing it.
1184 * We also need to do the same if the app selects for button presses
1185 * because then we will get implicit grabs for this window, and the
1186 * event mask used for that grab is based on the rest of the mask
1187 * for the window, but we might need more events than this window
1188 * lists due to some non-native child window.
1190 if (gdk_window_is_toplevel (private) ||
1191 mask & GDK_BUTTON_PRESS_MASK)
1193 GDK_POINTER_MOTION_MASK |
1194 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1202 get_native_grab_event_mask (GdkEventMask grab_mask)
1204 /* Similar to the above but for pointer events only */
1206 GDK_POINTER_MOTION_MASK |
1207 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1208 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1211 ~GDK_POINTER_MOTION_HINT_MASK);
1215 get_native_event_mask (GdkWindow *private)
1217 return get_native_device_event_mask (private, NULL);
1220 /* Puts the native window in the right order wrt the other native windows
1221 * in the hierarchy, given the position it has in the client side data.
1222 * This is useful if some operation changed the stacking order.
1223 * This calls assumes the native window is now topmost in its native parent.
1226 sync_native_window_stack_position (GdkWindow *window)
1229 GdkWindowImplClass *impl_class;
1230 GList listhead = {0};
1232 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1234 above = find_native_sibling_above (window->parent, window);
1237 listhead.data = window;
1238 impl_class->restack_under (above, &listhead);
1243 * gdk_window_new: (constructor):
1244 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1245 * the default root window for the default display.
1246 * @attributes: attributes of the new window
1247 * @attributes_mask: mask indicating which fields in @attributes are valid
1249 * Creates a new #GdkWindow using the attributes from
1250 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1251 * more details. Note: to use this on displays other than the default
1252 * display, @parent must be specified.
1254 * Return value: (transfer full): the new #GdkWindow
1257 gdk_window_new (GdkWindow *parent,
1258 GdkWindowAttr *attributes,
1259 gint attributes_mask)
1263 GdkDisplay *display;
1266 GdkEventMask event_mask;
1267 GdkWindow *real_parent;
1268 GdkDeviceManager *device_manager;
1270 g_return_val_if_fail (attributes != NULL, NULL);
1274 GDK_NOTE (MULTIHEAD,
1275 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1277 screen = gdk_screen_get_default ();
1278 parent = gdk_screen_get_root_window (screen);
1281 screen = gdk_window_get_screen (parent);
1283 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1285 if (GDK_WINDOW_DESTROYED (parent))
1287 g_warning ("gdk_window_new(): parent is destroyed\n");
1291 if (attributes->window_type == GDK_WINDOW_OFFSCREEN &&
1292 _gdk_native_windows)
1294 g_warning ("Offscreen windows not supported with native-windows gdk");
1298 display = gdk_screen_get_display (screen);
1300 window = _gdk_display_create_window (display);
1302 /* Windows with a foreign parent are treated as if they are children
1303 * of the root window, except for actual creation.
1305 real_parent = parent;
1306 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1307 parent = gdk_screen_get_root_window (screen);
1309 window->parent = parent;
1311 window->accept_focus = TRUE;
1312 window->focus_on_map = TRUE;
1314 if (attributes_mask & GDK_WA_X)
1319 if (attributes_mask & GDK_WA_Y)
1326 window->width = (attributes->width > 1) ? (attributes->width) : (1);
1327 window->height = (attributes->height > 1) ? (attributes->height) : (1);
1329 if (attributes->wclass == GDK_INPUT_ONLY)
1331 /* Backwards compatiblity - we've always ignored
1332 * attributes->window_type for input-only windows
1335 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1336 window->window_type = GDK_WINDOW_TEMP;
1338 window->window_type = GDK_WINDOW_CHILD;
1341 window->window_type = attributes->window_type;
1344 switch (window->window_type)
1346 case GDK_WINDOW_TOPLEVEL:
1347 case GDK_WINDOW_TEMP:
1348 case GDK_WINDOW_OFFSCREEN:
1349 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1350 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1351 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1352 case GDK_WINDOW_CHILD:
1356 g_warning (G_STRLOC "cannot make windows of type %d", window->window_type);
1360 if (attributes_mask & GDK_WA_VISUAL)
1361 window->visual = attributes->visual;
1363 window->visual = gdk_screen_get_system_visual (screen);
1365 window->event_mask = attributes->event_mask;
1367 if (attributes->wclass == GDK_INPUT_OUTPUT)
1369 window->input_only = FALSE;
1370 window->depth = window->visual->depth;
1372 /* XXX: Cache this somehow? */
1373 window->background = cairo_pattern_create_rgb (0, 0, 0);
1378 window->input_only = TRUE;
1382 window->parent->children = g_list_prepend (window->parent->children, window);
1384 window->device_cursor = g_hash_table_new_full (NULL, NULL,
1385 NULL, g_object_unref);
1387 native = _gdk_native_windows; /* Default */
1388 if (window->parent->window_type == GDK_WINDOW_ROOT)
1389 native = TRUE; /* Always use native windows for toplevels */
1390 else if (!window->input_only &&
1391 (attributes_mask & GDK_WA_VISUAL &&
1392 attributes->visual != gdk_window_get_visual (window->parent)))
1393 native = TRUE; /* InputOutput window with different visual than parent, needs native window */
1395 if (gdk_window_is_offscreen (window))
1397 _gdk_offscreen_window_new (window, attributes, attributes_mask);
1398 window->impl_window = window;
1402 event_mask = get_native_event_mask (window);
1404 /* Create the impl */
1405 _gdk_display_create_window_impl (display, window, real_parent, screen, event_mask, attributes, attributes_mask);
1406 window->impl_window = window;
1408 /* This will put the native window topmost in the native parent, which may
1409 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1410 if (!_gdk_window_has_impl (real_parent))
1411 sync_native_window_stack_position (window);
1415 window->impl_window = g_object_ref (window->parent->impl_window);
1416 window->impl = g_object_ref (window->impl_window->impl);
1419 recompute_visible_regions (window, TRUE, FALSE);
1421 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1422 (attributes->cursor) :
1425 device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent));
1426 g_signal_connect (device_manager, "device-removed",
1427 G_CALLBACK (device_removed_cb), window);
1433 is_parent_of (GdkWindow *parent,
1444 w = gdk_window_get_parent (w);
1451 change_impl (GdkWindow *private,
1452 GdkWindow *impl_window,
1457 GdkWindowImpl *old_impl;
1458 GdkWindow *old_impl_window;
1460 old_impl = private->impl;
1461 old_impl_window = private->impl_window;
1462 if (private != impl_window)
1463 private->impl_window = g_object_ref (impl_window);
1465 private->impl_window = private;
1466 private->impl = g_object_ref (new);
1467 if (old_impl_window != private)
1468 g_object_unref (old_impl_window);
1469 g_object_unref (old_impl);
1471 for (l = private->children; l != NULL; l = l->next)
1475 if (child->impl == old_impl)
1476 change_impl (child, impl_window, new);
1481 reparent_to_impl (GdkWindow *private)
1486 GdkWindowImplClass *impl_class;
1488 impl_class = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1490 /* Enumerate in reverse order so we get the right order for the native
1491 windows (first in childrens list is topmost, and reparent places on top) */
1492 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1496 if (child->impl == private->impl)
1497 reparent_to_impl (child);
1500 show = impl_class->reparent ((GdkWindow *)child,
1501 (GdkWindow *)private,
1502 child->x, child->y);
1504 gdk_window_show_unraised ((GdkWindow *)child);
1511 * gdk_window_reparent:
1512 * @window: a #GdkWindow
1513 * @new_parent: new parent to move @window into
1514 * @x: X location inside the new parent
1515 * @y: Y location inside the new parent
1517 * Reparents @window into the given @new_parent. The window being
1518 * reparented will be unmapped as a side effect.
1522 gdk_window_reparent (GdkWindow *window,
1523 GdkWindow *new_parent,
1527 GdkWindow *old_parent;
1529 gboolean show, was_mapped, applied_clip_as_shape;
1530 gboolean do_reparent_to_impl;
1531 GdkEventMask old_native_event_mask;
1532 GdkWindowImplClass *impl_class;
1534 g_return_if_fail (GDK_IS_WINDOW (window));
1535 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1536 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1538 if (GDK_WINDOW_DESTROYED (window) ||
1539 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1542 screen = gdk_window_get_screen (window);
1544 new_parent = gdk_screen_get_root_window (screen);
1546 /* No input-output children of input-only windows */
1547 if (new_parent->input_only && !window->input_only)
1550 /* Don't create loops in hierarchy */
1551 if (is_parent_of (window, new_parent))
1554 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1555 To make sure we're ok, just wipe it. */
1556 gdk_window_drop_cairo_surface (window);
1558 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1559 old_parent = window->parent;
1561 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1564 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1565 if (new_parent->window_type == GDK_WINDOW_ROOT ||
1566 new_parent->window_type == GDK_WINDOW_FOREIGN)
1567 gdk_window_ensure_native (window);
1569 applied_clip_as_shape = should_apply_clip_as_shape (window);
1571 old_native_event_mask = 0;
1572 do_reparent_to_impl = FALSE;
1573 if (gdk_window_has_impl (window))
1575 old_native_event_mask = get_native_event_mask (window);
1577 show = impl_class->reparent (window, new_parent, x, y);
1581 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1582 g_assert (new_parent->window_type != GDK_WINDOW_ROOT &&
1583 new_parent->window_type != GDK_WINDOW_FOREIGN);
1586 gdk_window_hide (window);
1588 do_reparent_to_impl = TRUE;
1589 change_impl (window,
1590 new_parent->impl_window,
1594 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1597 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1599 new_parent = gdk_screen_get_root_window (screen);
1603 old_parent->children = g_list_remove (old_parent->children, window);
1605 window->parent = new_parent;
1609 new_parent->children = g_list_prepend (new_parent->children, window);
1611 /* Switch the window type as appropriate */
1613 switch (GDK_WINDOW_TYPE (new_parent))
1615 case GDK_WINDOW_ROOT:
1616 case GDK_WINDOW_FOREIGN:
1617 if (window->toplevel_window_type != -1)
1618 GDK_WINDOW_TYPE (window) = window->toplevel_window_type;
1619 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1620 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1622 case GDK_WINDOW_OFFSCREEN:
1623 case GDK_WINDOW_TOPLEVEL:
1624 case GDK_WINDOW_CHILD:
1625 case GDK_WINDOW_TEMP:
1626 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1627 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1629 /* Save the original window type so we can restore it if the
1630 * window is reparented back to be a toplevel
1632 window->toplevel_window_type = GDK_WINDOW_TYPE (window);
1633 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1637 /* We might have changed window type for a native windows, so we
1638 need to change the event mask too. */
1639 if (gdk_window_has_impl (window))
1641 GdkEventMask native_event_mask = get_native_event_mask (window);
1643 if (native_event_mask != old_native_event_mask)
1644 impl_class->set_events (window, native_event_mask);
1647 _gdk_window_update_viewable (window);
1649 recompute_visible_regions (window, TRUE, FALSE);
1650 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1651 recompute_visible_regions (old_parent, FALSE, TRUE);
1653 /* We used to apply the clip as the shape, but no more.
1654 Reset this to the real shape */
1655 if (gdk_window_has_impl (window) &&
1656 applied_clip_as_shape &&
1657 !should_apply_clip_as_shape (window))
1658 apply_shape (window, window->shape);
1660 if (do_reparent_to_impl)
1661 reparent_to_impl (window);
1664 /* The reparent will have put the native window topmost in the native parent,
1665 * which may be wrong wrt other native windows in the non-native hierarchy,
1667 if (!gdk_window_has_impl (new_parent))
1668 sync_native_window_stack_position (window);
1672 gdk_window_show_unraised (window);
1674 _gdk_synthesize_crossing_events_for_geometry_change (window);
1678 * gdk_window_ensure_native:
1679 * @window: a #GdkWindow
1681 * Tries to ensure that there is a window-system native window for this
1682 * GdkWindow. This may fail in some situations, returning %FALSE.
1684 * Offscreen window and children of them can never have native windows.
1686 * Some backends may not support native child windows.
1688 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1693 gdk_window_ensure_native (GdkWindow *window)
1695 GdkWindow *impl_window;
1696 GdkWindowImpl *new_impl, *old_impl;
1697 GdkDisplay *display;
1701 GdkWindowImplClass *impl_class;
1703 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1705 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1706 GDK_WINDOW_DESTROYED (window))
1709 impl_window = gdk_window_get_impl_window (window);
1711 if (gdk_window_is_offscreen (impl_window))
1712 return FALSE; /* native in offscreens not supported */
1714 if (impl_window == window)
1715 /* Already has an impl, and its not offscreen . */
1718 /* Need to create a native window */
1720 gdk_window_drop_cairo_surface (window);
1722 screen = gdk_window_get_screen (window);
1723 display = gdk_screen_get_display (screen);
1725 old_impl = window->impl;
1726 _gdk_display_create_window_impl (display,
1727 window, window->parent,
1729 get_native_event_mask (window),
1731 new_impl = window->impl;
1733 window->impl = old_impl;
1734 change_impl (window, window, new_impl);
1736 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1738 /* Native window creation will put the native window topmost in the
1739 * native parent, which may be wrong wrt the position of the previous
1740 * non-native window wrt to the other non-native children, so correct this.
1742 above = find_native_sibling_above (window->parent, window);
1745 listhead.data = window;
1746 listhead.prev = NULL;
1747 listhead.next = NULL;
1748 impl_class->restack_under ((GdkWindow *)above, &listhead);
1751 recompute_visible_regions (window, FALSE, FALSE);
1753 /* The shape may not have been set, as the clip region doesn't actually
1754 change, so do it here manually */
1755 if (should_apply_clip_as_shape (window))
1756 apply_clip_as_shape (window);
1758 reparent_to_impl (window);
1760 if (!window->input_only)
1761 impl_class->set_background (window, window->background);
1763 impl_class->input_shape_combine_region (window,
1764 window->input_shape,
1767 if (gdk_window_is_viewable (window))
1768 impl_class->show (window, FALSE);
1774 * _gdk_event_filter_unref:
1775 * @window: A #GdkWindow, or %NULL to be the global window
1776 * @filter: A window filter
1778 * Release a reference to @filter. Note this function may
1779 * mutate the list storage, so you need to handle this
1780 * if iterating over a list of filters.
1783 _gdk_event_filter_unref (GdkWindow *window,
1784 GdkEventFilter *filter)
1790 filters = &_gdk_default_filters;
1792 filters = &window->filters;
1794 tmp_list = *filters;
1797 GdkEventFilter *iter_filter = tmp_list->data;
1801 tmp_list = tmp_list->next;
1803 if (iter_filter != filter)
1806 g_assert (iter_filter->ref_count > 0);
1808 filter->ref_count--;
1809 if (filter->ref_count != 0)
1812 *filters = g_list_remove_link (*filters, node);
1814 g_list_free_1 (node);
1819 window_remove_filters (GdkWindow *window)
1821 while (window->filters)
1822 _gdk_event_filter_unref (window, window->filters->data);
1826 update_pointer_info_foreach (GdkDisplay *display,
1828 GdkPointerWindowInfo *pointer_info,
1831 GdkWindow *window = user_data;
1833 if (pointer_info->toplevel_under_pointer == window)
1835 g_object_unref (pointer_info->toplevel_under_pointer);
1836 pointer_info->toplevel_under_pointer = NULL;
1841 window_remove_from_pointer_info (GdkWindow *window,
1842 GdkDisplay *display)
1844 _gdk_display_pointer_info_foreach (display,
1845 update_pointer_info_foreach,
1850 * _gdk_window_destroy_hierarchy:
1851 * @window: a #GdkWindow
1852 * @recursing: If TRUE, then this is being called because a parent
1854 * @recursing_native: If TRUE, then this is being called because a native parent
1855 * was destroyed. This generally means that the call to the
1856 * windowing system to destroy the window can be omitted, since
1857 * it will be destroyed as a result of the parent being destroyed.
1858 * Unless @foreign_destroy.
1859 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1860 * external agency. The window has already been destroyed and no
1861 * windowing system calls should be made. (This may never happen
1862 * for some windowing systems.)
1864 * Internal function to destroy a window. Like gdk_window_destroy(),
1865 * but does not drop the reference count created by gdk_window_new().
1868 _gdk_window_destroy_hierarchy (GdkWindow *window,
1870 gboolean recursing_native,
1871 gboolean foreign_destroy)
1873 GdkWindowImplClass *impl_class;
1874 GdkWindow *temp_window;
1876 GdkDisplay *display;
1880 g_return_if_fail (GDK_IS_WINDOW (window));
1882 if (GDK_WINDOW_DESTROYED (window))
1885 display = gdk_window_get_display (window);
1886 screen = gdk_window_get_screen (window);
1887 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1888 if (temp_window == window)
1889 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1892 switch (window->window_type)
1894 case GDK_WINDOW_ROOT:
1895 if (!screen->closed)
1897 g_error ("attempted to destroy root window");
1900 /* else fall thru */
1901 case GDK_WINDOW_TOPLEVEL:
1902 case GDK_WINDOW_CHILD:
1903 case GDK_WINDOW_TEMP:
1904 case GDK_WINDOW_FOREIGN:
1905 case GDK_WINDOW_OFFSCREEN:
1906 if (window->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
1908 /* Logically, it probably makes more sense to send
1909 * a "destroy yourself" message to the foreign window
1910 * whether or not it's in our hierarchy; but for historical
1911 * reasons, we only send "destroy yourself" messages to
1912 * foreign windows in our hierarchy.
1916 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1918 if (gdk_window_has_impl (window))
1919 impl_class->destroy_foreign (window);
1922 /* Also for historical reasons, we remove any filters
1923 * on a foreign window when it or a parent is destroyed;
1924 * this likely causes problems if two separate portions
1925 * of code are maintaining filter lists on a foreign window.
1927 window_remove_filters (window);
1933 if (window->parent->children)
1934 window->parent->children = g_list_remove (window->parent->children, window);
1937 GDK_WINDOW_IS_MAPPED (window))
1939 recompute_visible_regions (window, TRUE, FALSE);
1940 gdk_window_invalidate_in_parent (window);
1944 gdk_window_free_paint_stack (window);
1946 if (window->background)
1948 cairo_pattern_destroy (window->background);
1949 window->background = NULL;
1952 if (window->window_type == GDK_WINDOW_FOREIGN)
1953 g_assert (window->children == NULL);
1956 children = tmp = window->children;
1957 window->children = NULL;
1961 temp_window = tmp->data;
1965 _gdk_window_destroy_hierarchy (temp_window,
1967 recursing_native || gdk_window_has_impl (window),
1971 g_list_free (children);
1974 _gdk_window_clear_update_area (window);
1976 gdk_window_drop_cairo_surface (window);
1978 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1980 if (gdk_window_has_impl (window))
1981 impl_class->destroy (window, recursing_native,
1985 /* hide to make sure we repaint and break grabs */
1986 gdk_window_hide (window);
1989 window->state |= GDK_WINDOW_STATE_WITHDRAWN;
1990 window->parent = NULL;
1991 window->destroyed = TRUE;
1993 window_remove_filters (window);
1995 window_remove_from_pointer_info (window, display);
1997 if (window->clip_region)
1999 cairo_region_destroy (window->clip_region);
2000 window->clip_region = NULL;
2003 if (window->clip_region_with_children)
2005 cairo_region_destroy (window->clip_region_with_children);
2006 window->clip_region_with_children = NULL;
2009 if (window->outstanding_moves)
2011 g_list_foreach (window->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
2012 g_list_free (window->outstanding_moves);
2013 window->outstanding_moves = NULL;
2021 * _gdk_window_destroy:
2022 * @window: a #GdkWindow
2023 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2024 * external agency. The window has already been destroyed and no
2025 * windowing system calls should be made. (This may never happen
2026 * for some windowing systems.)
2028 * Internal function to destroy a window. Like gdk_window_destroy(),
2029 * but does not drop the reference count created by gdk_window_new().
2032 _gdk_window_destroy (GdkWindow *window,
2033 gboolean foreign_destroy)
2035 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2039 * gdk_window_destroy:
2040 * @window: a #GdkWindow
2042 * Destroys the window system resources associated with @window and decrements @window's
2043 * reference count. The window system resources for all children of @window are also
2044 * destroyed, but the children's reference counts are not decremented.
2046 * Note that a window will not be destroyed automatically when its reference count
2047 * reaches zero. You must call this function yourself before that happens.
2051 gdk_window_destroy (GdkWindow *window)
2053 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2054 g_object_unref (window);
2058 * gdk_window_set_user_data:
2059 * @window: a #GdkWindow
2060 * @user_data: user data
2062 * For most purposes this function is deprecated in favor of
2063 * g_object_set_data(). However, for historical reasons GTK+ stores
2064 * the #GtkWidget that owns a #GdkWindow as user data on the
2065 * #GdkWindow. So, custom widget implementations should use
2066 * this function for that. If GTK+ receives an event for a #GdkWindow,
2067 * and the user data for the window is non-%NULL, GTK+ will assume the
2068 * user data is a #GtkWidget, and forward the event to that widget.
2072 gdk_window_set_user_data (GdkWindow *window,
2075 g_return_if_fail (GDK_IS_WINDOW (window));
2077 window->user_data = user_data;
2081 * gdk_window_get_user_data:
2082 * @window: a #GdkWindow
2083 * @data: (out): return location for user data
2085 * Retrieves the user data for @window, which is normally the widget
2086 * that @window belongs to. See gdk_window_set_user_data().
2090 gdk_window_get_user_data (GdkWindow *window,
2093 g_return_if_fail (GDK_IS_WINDOW (window));
2095 *data = window->user_data;
2099 * gdk_window_get_window_type:
2100 * @window: a #GdkWindow
2102 * Gets the type of the window. See #GdkWindowType.
2104 * Return value: type of window
2107 gdk_window_get_window_type (GdkWindow *window)
2109 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2111 return GDK_WINDOW_TYPE (window);
2115 * gdk_window_get_visual:
2116 * @window: a #GdkWindow
2118 * Gets the #GdkVisual describing the pixel format of @window.
2120 * Return value: (transfer none): a #GdkVisual
2125 gdk_window_get_visual (GdkWindow *window)
2127 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2129 return window->visual;
2133 * gdk_window_get_screen:
2134 * @window: a #GdkWindow
2136 * Gets the #GdkScreen associated with a #GdkWindow.
2138 * Return value: (transfer none): the #GdkScreen associated with @window
2143 gdk_window_get_screen (GdkWindow *window)
2145 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2147 return gdk_visual_get_screen (window->visual);
2151 * gdk_window_get_display:
2152 * @window: a #GdkWindow
2154 * Gets the #GdkDisplay associated with a #GdkWindow.
2156 * Return value: (transfer none): the #GdkDisplay associated with @window
2161 gdk_window_get_display (GdkWindow *window)
2163 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2165 return gdk_screen_get_display (gdk_visual_get_screen (window->visual));
2168 * gdk_window_is_destroyed:
2169 * @window: a #GdkWindow
2171 * Check to see if a window is destroyed..
2173 * Return value: %TRUE if the window is destroyed
2178 gdk_window_is_destroyed (GdkWindow *window)
2180 return GDK_WINDOW_DESTROYED (window);
2184 to_embedder (GdkWindow *window,
2185 gdouble offscreen_x,
2186 gdouble offscreen_y,
2187 gdouble *embedder_x,
2188 gdouble *embedder_y)
2190 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2191 offscreen_x, offscreen_y,
2192 embedder_x, embedder_y);
2196 from_embedder (GdkWindow *window,
2199 gdouble *offscreen_x,
2200 gdouble *offscreen_y)
2202 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2203 embedder_x, embedder_y,
2204 offscreen_x, offscreen_y);
2208 * gdk_window_has_native:
2209 * @window: a #GdkWindow
2211 * Checks whether the window has a native window or not. Note that
2212 * you can use gdk_window_ensure_native() if a native window is needed.
2214 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2219 gdk_window_has_native (GdkWindow *window)
2221 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2223 return window->parent == NULL || window->parent->impl != window->impl;
2227 * gdk_window_get_position:
2228 * @window: a #GdkWindow
2229 * @x: (out) (allow-none): X coordinate of window
2230 * @y: (out) (allow-none): Y coordinate of window
2232 * Obtains the position of the window as reported in the
2233 * most-recently-processed #GdkEventConfigure. Contrast with
2234 * gdk_window_get_geometry() which queries the X server for the
2235 * current window position, regardless of which events have been
2236 * received or processed.
2238 * The position coordinates are relative to the window's parent window.
2242 gdk_window_get_position (GdkWindow *window,
2246 g_return_if_fail (GDK_IS_WINDOW (window));
2255 * gdk_window_get_parent:
2256 * @window: a #GdkWindow
2258 * Obtains the parent of @window, as known to GDK. Does not query the
2259 * X server; thus this returns the parent as passed to gdk_window_new(),
2260 * not the actual parent. This should never matter unless you're using
2261 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2262 * matter for toplevel windows, because the window manager may choose
2265 * Note that you should use gdk_window_get_effective_parent() when
2266 * writing generic code that walks up a window hierarchy, because
2267 * gdk_window_get_parent() will most likely not do what you expect if
2268 * there are offscreen windows in the hierarchy.
2270 * Return value: (transfer none): parent of @window
2273 gdk_window_get_parent (GdkWindow *window)
2275 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2277 return window->parent;
2281 * gdk_window_get_effective_parent:
2282 * @window: a #GdkWindow
2284 * Obtains the parent of @window, as known to GDK. Works like
2285 * gdk_window_get_parent() for normal windows, but returns the
2286 * window's embedder for offscreen windows.
2288 * See also: gdk_offscreen_window_get_embedder()
2290 * Return value: (transfer none): effective parent of @window
2295 gdk_window_get_effective_parent (GdkWindow *window)
2297 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2299 if (gdk_window_is_offscreen (window))
2300 return gdk_offscreen_window_get_embedder (window);
2302 return window->parent;
2306 * gdk_window_get_toplevel:
2307 * @window: a #GdkWindow
2309 * Gets the toplevel window that's an ancestor of @window.
2311 * Any window type but %GDK_WINDOW_CHILD is considered a
2312 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2313 * has a root window as parent.
2315 * Note that you should use gdk_window_get_effective_toplevel() when
2316 * you want to get to a window's toplevel as seen on screen, because
2317 * gdk_window_get_toplevel() will most likely not do what you expect
2318 * if there are offscreen windows in the hierarchy.
2320 * Return value: (transfer none): the toplevel window containing @window
2323 gdk_window_get_toplevel (GdkWindow *window)
2325 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2327 while (window->window_type == GDK_WINDOW_CHILD)
2329 if (gdk_window_is_toplevel (window))
2331 window = window->parent;
2338 * gdk_window_get_effective_toplevel:
2339 * @window: a #GdkWindow
2341 * Gets the toplevel window that's an ancestor of @window.
2343 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2344 * embedder as its parent, using gdk_window_get_effective_parent().
2346 * See also: gdk_offscreen_window_get_embedder()
2348 * Return value: (transfer none): the effective toplevel window containing @window
2353 gdk_window_get_effective_toplevel (GdkWindow *window)
2357 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2359 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2360 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2367 * gdk_window_get_children:
2368 * @window: a #GdkWindow
2370 * Gets the list of children of @window known to GDK.
2371 * This function only returns children created via GDK,
2372 * so for example it's useless when used with the root window;
2373 * it only returns windows an application created itself.
2375 * The returned list must be freed, but the elements in the
2378 * Return value: (transfer container) (element-type GdkWindow):
2379 * list of child windows inside @window
2382 gdk_window_get_children (GdkWindow *window)
2384 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2386 if (GDK_WINDOW_DESTROYED (window))
2389 return g_list_copy (window->children);
2393 * gdk_window_peek_children:
2394 * @window: a #GdkWindow
2396 * Like gdk_window_get_children(), but does not copy the list of
2397 * children, so the list does not need to be freed.
2399 * Return value: (transfer none) (element-type GdkWindow):
2400 * a reference to the list of child windows in @window
2403 gdk_window_peek_children (GdkWindow *window)
2405 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2407 if (GDK_WINDOW_DESTROYED (window))
2410 return window->children;
2414 * gdk_window_add_filter: (skip)
2415 * @window: a #GdkWindow
2416 * @function: filter callback
2417 * @data: data to pass to filter callback
2419 * Adds an event filter to @window, allowing you to intercept events
2420 * before they reach GDK. This is a low-level operation and makes it
2421 * easy to break GDK and/or GTK+, so you have to know what you're
2422 * doing. Pass %NULL for @window to get all events for all windows,
2423 * instead of events for a specific window.
2425 * See gdk_display_add_client_message_filter() if you are interested
2426 * in X ClientMessage events.
2429 gdk_window_add_filter (GdkWindow *window,
2430 GdkFilterFunc function,
2434 GdkEventFilter *filter;
2436 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2438 if (window && GDK_WINDOW_DESTROYED (window))
2441 /* Filters are for the native events on the native window, so
2442 ensure there is a native window. */
2444 gdk_window_ensure_native (window);
2447 tmp_list = window->filters;
2449 tmp_list = _gdk_default_filters;
2453 filter = (GdkEventFilter *)tmp_list->data;
2454 if ((filter->function == function) && (filter->data == data))
2456 filter->ref_count++;
2459 tmp_list = tmp_list->next;
2462 filter = g_new (GdkEventFilter, 1);
2463 filter->function = function;
2464 filter->data = data;
2465 filter->ref_count = 1;
2469 window->filters = g_list_append (window->filters, filter);
2471 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2475 * gdk_window_remove_filter: (skip)
2476 * @window: a #GdkWindow
2477 * @function: previously-added filter function
2478 * @data: user data for previously-added filter function
2480 * Remove a filter previously added with gdk_window_add_filter().
2483 gdk_window_remove_filter (GdkWindow *window,
2484 GdkFilterFunc function,
2488 GdkEventFilter *filter;
2490 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2493 tmp_list = window->filters;
2495 tmp_list = _gdk_default_filters;
2499 filter = (GdkEventFilter *)tmp_list->data;
2500 tmp_list = tmp_list->next;
2502 if ((filter->function == function) && (filter->data == data))
2504 filter->flags |= GDK_EVENT_FILTER_REMOVED;
2506 _gdk_event_filter_unref (window, filter);
2514 * gdk_screen_get_toplevel_windows:
2515 * @screen: The #GdkScreen where the toplevels are located.
2517 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2518 * A toplevel window is a child of the root window (see
2519 * gdk_get_default_root_window()).
2521 * The returned list should be freed with g_list_free(), but
2522 * its elements need not be freed.
2524 * Return value: (transfer container) (element-type GdkWindow):
2525 * list of toplevel windows, free with g_list_free()
2530 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2532 GdkWindow * root_window;
2533 GList *new_list = NULL;
2536 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2538 root_window = gdk_screen_get_root_window (screen);
2540 tmp_list = root_window->children;
2543 GdkWindow *w = tmp_list->data;
2545 if (w->window_type != GDK_WINDOW_FOREIGN)
2546 new_list = g_list_prepend (new_list, w);
2547 tmp_list = tmp_list->next;
2554 * gdk_window_is_visible:
2555 * @window: a #GdkWindow
2557 * Checks whether the window has been mapped (with gdk_window_show() or
2558 * gdk_window_show_unraised()).
2560 * Return value: %TRUE if the window is mapped
2563 gdk_window_is_visible (GdkWindow *window)
2565 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2567 return GDK_WINDOW_IS_MAPPED (window);
2571 * gdk_window_is_viewable:
2572 * @window: a #GdkWindow
2574 * Check if the window and all ancestors of the window are
2575 * mapped. (This is not necessarily "viewable" in the X sense, since
2576 * we only check as far as we have GDK window parents, not to the root
2579 * Return value: %TRUE if the window is viewable
2582 gdk_window_is_viewable (GdkWindow *window)
2584 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2586 if (window->destroyed)
2589 return window->viewable;
2593 * gdk_window_get_state:
2594 * @window: a #GdkWindow
2596 * Gets the bitwise OR of the currently active window state flags,
2597 * from the #GdkWindowState enumeration.
2599 * Return value: window state bitfield
2602 gdk_window_get_state (GdkWindow *window)
2604 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2606 return window->state;
2609 static cairo_content_t
2610 gdk_window_get_content (GdkWindow *window)
2612 cairo_surface_t *surface;
2613 cairo_content_t content;
2615 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2617 surface = _gdk_window_ref_cairo_surface (window);
2618 content = cairo_surface_get_content (surface);
2619 cairo_surface_destroy (surface);
2624 /* This creates an empty "implicit" paint region for the impl window.
2625 * By itself this does nothing, but real paints to this window
2626 * or children of it can use this surface as backing to avoid allocating
2627 * multiple surfaces for subwindow rendering. When doing so they
2628 * add to the region of the implicit paint region, which will be
2629 * pushed to the window when the implicit paint region is ended.
2630 * Such paints should not copy anything to the window on paint end, but
2631 * should rely on the implicit paint end.
2632 * The implicit paint will be automatically ended if someone draws
2633 * directly to the window or a child window.
2636 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2638 GdkWindowPaint *paint;
2640 g_assert (gdk_window_has_impl (window));
2642 if (_gdk_native_windows)
2643 return FALSE; /* No need for implicit paints since we can't merge draws anyway */
2645 if (GDK_IS_PAINTABLE (window->impl))
2646 return FALSE; /* Implementation does double buffering */
2648 if (window->paint_stack != NULL ||
2649 window->implicit_paint != NULL)
2650 return FALSE; /* Don't stack implicit paints */
2652 /* Never do implicit paints for foreign windows, they don't need
2653 * double buffer combination since they have no client side children,
2654 * and creating surfaces for them is risky since they could disappear
2657 if (window->window_type == GDK_WINDOW_FOREIGN)
2660 paint = g_new (GdkWindowPaint, 1);
2661 paint->region = cairo_region_create (); /* Empty */
2662 paint->uses_implicit = FALSE;
2663 paint->flushed = FALSE;
2664 paint->surface = gdk_window_create_similar_surface (window,
2665 gdk_window_get_content (window),
2666 MAX (rect->width, 1),
2667 MAX (rect->height, 1));
2668 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2670 window->implicit_paint = paint;
2675 static cairo_surface_t *
2676 gdk_window_ref_impl_surface (GdkWindow *window)
2678 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->ref_cairo_surface (gdk_window_get_impl_window (window));
2682 gdk_cairo_create_for_impl (GdkWindow *window)
2684 cairo_surface_t *surface;
2687 surface = gdk_window_ref_impl_surface (window);
2688 cr = cairo_create (surface);
2690 cairo_surface_destroy (surface);
2695 /* Ensure that all content related to this (sub)window is pushed to the
2696 native region. If there is an active paint then that area is not
2697 pushed, in order to not show partially finished double buffers. */
2699 gdk_window_flush_implicit_paint (GdkWindow *window)
2701 GdkWindow *impl_window;
2702 GdkWindowPaint *paint;
2703 cairo_region_t *region;
2706 impl_window = gdk_window_get_impl_window (window);
2707 if (impl_window->implicit_paint == NULL)
2710 paint = impl_window->implicit_paint;
2711 paint->flushed = TRUE;
2712 region = cairo_region_copy (window->clip_region_with_children);
2714 /* Don't flush active double buffers, as that may show partially done
2716 for (list = window->paint_stack; list != NULL; list = list->next)
2718 GdkWindowPaint *tmp_paint = list->data;
2720 cairo_region_subtract (region, tmp_paint->region);
2723 cairo_region_translate (region, -window->abs_x, -window->abs_y);
2724 cairo_region_intersect (region, paint->region);
2726 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2730 /* Remove flushed region from the implicit paint */
2731 cairo_region_subtract (paint->region, region);
2733 /* Some regions are valid, push these to window now */
2734 cr = gdk_cairo_create_for_impl (window);
2735 gdk_cairo_region (cr, region);
2737 cairo_set_source_surface (cr, paint->surface, 0, 0);
2738 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2743 cairo_region_destroy (region);
2746 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2748 gdk_window_end_implicit_paint (GdkWindow *window)
2750 GdkWindowPaint *paint;
2752 g_assert (gdk_window_has_impl (window));
2754 g_assert (window->implicit_paint != NULL);
2756 paint = window->implicit_paint;
2758 window->implicit_paint = NULL;
2760 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2764 /* Some regions are valid, push these to window now */
2765 cr = gdk_cairo_create_for_impl (window);
2766 gdk_cairo_region (cr, paint->region);
2768 cairo_set_source_surface (cr, paint->surface, 0, 0);
2769 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2774 cairo_region_destroy (paint->region);
2776 cairo_surface_destroy (paint->surface);
2781 * gdk_window_begin_paint_rect:
2782 * @window: a #GdkWindow
2783 * @rectangle: rectangle you intend to draw to
2785 * A convenience wrapper around gdk_window_begin_paint_region() which
2786 * creates a rectangular region for you. See
2787 * gdk_window_begin_paint_region() for details.
2791 gdk_window_begin_paint_rect (GdkWindow *window,
2792 const GdkRectangle *rectangle)
2794 cairo_region_t *region;
2796 g_return_if_fail (GDK_IS_WINDOW (window));
2798 region = cairo_region_create_rectangle (rectangle);
2799 gdk_window_begin_paint_region (window, region);
2800 cairo_region_destroy (region);
2804 * gdk_window_begin_paint_region:
2805 * @window: a #GdkWindow
2806 * @region: region you intend to draw to
2808 * Indicates that you are beginning the process of redrawing @region.
2809 * A backing store (offscreen buffer) large enough to contain @region
2810 * will be created. The backing store will be initialized with the
2811 * background color or background surface for @window. Then, all
2812 * drawing operations performed on @window will be diverted to the
2813 * backing store. When you call gdk_window_end_paint(), the backing
2814 * store will be copied to @window, making it visible onscreen. Only
2815 * the part of @window contained in @region will be modified; that is,
2816 * drawing operations are clipped to @region.
2818 * The net result of all this is to remove flicker, because the user
2819 * sees the finished product appear all at once when you call
2820 * gdk_window_end_paint(). If you draw to @window directly without
2821 * calling gdk_window_begin_paint_region(), the user may see flicker
2822 * as individual drawing operations are performed in sequence. The
2823 * clipping and background-initializing features of
2824 * gdk_window_begin_paint_region() are conveniences for the
2825 * programmer, so you can avoid doing that work yourself.
2827 * When using GTK+, the widget system automatically places calls to
2828 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2829 * emissions of the expose_event signal. That is, if you're writing an
2830 * expose event handler, you can assume that the exposed area in
2831 * #GdkEventExpose has already been cleared to the window background,
2832 * is already set as the clip region, and already has a backing store.
2833 * Therefore in most cases, application code need not call
2834 * gdk_window_begin_paint_region(). (You can disable the automatic
2835 * calls around expose events on a widget-by-widget basis by calling
2836 * gtk_widget_set_double_buffered().)
2838 * If you call this function multiple times before calling the
2839 * matching gdk_window_end_paint(), the backing stores are pushed onto
2840 * a stack. gdk_window_end_paint() copies the topmost backing store
2841 * onscreen, subtracts the topmost region from all other regions in
2842 * the stack, and pops the stack. All drawing operations affect only
2843 * the topmost backing store in the stack. One matching call to
2844 * gdk_window_end_paint() is required for each call to
2845 * gdk_window_begin_paint_region().
2849 gdk_window_begin_paint_region (GdkWindow *window,
2850 const cairo_region_t *region)
2852 #ifdef USE_BACKING_STORE
2853 GdkRectangle clip_box;
2854 GdkWindowPaint *paint, *implicit_paint;
2855 GdkWindow *impl_window;
2858 g_return_if_fail (GDK_IS_WINDOW (window));
2860 if (GDK_WINDOW_DESTROYED (window))
2863 if (GDK_IS_PAINTABLE (window->impl))
2865 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
2867 if (iface->begin_paint_region)
2868 iface->begin_paint_region ((GdkPaintable*)window->impl, window, region);
2873 impl_window = gdk_window_get_impl_window (window);
2874 implicit_paint = impl_window->implicit_paint;
2876 paint = g_new (GdkWindowPaint, 1);
2877 paint->region = cairo_region_copy (region);
2878 paint->region_tag = new_region_tag ();
2880 cairo_region_intersect (paint->region, window->clip_region_with_children);
2881 cairo_region_get_extents (paint->region, &clip_box);
2883 cairo_region_translate (paint->region, window->abs_x, window->abs_y);
2885 /* Mark the region as valid on the implicit paint */
2888 cairo_region_union (implicit_paint->region, paint->region);
2890 /* Convert back to normal coords */
2891 cairo_region_translate (paint->region, -window->abs_x, -window->abs_y);
2895 paint->uses_implicit = TRUE;
2896 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
2897 window->abs_x + clip_box.x,
2898 window->abs_y + clip_box.y,
2899 MAX (clip_box.width, 1),
2900 MAX (clip_box.height, 1));
2904 paint->uses_implicit = FALSE;
2905 paint->surface = gdk_window_create_similar_surface (window,
2906 gdk_window_get_content (window),
2907 MAX (clip_box.width, 1),
2908 MAX (clip_box.height, 1));
2910 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
2912 for (list = window->paint_stack; list != NULL; list = list->next)
2914 GdkWindowPaint *tmp_paint = list->data;
2916 cairo_region_subtract (tmp_paint->region, paint->region);
2919 window->paint_stack = g_slist_prepend (window->paint_stack, paint);
2921 if (!cairo_region_is_empty (paint->region))
2923 gdk_window_clear_backing_region (window,
2927 #endif /* USE_BACKING_STORE */
2931 * gdk_window_end_paint:
2932 * @window: a #GdkWindow
2934 * Indicates that the backing store created by the most recent call to
2935 * gdk_window_begin_paint_region() should be copied onscreen and
2936 * deleted, leaving the next-most-recent backing store or no backing
2937 * store at all as the active paint region. See
2938 * gdk_window_begin_paint_region() for full details. It is an error to
2939 * call this function without a matching
2940 * gdk_window_begin_paint_region() first.
2944 gdk_window_end_paint (GdkWindow *window)
2946 #ifdef USE_BACKING_STORE
2947 GdkWindow *composited;
2948 GdkWindowPaint *paint;
2949 GdkRectangle clip_box;
2950 cairo_region_t *full_clip;
2952 g_return_if_fail (GDK_IS_WINDOW (window));
2954 if (GDK_WINDOW_DESTROYED (window))
2957 if (GDK_IS_PAINTABLE (window->impl))
2959 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
2961 if (iface->end_paint)
2962 iface->end_paint ((GdkPaintable*)window->impl);
2966 if (window->paint_stack == NULL)
2968 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
2972 paint = window->paint_stack->data;
2974 window->paint_stack = g_slist_delete_link (window->paint_stack,
2975 window->paint_stack);
2977 cairo_region_get_extents (paint->region, &clip_box);
2979 if (!paint->uses_implicit)
2983 gdk_window_flush_outstanding_moves (window);
2985 full_clip = cairo_region_copy (window->clip_region_with_children);
2986 cairo_region_intersect (full_clip, paint->region);
2988 cr = gdk_cairo_create (window);
2989 cairo_set_source_surface (cr, paint->surface, 0, 0);
2990 gdk_cairo_region (cr, full_clip);
2994 cairo_region_destroy (full_clip);
2997 cairo_surface_destroy (paint->surface);
2998 cairo_region_destroy (paint->region);
3001 /* find a composited window in our hierarchy to signal its
3002 * parent to redraw, calculating the clip box as we go...
3004 * stop if parent becomes NULL since then we'd have nowhere
3005 * to draw (ie: 'composited' will always be non-NULL here).
3007 for (composited = window;
3009 composited = composited->parent)
3011 clip_box.x += composited->x;
3012 clip_box.y += composited->y;
3013 clip_box.width = MIN (clip_box.width, composited->parent->width - clip_box.x);
3014 clip_box.height = MIN (clip_box.height, composited->parent->height - clip_box.y);
3016 if (composited->composited)
3018 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3023 #endif /* USE_BACKING_STORE */
3027 gdk_window_free_paint_stack (GdkWindow *window)
3029 if (window->paint_stack)
3031 GSList *tmp_list = window->paint_stack;
3035 GdkWindowPaint *paint = tmp_list->data;
3037 if (tmp_list == window->paint_stack)
3038 cairo_surface_destroy (paint->surface);
3040 cairo_region_destroy (paint->region);
3043 tmp_list = tmp_list->next;
3046 g_slist_free (window->paint_stack);
3047 window->paint_stack = NULL;
3052 do_move_region_bits_on_impl (GdkWindow *impl_window,
3053 cairo_region_t *dest_region, /* In impl window coords */
3056 GdkWindowImplClass *impl_class;
3058 impl_class = GDK_WINDOW_IMPL_GET_CLASS (impl_window->impl);
3060 impl_class->translate (impl_window, dest_region, dx, dy);
3063 static GdkWindowRegionMove *
3064 gdk_window_region_move_new (cairo_region_t *region,
3067 GdkWindowRegionMove *move;
3069 move = g_slice_new (GdkWindowRegionMove);
3070 move->dest_region = cairo_region_copy (region);
3078 gdk_window_region_move_free (GdkWindowRegionMove *move)
3080 cairo_region_destroy (move->dest_region);
3081 g_slice_free (GdkWindowRegionMove, move);
3085 append_move_region (GdkWindow *impl_window,
3086 cairo_region_t *new_dest_region,
3089 GdkWindowRegionMove *move, *old_move;
3090 cairo_region_t *new_total_region, *old_total_region;
3091 cairo_region_t *source_overlaps_destination;
3092 cairo_region_t *non_overwritten;
3093 gboolean added_move;
3096 if (cairo_region_is_empty (new_dest_region))
3099 /* In principle this could just append the move to the list of outstanding
3100 moves that will be replayed before drawing anything when we're handling
3101 exposes. However, we'd like to do a bit better since its commonly the case
3102 that we get multiple copies where A is copied to B and then B is copied
3103 to C, and we'd like to express this as a simple copy A to C operation. */
3105 /* We approach this by taking the new move and pushing it ahead of moves
3106 starting at the end of the list and stopping when its not safe to do so.
3107 It's not safe to push past a move if either the source of the new move
3108 is in the destination of the old move, or if the destination of the new
3109 move is in the source of the new move, or if the destination of the new
3110 move overlaps the destination of the old move. We simplify this by
3111 just comparing the total regions (src + dest) */
3112 new_total_region = cairo_region_copy (new_dest_region);
3113 cairo_region_translate (new_total_region, -dx, -dy);
3114 cairo_region_union (new_total_region, new_dest_region);
3117 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3122 old_total_region = cairo_region_copy (old_move->dest_region);
3123 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3124 cairo_region_union (old_total_region, old_move->dest_region);
3126 cairo_region_intersect (old_total_region, new_total_region);
3127 /* If these regions intersect then its not safe to push the
3128 new region before the old one */
3129 if (!cairo_region_is_empty (old_total_region))
3131 /* The area where the new moves source overlaps the old ones
3133 source_overlaps_destination = cairo_region_copy (new_dest_region);
3134 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3135 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3136 cairo_region_translate (source_overlaps_destination, dx, dy);
3138 /* We can do all sort of optimizations here, but to do things safely it becomes
3139 quite complicated. However, a very common case is that you copy something first,
3140 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3141 in the same direction). We'd like to detect this case and optimize it to one
3143 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3145 /* This means we might be able to replace the old move and the new one
3146 with the new one read from the old ones source, and a second copy of
3147 the non-overwritten parts of the old move. However, such a split
3148 is only valid if the source in the old move isn't overwritten
3149 by the destination of the new one */
3151 /* the new destination of old move if split is ok: */
3152 non_overwritten = cairo_region_copy (old_move->dest_region);
3153 cairo_region_subtract (non_overwritten, new_dest_region);
3154 /* move to source region */
3155 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3157 cairo_region_intersect (non_overwritten, new_dest_region);
3158 if (cairo_region_is_empty (non_overwritten))
3161 move = gdk_window_region_move_new (new_dest_region,
3165 impl_window->outstanding_moves =
3166 g_list_insert_before (impl_window->outstanding_moves,
3168 cairo_region_subtract (old_move->dest_region, new_dest_region);
3170 cairo_region_destroy (non_overwritten);
3173 cairo_region_destroy (source_overlaps_destination);
3174 cairo_region_destroy (old_total_region);
3177 cairo_region_destroy (old_total_region);
3180 cairo_region_destroy (new_total_region);
3184 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3187 impl_window->outstanding_moves =
3188 g_list_prepend (impl_window->outstanding_moves,
3191 impl_window->outstanding_moves =
3192 g_list_insert_before (impl_window->outstanding_moves,
3197 /* Moves bits and update area by dx/dy in impl window.
3198 Takes ownership of region to avoid copy (because we may change it) */
3200 move_region_on_impl (GdkWindow *impl_window,
3201 cairo_region_t *region, /* In impl window coords */
3204 if ((dx == 0 && dy == 0) ||
3205 cairo_region_is_empty (region))
3207 cairo_region_destroy (region);
3211 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3213 /* Move any old invalid regions in the copy source area by dx/dy */
3214 if (impl_window->update_area)
3216 cairo_region_t *update_area;
3218 update_area = cairo_region_copy (region);
3220 /* Convert from target to source */
3221 cairo_region_translate (update_area, -dx, -dy);
3222 cairo_region_intersect (update_area, impl_window->update_area);
3223 /* We only copy the area, so keep the old update area invalid.
3224 It would be safe to remove it too, as code that uses
3225 move_region_on_impl generally also invalidate the source
3226 area. However, it would just use waste cycles. */
3229 cairo_region_translate (update_area, dx, dy);
3230 cairo_region_union (impl_window->update_area, update_area);
3232 /* This area of the destination is now invalid,
3233 so no need to copy to it. */
3234 cairo_region_subtract (region, update_area);
3236 cairo_region_destroy (update_area);
3239 /* If we're currently exposing this window, don't copy to this
3240 destination, as it will be overdrawn when the expose is done,
3241 instead invalidate it and repaint later. */
3242 if (impl_window->implicit_paint)
3244 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3245 cairo_region_t *exposing;
3247 exposing = cairo_region_copy (implicit_paint->region);
3248 cairo_region_intersect (exposing, region);
3249 cairo_region_subtract (region, exposing);
3251 impl_window_add_update_area (impl_window, exposing);
3252 cairo_region_destroy (exposing);
3255 append_move_region (impl_window, region, dx, dy);
3257 cairo_region_destroy (region);
3260 /* Flushes all outstanding changes to the window, call this
3261 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3264 gdk_window_flush_outstanding_moves (GdkWindow *window)
3266 GdkWindow *impl_window;
3267 GList *l, *outstanding;
3268 GdkWindowRegionMove *move;
3270 impl_window = gdk_window_get_impl_window (window);
3271 outstanding = impl_window->outstanding_moves;
3272 impl_window->outstanding_moves = NULL;
3274 for (l = outstanding; l != NULL; l = l->next)
3278 do_move_region_bits_on_impl (impl_window,
3279 move->dest_region, move->dx, move->dy);
3281 gdk_window_region_move_free (move);
3284 g_list_free (outstanding);
3289 * @window: a #GdkWindow
3291 * Flush all outstanding cached operations on a window, leaving the
3292 * window in a state which reflects all that has been drawn before.
3294 * Gdk uses multiple kinds of caching to get better performance and
3295 * nicer drawing. For instance, during exposes all paints to a window
3296 * using double buffered rendering are keep on a surface until the last
3297 * window has been exposed. It also delays window moves/scrolls until
3298 * as long as possible until next update to avoid tearing when moving
3301 * Normally this should be completely invisible to applications, as
3302 * we automatically flush the windows when required, but this might
3303 * be needed if you for instance mix direct native drawing with
3304 * gdk drawing. For Gtk widgets that don't use double buffering this
3305 * will be called automatically before sending the expose event.
3310 gdk_window_flush (GdkWindow *window)
3312 gdk_window_flush_outstanding_moves (window);
3313 gdk_window_flush_implicit_paint (window);
3316 /* If we're about to move/resize or otherwise change the
3317 * hierarchy of a client side window in an impl and we're
3318 * called from an expose event handler then we need to
3319 * flush any already painted parts of the implicit paint
3320 * that are not part of the current paint, as these may
3321 * be used when scrolling or may overdraw the changes
3322 * caused by the hierarchy change.
3325 gdk_window_flush_if_exposing (GdkWindow *window)
3327 GdkWindow *impl_window;
3329 impl_window = gdk_window_get_impl_window (window);
3331 /* If we're in an implicit paint (i.e. in an expose handler, flush
3332 all the already finished exposes to get things to an uptodate state. */
3333 if (impl_window->implicit_paint)
3334 gdk_window_flush (window);
3339 gdk_window_flush_recursive_helper (GdkWindow *window,
3340 GdkWindowImpl *impl)
3345 for (l = window->children; l != NULL; l = l->next)
3349 if (child->impl == impl)
3350 /* Same impl, ignore */
3351 gdk_window_flush_recursive_helper (child, impl);
3353 gdk_window_flush_recursive (child);
3358 gdk_window_flush_recursive (GdkWindow *window)
3360 gdk_window_flush (window);
3361 gdk_window_flush_recursive_helper (window, window->impl);
3365 * gdk_window_get_clip_region:
3366 * @window: a #GdkWindow
3368 * Computes the region of a window that potentially can be written
3369 * to by drawing primitives. This region may not take into account
3370 * other factors such as if the window is obscured by other windows,
3371 * but no area outside of this region will be affected by drawing
3374 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3375 * when you are done.
3378 gdk_window_get_clip_region (GdkWindow *window)
3380 cairo_region_t *result;
3382 g_return_val_if_fail (GDK_WINDOW (window), NULL);
3384 result = cairo_region_copy (window->clip_region);
3386 if (window->paint_stack)
3388 cairo_region_t *paint_region = cairo_region_create ();
3389 GSList *tmp_list = window->paint_stack;
3393 GdkWindowPaint *paint = tmp_list->data;
3395 cairo_region_union (paint_region, paint->region);
3397 tmp_list = tmp_list->next;
3400 cairo_region_intersect (result, paint_region);
3401 cairo_region_destroy (paint_region);
3408 * gdk_window_get_visible_region:
3409 * @window: a #GdkWindow
3411 * Computes the region of the @window that is potentially visible.
3412 * This does not necessarily take into account if the window is
3413 * obscured by other windows, but no area outside of this region
3416 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3417 * when you are done.
3420 gdk_window_get_visible_region (GdkWindow *window)
3422 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3424 return cairo_region_copy (window->clip_region);
3428 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3430 GdkWindow *bg_window;
3431 cairo_pattern_t *pattern = NULL;
3432 int x_offset = 0, y_offset = 0;
3435 cr = cairo_create (paint->surface);
3437 for (bg_window = window; bg_window; bg_window = bg_window->parent)
3439 pattern = gdk_window_get_background_pattern (bg_window);
3443 x_offset += bg_window->x;
3444 y_offset += bg_window->y;
3449 cairo_translate (cr, -x_offset, -y_offset);
3450 cairo_set_source (cr, pattern);
3451 cairo_translate (cr, x_offset, y_offset);
3454 cairo_set_source_rgb (cr, 0, 0, 0);
3460 gdk_window_clear_backing_region (GdkWindow *window,
3461 cairo_region_t *region)
3463 GdkWindowPaint *paint = window->paint_stack->data;
3464 cairo_region_t *clip;
3465 GdkRectangle clipbox;
3468 if (GDK_WINDOW_DESTROYED (window))
3471 cr = setup_backing_rect (window, paint, 0, 0);
3473 clip = cairo_region_copy (paint->region);
3474 cairo_region_intersect (clip, region);
3475 cairo_region_get_extents (clip, &clipbox);
3477 gdk_cairo_region (cr, clip);
3482 cairo_region_destroy (clip);
3486 gdk_window_clear_backing_region_direct (GdkWindow *window,
3487 cairo_region_t *region)
3489 GdkWindowPaint paint;
3490 cairo_region_t *clip;
3491 GdkRectangle clipbox;
3494 if (GDK_WINDOW_DESTROYED (window))
3497 paint.surface = _gdk_window_ref_cairo_surface (window);
3499 cr = setup_backing_rect (window, &paint, 0, 0);
3501 clip = cairo_region_copy (window->clip_region_with_children);
3502 cairo_region_intersect (clip, region);
3503 cairo_region_get_extents (clip, &clipbox);
3505 gdk_cairo_region (cr, clip);
3510 cairo_region_destroy (clip);
3511 cairo_surface_destroy (paint.surface);
3516 gdk_window_clear_region_internal (GdkWindow *window,
3517 cairo_region_t *region)
3519 if (window->paint_stack)
3520 gdk_window_clear_backing_region (window, region);
3522 gdk_window_clear_backing_region_direct (window, region);
3526 gdk_window_drop_cairo_surface (GdkWindow *window)
3528 if (window->cairo_surface)
3530 cairo_surface_finish (window->cairo_surface);
3531 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3533 window->cairo_surface = NULL;
3538 gdk_window_cairo_surface_destroy (void *data)
3540 GdkWindow *window = data;
3542 window->cairo_surface = NULL;
3545 static cairo_surface_t *
3546 gdk_window_create_cairo_surface (GdkWindow *window,
3550 cairo_surface_t *surface, *subsurface;
3552 surface = gdk_window_ref_impl_surface (window);
3553 if (gdk_window_has_impl (window))
3556 subsurface = cairo_surface_create_for_rectangle (surface,
3561 cairo_surface_destroy (surface);
3567 _gdk_window_ref_cairo_surface (GdkWindow *window)
3569 cairo_surface_t *surface;
3571 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3573 if (window->paint_stack)
3575 GdkWindowPaint *paint = window->paint_stack->data;
3577 surface = paint->surface;
3578 cairo_surface_reference (surface);
3583 /* This will be drawing directly to the window, so flush implicit paint */
3584 gdk_window_flush (window);
3586 if (!window->cairo_surface)
3588 window->cairo_surface = gdk_window_create_cairo_surface (window,
3592 if (window->cairo_surface)
3594 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3595 window, gdk_window_cairo_surface_destroy);
3599 cairo_surface_reference (window->cairo_surface);
3601 surface = window->cairo_surface;
3609 * @window: a #GdkWindow
3611 * Creates a Cairo context for drawing to @window.
3614 * Note that calling cairo_reset_clip() on the resulting #cairo_t will
3615 * produce undefined results, so avoid it at all costs.
3618 * Return value: A newly created Cairo context. Free with
3619 * cairo_destroy() when you are done drawing.
3624 gdk_cairo_create (GdkWindow *window)
3626 cairo_surface_t *surface;
3629 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3631 surface = _gdk_window_ref_cairo_surface (window);
3632 cr = cairo_create (surface);
3634 if (!window->paint_stack)
3636 gdk_cairo_region (cr, window->clip_region_with_children);
3641 GdkWindowPaint *paint = window->paint_stack->data;
3643 /* Only needs to clip to region if piggybacking
3644 on an implicit paint */
3645 if (paint->uses_implicit)
3647 gdk_cairo_region (cr, paint->region);
3652 cairo_surface_destroy (surface);
3657 /* Code for dirty-region queueing
3659 static GSList *update_windows = NULL;
3660 static guint update_idle = 0;
3661 static gboolean debug_updates = FALSE;
3663 static inline gboolean
3664 gdk_window_is_ancestor (GdkWindow *window,
3665 GdkWindow *ancestor)
3669 GdkWindow *parent = window->parent;
3671 if (parent == ancestor)
3681 gdk_window_add_update_window (GdkWindow *window)
3684 GSList *prev = NULL;
3685 gboolean has_ancestor_in_list = FALSE;
3687 for (tmp = update_windows; tmp; tmp = tmp->next)
3689 GdkWindow *parent = window->parent;
3691 /* check if tmp is an ancestor of "window"; if it is, set a
3692 * flag indicating that all following windows are either
3693 * children of "window" or from a differen hierarchy
3695 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3696 has_ancestor_in_list = TRUE;
3698 /* insert in reverse stacking order when adding around siblings,
3699 * so processing updates properly paints over lower stacked windows
3701 if (parent == GDK_WINDOW (tmp->data)->parent)
3703 gint index = g_list_index (parent->children, window);
3704 for (; tmp && parent == GDK_WINDOW (tmp->data)->parent; tmp = tmp->next)
3706 gint sibling_index = g_list_index (parent->children, tmp->data);
3707 if (index > sibling_index)
3711 /* here, tmp got advanced past all lower stacked siblings */
3712 tmp = g_slist_prepend (tmp, window);
3716 update_windows = tmp;
3720 /* if "window" has an ancestor in the list and tmp is one of
3721 * "window's" children, insert "window" before tmp
3723 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3725 tmp = g_slist_prepend (tmp, window);
3730 update_windows = tmp;
3734 /* if we're at the end of the list and had an ancestor it it,
3735 * append to the list
3737 if (! tmp->next && has_ancestor_in_list)
3739 tmp = g_slist_append (tmp, window);
3746 /* if all above checks failed ("window" is from a different
3747 * hierarchy than what is already in the list) or the list is
3750 update_windows = g_slist_prepend (update_windows, window);
3754 gdk_window_remove_update_window (GdkWindow *window)
3756 update_windows = g_slist_remove (update_windows, window);
3760 gdk_window_update_idle (gpointer data)
3762 gdk_window_process_all_updates ();
3768 gdk_window_is_toplevel_frozen (GdkWindow *window)
3770 GdkWindow *toplevel;
3772 toplevel = gdk_window_get_toplevel (window);
3774 return toplevel->update_and_descendants_freeze_count > 0;
3778 gdk_window_schedule_update (GdkWindow *window)
3781 (window->update_freeze_count ||
3782 gdk_window_is_toplevel_frozen (window)))
3787 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
3788 gdk_window_update_idle,
3793 _gdk_window_process_updates_recurse (GdkWindow *window,
3794 cairo_region_t *expose_region)
3797 cairo_region_t *child_region;
3799 GList *l, *children;
3801 if (cairo_region_is_empty (expose_region))
3804 if (gdk_window_is_offscreen (window->impl_window) &&
3805 window == window->impl_window)
3806 _gdk_window_add_damage ((GdkWindow *) window->impl_window, expose_region);
3808 /* Make this reentrancy safe for expose handlers freeing windows */
3809 children = g_list_copy (window->children);
3810 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3812 /* Iterate over children, starting at topmost */
3813 for (l = children; l != NULL; l = l->next)
3817 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3820 /* Ignore offscreen children, as they don't draw in their parent and
3821 * don't take part in the clipping */
3822 if (gdk_window_is_offscreen (child))
3827 r.width = child->width;
3828 r.height = child->height;
3830 child_region = cairo_region_create_rectangle (&r);
3833 /* Adjust shape region to parent window coords */
3834 cairo_region_translate (child->shape, child->x, child->y);
3835 cairo_region_intersect (child_region, child->shape);
3836 cairo_region_translate (child->shape, -child->x, -child->y);
3839 if (child->impl == window->impl)
3841 /* Client side child, expose */
3842 cairo_region_intersect (child_region, expose_region);
3843 cairo_region_subtract (expose_region, child_region);
3844 cairo_region_translate (child_region, -child->x, -child->y);
3845 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
3849 /* Native child, just remove area from expose region */
3850 cairo_region_subtract (expose_region, child_region);
3852 cairo_region_destroy (child_region);
3855 g_list_foreach (children, (GFunc)g_object_unref, NULL);
3856 g_list_free (children);
3858 if (!cairo_region_is_empty (expose_region) &&
3861 if (window->event_mask & GDK_EXPOSURE_MASK)
3865 event.expose.type = GDK_EXPOSE;
3866 event.expose.window = g_object_ref (window);
3867 event.expose.send_event = FALSE;
3868 event.expose.count = 0;
3869 event.expose.region = expose_region;
3870 cairo_region_get_extents (expose_region, &event.expose.area);
3872 _gdk_event_emit (&event);
3874 g_object_unref (window);
3876 else if (window->window_type != GDK_WINDOW_FOREIGN)
3878 /* No exposure mask set, so nothing will be drawn, the
3879 * app relies on the background being what it specified
3880 * for the window. So, we need to clear this manually.
3882 * For foreign windows if expose is not set that generally
3883 * means some other client paints them, so don't clear
3886 * We use begin/end_paint around the clear so that we can
3887 * piggyback on the implicit paint */
3889 gdk_window_begin_paint_region (window, expose_region);
3890 gdk_window_clear_region_internal (window, expose_region);
3891 gdk_window_end_paint (window);
3896 /* Process and remove any invalid area on the native window by creating
3897 * expose events for the window and all non-native descendants.
3898 * Also processes any outstanding moves on the window before doing
3899 * any drawing. Note that its possible to have outstanding moves without
3900 * any invalid area as we use the update idle mechanism to coalesce
3901 * multiple moves as well as multiple invalidations.
3904 gdk_window_process_updates_internal (GdkWindow *window)
3906 GdkWindowImplClass *impl_class;
3907 gboolean save_region = FALSE;
3908 GdkRectangle clip_box;
3910 /* Ensure the window lives while updating it */
3911 g_object_ref (window);
3913 /* If an update got queued during update processing, we can get a
3914 * window in the update queue that has an empty update_area.
3917 if (window->update_area)
3919 cairo_region_t *update_area = window->update_area;
3920 window->update_area = NULL;
3922 if (gdk_window_is_viewable (window))
3924 cairo_region_t *expose_region;
3925 gboolean end_implicit;
3927 /* Clip to part visible in toplevel */
3928 cairo_region_intersect (update_area, window->clip_region);
3932 /* Make sure we see the red invalid area before redrawing. */
3933 gdk_display_sync (gdk_window_get_display (window));
3937 /* At this point we will be completely redrawing all of update_area.
3938 * If we have any outstanding moves that end up moving stuff inside
3939 * this area we don't actually need to move that as that part would
3940 * be overdrawn by the expose anyway. So, in order to copy less data
3941 * we remove these areas from the outstanding moves.
3943 if (window->outstanding_moves)
3945 GdkWindowRegionMove *move;
3946 cairo_region_t *remove;
3949 remove = cairo_region_copy (update_area);
3950 /* We iterate backwards, starting from the state that would be
3951 if we had applied all the moves. */
3952 for (l = g_list_last (window->outstanding_moves); l != NULL; l = prev)
3957 /* Don't need this area */
3958 cairo_region_subtract (move->dest_region, remove);
3960 /* However if any of the destination we do need has a source
3961 in the updated region we do need that as a destination for
3962 the earlier moves */
3963 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
3964 cairo_region_subtract (remove, move->dest_region);
3966 if (cairo_region_is_empty (move->dest_region))
3968 gdk_window_region_move_free (move);
3969 window->outstanding_moves =
3970 g_list_delete_link (window->outstanding_moves, l);
3972 else /* move back */
3973 cairo_region_translate (move->dest_region, move->dx, move->dy);
3975 cairo_region_destroy (remove);
3978 /* By now we a set of window moves that should be applied, and then
3979 * an update region that should be repainted. A trivial implementation
3980 * would just do that in order, however in order to get nicer drawing
3981 * we do some tricks:
3983 * First of all, each subwindow expose may be double buffered by
3984 * itself (depending on widget setting) via
3985 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
3986 * creating a single surface the size of the invalid area on the
3987 * native window which all the individual normal paints will draw
3988 * into. This way in the normal case there will be only one surface
3989 * allocated and only once surface draw done for all the windows
3990 * in this native window.
3991 * There are a couple of reasons this may fail, for instance, some
3992 * backends (like quartz) do its own double buffering, so we disable
3993 * gdk double buffering there. Secondly, some subwindow could be
3994 * non-double buffered and draw directly to the window outside a
3995 * begin/end_paint pair. That will be lead to a gdk_window_flush
3996 * which immediately executes all outstanding moves and paints+removes
3997 * the implicit paint (further paints will allocate their own surfaces).
3999 * Secondly, in the case of implicit double buffering we expose all
4000 * the child windows into the implicit surface before we execute
4001 * the outstanding moves. This way we minimize the time between
4002 * doing the moves and rendering the new update area, thus minimizing
4003 * flashing. Of course, if any subwindow is non-double buffered we
4004 * well flush earlier than that.
4006 * Thirdly, after having done the outstanding moves we queue an
4007 * "antiexpose" on the area that will be drawn by the expose, which
4008 * means that any invalid region on the native window side before
4009 * the first expose drawing operation will be discarded, as it
4010 * has by then been overdrawn with valid data. This means we can
4011 * avoid doing the unnecessary repaint any outstanding expose events.
4014 cairo_region_get_extents (update_area, &clip_box);
4015 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
4016 expose_region = cairo_region_copy (update_area);
4017 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
4020 /* Rendering is not double buffered by gdk, do outstanding
4021 * moves and queue antiexposure immediately. No need to do
4023 gdk_window_flush_outstanding_moves (window);
4024 save_region = impl_class->queue_antiexpose (window, update_area);
4026 /* Render the invalid areas to the implicit paint, by sending exposes.
4027 * May flush if non-double buffered widget draw. */
4028 impl_class->process_updates_recurse (window, expose_region);
4032 /* Do moves right before exposes are rendered to the window */
4033 gdk_window_flush_outstanding_moves (window);
4035 /* By this time we know that any outstanding expose for this
4036 * area is invalid and we can avoid it, so queue an antiexpose.
4037 * we have already started drawing to the window, so it would
4038 * be to late to anti-expose now. Since this is merely an
4039 * optimization we just avoid doing it at all in that case.
4041 if (window->implicit_paint != NULL && !window->implicit_paint->flushed)
4042 save_region = impl_class->queue_antiexpose (window, update_area);
4044 gdk_window_end_implicit_paint (window);
4046 cairo_region_destroy (expose_region);
4049 cairo_region_destroy (update_area);
4052 if (window->outstanding_moves)
4054 /* Flush any outstanding moves, may happen if we moved a window but got
4055 no actual invalid area */
4056 gdk_window_flush_outstanding_moves (window);
4059 g_object_unref (window);
4063 flush_all_displays (void)
4065 GSList *displays, *l;
4067 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4068 for (l = displays; l; l = l->next)
4069 gdk_display_flush (l->data);
4071 g_slist_free (displays);
4075 before_process_all_updates (void)
4077 GSList *displays, *l;
4078 GdkDisplayClass *display_class;
4080 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4081 display_class = GDK_DISPLAY_GET_CLASS (displays->data);
4082 for (l = displays; l; l = l->next)
4083 display_class->before_process_all_updates (l->data);
4085 g_slist_free (displays);
4089 after_process_all_updates (void)
4091 GSList *displays, *l;
4092 GdkDisplayClass *display_class;
4094 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4095 display_class = GDK_DISPLAY_GET_CLASS (displays->data);
4096 for (l = displays; l; l = l->next)
4097 display_class->after_process_all_updates (l->data);
4099 g_slist_free (displays);
4102 /* Currently it is not possible to override
4103 * gdk_window_process_all_updates in the same manner as
4104 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4105 * by implementing the GdkPaintable interface. If in the future a
4106 * backend would need this, the right solution would be to add a
4107 * method to GdkDisplay that can be optionally
4108 * NULL. gdk_window_process_all_updates can then walk the list of open
4109 * displays and call the mehod.
4113 * gdk_window_process_all_updates:
4115 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4116 * in the application.
4120 gdk_window_process_all_updates (void)
4122 GSList *old_update_windows = update_windows;
4123 GSList *tmp_list = update_windows;
4124 static gboolean in_process_all_updates = FALSE;
4125 static gboolean got_recursive_update = FALSE;
4127 if (in_process_all_updates)
4129 /* We can't do this now since that would recurse, so
4130 delay it until after the recursion is done. */
4131 got_recursive_update = TRUE;
4136 in_process_all_updates = TRUE;
4137 got_recursive_update = FALSE;
4140 g_source_remove (update_idle);
4142 update_windows = NULL;
4145 before_process_all_updates ();
4147 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4151 GdkWindow *window = tmp_list->data;
4153 if (!GDK_WINDOW_DESTROYED (window))
4155 if (window->update_freeze_count ||
4156 gdk_window_is_toplevel_frozen (window))
4157 gdk_window_add_update_window (window);
4159 gdk_window_process_updates_internal (window);
4162 g_object_unref (window);
4163 tmp_list = tmp_list->next;
4166 g_slist_free (old_update_windows);
4168 flush_all_displays ();
4170 after_process_all_updates ();
4172 in_process_all_updates = FALSE;
4174 /* If we ignored a recursive call, schedule a
4175 redraw now so that it eventually happens,
4176 otherwise we could miss an update if nothing
4177 else schedules an update. */
4178 if (got_recursive_update && !update_idle)
4180 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4181 gdk_window_update_idle,
4186 * gdk_window_process_updates:
4187 * @window: a #GdkWindow
4188 * @update_children: whether to also process updates for child windows
4190 * Sends one or more expose events to @window. The areas in each
4191 * expose event will cover the entire update area for the window (see
4192 * gdk_window_invalidate_region() for details). Normally GDK calls
4193 * gdk_window_process_all_updates() on your behalf, so there's no
4194 * need to call this function unless you want to force expose events
4195 * to be delivered immediately and synchronously (vs. the usual
4196 * case, where GDK delivers them in an idle handler). Occasionally
4197 * this is useful to produce nicer scrolling behavior, for example.
4201 gdk_window_process_updates (GdkWindow *window,
4202 gboolean update_children)
4204 GdkWindow *impl_window;
4206 g_return_if_fail (GDK_IS_WINDOW (window));
4208 if (GDK_WINDOW_DESTROYED (window))
4211 /* Make sure the window lives during the expose callouts */
4212 g_object_ref (window);
4214 impl_window = gdk_window_get_impl_window (window);
4215 if ((impl_window->update_area ||
4216 impl_window->outstanding_moves) &&
4217 !impl_window->update_freeze_count &&
4218 !gdk_window_is_toplevel_frozen (window) &&
4220 /* Don't recurse into process_updates_internal, we'll
4221 * do the update later when idle instead. */
4222 impl_window->implicit_paint == NULL)
4224 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4225 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4228 if (update_children)
4230 /* process updates in reverse stacking order so composition or
4231 * painting over achieves the desired effect for offscreen windows
4233 GList *node, *children;
4235 children = g_list_copy (window->children);
4236 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4238 for (node = g_list_last (children); node; node = node->prev)
4240 gdk_window_process_updates (node->data, TRUE);
4241 g_object_unref (node->data);
4244 g_list_free (children);
4247 g_object_unref (window);
4251 gdk_window_invalidate_rect_full (GdkWindow *window,
4252 const GdkRectangle *rect,
4253 gboolean invalidate_children,
4256 GdkRectangle window_rect;
4257 cairo_region_t *region;
4259 g_return_if_fail (GDK_IS_WINDOW (window));
4261 if (GDK_WINDOW_DESTROYED (window))
4264 if (window->input_only || !window->viewable)
4271 window_rect.width = window->width;
4272 window_rect.height = window->height;
4273 rect = &window_rect;
4276 region = cairo_region_create_rectangle (rect);
4277 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4278 cairo_region_destroy (region);
4282 * gdk_window_invalidate_rect:
4283 * @window: a #GdkWindow
4284 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4286 * @invalidate_children: whether to also invalidate child windows
4288 * A convenience wrapper around gdk_window_invalidate_region() which
4289 * invalidates a rectangular region. See
4290 * gdk_window_invalidate_region() for details.
4293 gdk_window_invalidate_rect (GdkWindow *window,
4294 const GdkRectangle *rect,
4295 gboolean invalidate_children)
4297 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4301 draw_ugly_color (GdkWindow *window,
4302 const cairo_region_t *region)
4306 cr = gdk_cairo_create (window);
4307 /* Draw ugly color all over the newly-invalid region */
4308 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4309 gdk_cairo_region (cr, region);
4316 impl_window_add_update_area (GdkWindow *impl_window,
4317 cairo_region_t *region)
4319 if (impl_window->update_area)
4320 cairo_region_union (impl_window->update_area, region);
4323 gdk_window_add_update_window (impl_window);
4324 impl_window->update_area = cairo_region_copy (region);
4325 gdk_window_schedule_update (impl_window);
4329 /* clear_bg controls if the region will be cleared to
4330 * the background pattern if the exposure mask is not
4331 * set for the window, whereas this might not otherwise be
4332 * done (unless necessary to emulate background settings).
4333 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4334 * need to clear the background, such as when exposing the area beneath a
4335 * hidden or moved window, but not when an app requests repaint or when the
4336 * windowing system exposes a newly visible area (because then the windowing
4337 * system has already cleared the area).
4340 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4341 const cairo_region_t *region,
4343 GdkWindowChildFunc child_func,
4346 GdkWindow *impl_window;
4347 cairo_region_t *visible_region;
4350 g_return_if_fail (GDK_IS_WINDOW (window));
4352 if (GDK_WINDOW_DESTROYED (window))
4355 if (window->input_only ||
4356 !window->viewable ||
4357 cairo_region_is_empty (region) ||
4358 window->window_type == GDK_WINDOW_ROOT)
4361 visible_region = gdk_window_get_visible_region (window);
4362 cairo_region_intersect (visible_region, region);
4364 tmp_list = window->children;
4367 GdkWindow *child = tmp_list->data;
4369 if (!child->input_only)
4371 cairo_region_t *child_region;
4372 GdkRectangle child_rect;
4374 child_rect.x = child->x;
4375 child_rect.y = child->y;
4376 child_rect.width = child->width;
4377 child_rect.height = child->height;
4378 child_region = cairo_region_create_rectangle (&child_rect);
4380 /* remove child area from the invalid area of the parent */
4381 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4382 !child->composited &&
4383 !gdk_window_is_offscreen (child))
4384 cairo_region_subtract (visible_region, child_region);
4386 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4388 cairo_region_t *tmp = cairo_region_copy (region);
4390 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4391 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4392 cairo_region_intersect (child_region, tmp);
4394 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4395 child_region, clear_bg, child_func, user_data);
4397 cairo_region_destroy (tmp);
4400 cairo_region_destroy (child_region);
4403 tmp_list = tmp_list->next;
4406 impl_window = gdk_window_get_impl_window (window);
4408 if (!cairo_region_is_empty (visible_region) ||
4409 /* Even if we're not exposing anything, make sure we process
4410 idles for windows with outstanding moves */
4411 (impl_window->outstanding_moves != NULL &&
4412 impl_window->update_area == NULL))
4415 draw_ugly_color (window, region);
4417 /* Convert to impl coords */
4418 cairo_region_translate (visible_region, window->abs_x, window->abs_y);
4420 /* Only invalidate area if app requested expose events or if
4421 we need to clear the area (by request or to emulate background
4422 clearing for non-native windows or native windows with no support
4423 for window backgrounds */
4424 if (window->event_mask & GDK_EXPOSURE_MASK ||
4425 clear_bg == CLEAR_BG_ALL ||
4426 clear_bg == CLEAR_BG_WINCLEARED)
4427 impl_window_add_update_area (impl_window, visible_region);
4430 cairo_region_destroy (visible_region);
4434 * gdk_window_invalidate_maybe_recurse:
4435 * @window: a #GdkWindow
4436 * @region: a #cairo_region_t
4437 * @child_func: (scope call): function to use to decide if to recurse
4438 * to a child, %NULL means never recurse.
4439 * @user_data: data passed to @child_func
4441 * Adds @region to the update area for @window. The update area is the
4442 * region that needs to be redrawn, or "dirty region." The call
4443 * gdk_window_process_updates() sends one or more expose events to the
4444 * window, which together cover the entire update area. An
4445 * application would normally redraw the contents of @window in
4446 * response to those expose events.
4448 * GDK will call gdk_window_process_all_updates() on your behalf
4449 * whenever your program returns to the main loop and becomes idle, so
4450 * normally there's no need to do that manually, you just need to
4451 * invalidate regions that you know should be redrawn.
4453 * The @child_func parameter controls whether the region of
4454 * each child window that intersects @region will also be invalidated.
4455 * Only children for which @child_func returns TRUE will have the area
4459 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4460 const cairo_region_t *region,
4461 GdkWindowChildFunc child_func,
4464 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4465 child_func, user_data);
4469 true_predicate (GdkWindow *window,
4476 gdk_window_invalidate_region_full (GdkWindow *window,
4477 const cairo_region_t *region,
4478 gboolean invalidate_children,
4481 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4482 invalidate_children ?
4483 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4488 * gdk_window_invalidate_region:
4489 * @window: a #GdkWindow
4490 * @region: a #cairo_region_t
4491 * @invalidate_children: %TRUE to also invalidate child windows
4493 * Adds @region to the update area for @window. The update area is the
4494 * region that needs to be redrawn, or "dirty region." The call
4495 * gdk_window_process_updates() sends one or more expose events to the
4496 * window, which together cover the entire update area. An
4497 * application would normally redraw the contents of @window in
4498 * response to those expose events.
4500 * GDK will call gdk_window_process_all_updates() on your behalf
4501 * whenever your program returns to the main loop and becomes idle, so
4502 * normally there's no need to do that manually, you just need to
4503 * invalidate regions that you know should be redrawn.
4505 * The @invalidate_children parameter controls whether the region of
4506 * each child window that intersects @region will also be invalidated.
4507 * If %FALSE, then the update area for child windows will remain
4508 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4509 * fine grained control over which children are invalidated.
4512 gdk_window_invalidate_region (GdkWindow *window,
4513 const cairo_region_t *region,
4514 gboolean invalidate_children)
4516 gdk_window_invalidate_maybe_recurse (window, region,
4517 invalidate_children ?
4518 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4523 * _gdk_window_invalidate_for_expose:
4524 * @window: a #GdkWindow
4525 * @region: a #cairo_region_t
4527 * Adds @region to the update area for @window. The update area is the
4528 * region that needs to be redrawn, or "dirty region." The call
4529 * gdk_window_process_updates() sends one or more expose events to the
4530 * window, which together cover the entire update area. An
4531 * application would normally redraw the contents of @window in
4532 * response to those expose events.
4534 * GDK will call gdk_window_process_all_updates() on your behalf
4535 * whenever your program returns to the main loop and becomes idle, so
4536 * normally there's no need to do that manually, you just need to
4537 * invalidate regions that you know should be redrawn.
4539 * This version of invalidation is used when you recieve expose events
4540 * from the native window system. It exposes the native window, plus
4541 * any non-native child windows (but not native child windows, as those would
4542 * have gotten their own expose events).
4545 _gdk_window_invalidate_for_expose (GdkWindow *window,
4546 cairo_region_t *region)
4548 GdkWindowRegionMove *move;
4549 cairo_region_t *move_region;
4552 /* Any invalidations comming from the windowing system will
4553 be in areas that may be moved by outstanding moves,
4554 so we need to modify the expose region correspondingly,
4555 otherwise we would expose in the wrong place, as the
4556 outstanding moves will be copied before we draw the
4558 for (l = window->outstanding_moves; l != NULL; l = l->next)
4562 /* covert to move source region */
4563 move_region = cairo_region_copy (move->dest_region);
4564 cairo_region_translate (move_region, -move->dx, -move->dy);
4566 /* Move area of region that intersects with move source
4567 by dx, dy of the move*/
4568 cairo_region_intersect (move_region, region);
4569 cairo_region_subtract (region, move_region);
4570 cairo_region_translate (move_region, move->dx, move->dy);
4571 cairo_region_union (region, move_region);
4573 cairo_region_destroy (move_region);
4576 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4577 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4583 * gdk_window_get_update_area:
4584 * @window: a #GdkWindow
4586 * Transfers ownership of the update area from @window to the caller
4587 * of the function. That is, after calling this function, @window will
4588 * no longer have an invalid/dirty region; the update area is removed
4589 * from @window and handed to you. If a window has no update area,
4590 * gdk_window_get_update_area() returns %NULL. You are responsible for
4591 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4593 * Return value: the update area for @window
4596 gdk_window_get_update_area (GdkWindow *window)
4598 GdkWindow *impl_window;
4599 cairo_region_t *tmp_region;
4601 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4603 impl_window = gdk_window_get_impl_window (window);
4605 if (impl_window->update_area)
4607 tmp_region = cairo_region_copy (window->clip_region_with_children);
4608 /* Convert to impl coords */
4609 cairo_region_translate (tmp_region, window->abs_x, window->abs_y);
4610 cairo_region_intersect (tmp_region, impl_window->update_area);
4612 if (cairo_region_is_empty (tmp_region))
4614 cairo_region_destroy (tmp_region);
4619 cairo_region_subtract (impl_window->update_area, tmp_region);
4621 if (cairo_region_is_empty (impl_window->update_area) &&
4622 impl_window->outstanding_moves == NULL)
4624 cairo_region_destroy (impl_window->update_area);
4625 impl_window->update_area = NULL;
4627 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4630 /* Convert from impl coords */
4631 cairo_region_translate (tmp_region, -window->abs_x, -window->abs_y);
4641 * _gdk_window_clear_update_area:
4642 * @window: a #GdkWindow.
4644 * Internal function to clear the update area for a window. This
4645 * is called when the window is hidden or destroyed.
4648 _gdk_window_clear_update_area (GdkWindow *window)
4650 g_return_if_fail (GDK_IS_WINDOW (window));
4652 if (window->update_area)
4654 gdk_window_remove_update_window (window);
4656 cairo_region_destroy (window->update_area);
4657 window->update_area = NULL;
4662 * gdk_window_freeze_updates:
4663 * @window: a #GdkWindow
4665 * Temporarily freezes a window such that it won't receive expose
4666 * events. The window will begin receiving expose events again when
4667 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4668 * has been called more than once, gdk_window_thaw_updates() must be called
4669 * an equal number of times to begin processing exposes.
4672 gdk_window_freeze_updates (GdkWindow *window)
4674 GdkWindow *impl_window;
4676 g_return_if_fail (GDK_IS_WINDOW (window));
4678 impl_window = gdk_window_get_impl_window (window);
4679 impl_window->update_freeze_count++;
4683 * gdk_window_thaw_updates:
4684 * @window: a #GdkWindow
4686 * Thaws a window frozen with gdk_window_freeze_updates().
4689 gdk_window_thaw_updates (GdkWindow *window)
4691 GdkWindow *impl_window;
4693 g_return_if_fail (GDK_IS_WINDOW (window));
4695 impl_window = gdk_window_get_impl_window (window);
4697 g_return_if_fail (impl_window->update_freeze_count > 0);
4699 if (--impl_window->update_freeze_count == 0)
4700 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4704 * gdk_window_freeze_toplevel_updates_libgtk_only:
4705 * @window: a #GdkWindow
4707 * Temporarily freezes a window and all its descendants such that it won't
4708 * receive expose events. The window will begin receiving expose events
4709 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4710 * gdk_window_freeze_toplevel_updates_libgtk_only()
4711 * has been called more than once,
4712 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4713 * an equal number of times to begin processing exposes.
4715 * This function is not part of the GDK public API and is only
4719 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4721 g_return_if_fail (GDK_IS_WINDOW (window));
4722 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4724 window->update_and_descendants_freeze_count++;
4728 * gdk_window_thaw_toplevel_updates_libgtk_only:
4729 * @window: a #GdkWindow
4731 * Thaws a window frozen with
4732 * gdk_window_freeze_toplevel_updates_libgtk_only().
4734 * This function is not part of the GDK public API and is only
4738 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4740 g_return_if_fail (GDK_IS_WINDOW (window));
4741 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4742 g_return_if_fail (window->update_and_descendants_freeze_count > 0);
4744 window->update_and_descendants_freeze_count--;
4746 gdk_window_schedule_update (window);
4750 * gdk_window_set_debug_updates:
4751 * @setting: %TRUE to turn on update debugging
4753 * With update debugging enabled, calls to
4754 * gdk_window_invalidate_region() clear the invalidated region of the
4755 * screen to a noticeable color, and GDK pauses for a short time
4756 * before sending exposes to windows during
4757 * gdk_window_process_updates(). The net effect is that you can see
4758 * the invalid region for each window and watch redraws as they
4759 * occur. This allows you to diagnose inefficiencies in your application.
4761 * In essence, because the GDK rendering model prevents all flicker,
4762 * if you are redrawing the same region 400 times you may never
4763 * notice, aside from noticing a speed problem. Enabling update
4764 * debugging causes GTK to flicker slowly and noticeably, so you can
4765 * see exactly what's being redrawn when, in what order.
4767 * The --gtk-debug=updates command line option passed to GTK+ programs
4768 * enables this debug option at application startup time. That's
4769 * usually more useful than calling gdk_window_set_debug_updates()
4770 * yourself, though you might want to use this function to enable
4771 * updates sometime after application startup time.
4775 gdk_window_set_debug_updates (gboolean setting)
4777 debug_updates = setting;
4781 * gdk_window_constrain_size:
4782 * @geometry: a #GdkGeometry structure
4783 * @flags: a mask indicating what portions of @geometry are set
4784 * @width: desired width of window
4785 * @height: desired height of the window
4786 * @new_width: (out): location to store resulting width
4787 * @new_height: (out): location to store resulting height
4789 * Constrains a desired width and height according to a
4790 * set of geometry hints (such as minimum and maximum size).
4793 gdk_window_constrain_size (GdkGeometry *geometry,
4800 /* This routine is partially borrowed from fvwm.
4802 * Copyright 1993, Robert Nation
4803 * You may use this code for any purpose, as long as the original
4804 * copyright remains in the source code and all documentation
4806 * which in turn borrows parts of the algorithm from uwm
4809 gint min_height = 0;
4810 gint base_width = 0;
4811 gint base_height = 0;
4814 gint max_width = G_MAXINT;
4815 gint max_height = G_MAXINT;
4817 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4819 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4821 base_width = geometry->base_width;
4822 base_height = geometry->base_height;
4823 min_width = geometry->min_width;
4824 min_height = geometry->min_height;
4826 else if (flags & GDK_HINT_BASE_SIZE)
4828 base_width = geometry->base_width;
4829 base_height = geometry->base_height;
4830 min_width = geometry->base_width;
4831 min_height = geometry->base_height;
4833 else if (flags & GDK_HINT_MIN_SIZE)
4835 base_width = geometry->min_width;
4836 base_height = geometry->min_height;
4837 min_width = geometry->min_width;
4838 min_height = geometry->min_height;
4841 if (flags & GDK_HINT_MAX_SIZE)
4843 max_width = geometry->max_width ;
4844 max_height = geometry->max_height;
4847 if (flags & GDK_HINT_RESIZE_INC)
4849 xinc = MAX (xinc, geometry->width_inc);
4850 yinc = MAX (yinc, geometry->height_inc);
4853 /* clamp width and height to min and max values
4855 width = CLAMP (width, min_width, max_width);
4856 height = CLAMP (height, min_height, max_height);
4858 /* shrink to base + N * inc
4860 width = base_width + FLOOR (width - base_width, xinc);
4861 height = base_height + FLOOR (height - base_height, yinc);
4863 /* constrain aspect ratio, according to:
4866 * min_aspect <= -------- <= max_aspect
4870 if (flags & GDK_HINT_ASPECT &&
4871 geometry->min_aspect > 0 &&
4872 geometry->max_aspect > 0)
4876 if (geometry->min_aspect * height > width)
4878 delta = FLOOR (height - width / geometry->min_aspect, yinc);
4879 if (height - delta >= min_height)
4883 delta = FLOOR (height * geometry->min_aspect - width, xinc);
4884 if (width + delta <= max_width)
4889 if (geometry->max_aspect * height < width)
4891 delta = FLOOR (width - height * geometry->max_aspect, xinc);
4892 if (width - delta >= min_width)
4896 delta = FLOOR (width / geometry->max_aspect - height, yinc);
4897 if (height + delta <= max_height)
4906 *new_height = height;
4910 * gdk_window_get_pointer:
4911 * @window: a #GdkWindow
4912 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
4913 * return the X coordinate
4914 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
4915 * return the Y coordinate
4916 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
4919 * Obtains the current pointer position and modifier state.
4920 * The position is given in coordinates relative to the upper left
4921 * corner of @window.
4923 * Return value: (transfer none): the window containing the pointer (as with
4924 * gdk_window_at_pointer()), or %NULL if the window containing the
4925 * pointer isn't known to GDK
4927 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
4930 gdk_window_get_pointer (GdkWindow *window,
4933 GdkModifierType *mask)
4935 GdkDisplay *display;
4937 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4939 display = gdk_window_get_display (window);
4941 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
4945 * gdk_window_get_device_position:
4946 * @window: a #GdkWindow.
4947 * @device: pointer #GdkDevice to query to.
4948 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
4949 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
4950 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
4952 * Obtains the current device position and modifier state.
4953 * The position is given in coordinates relative to the upper left
4954 * corner of @window.
4956 * Return value: (transfer none): The window underneath @device (as with
4957 * gdk_device_get_window_at_position()), or %NULL if the window is not known to GDK.
4962 gdk_window_get_device_position (GdkWindow *window,
4966 GdkModifierType *mask)
4969 GdkModifierType tmp_mask;
4970 gboolean normal_child;
4972 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4973 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
4974 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
4976 normal_child = GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_device_state (window,
4980 /* We got the coords on the impl, convert to the window */
4981 tmp_x -= window->abs_x;
4982 tmp_y -= window->abs_y;
4991 _gdk_display_enable_motion_hints (gdk_window_get_display (window), device);
4994 return _gdk_window_find_child_at (window, tmp_x, tmp_y);
4999 * gdk_window_at_pointer:
5000 * @win_x: (out) (allow-none): return location for origin of the window under the pointer
5001 * @win_y: (out) (allow-none): return location for origin of the window under the pointer
5003 * Obtains the window underneath the mouse pointer, returning the
5004 * location of that window in @win_x, @win_y. Returns %NULL if the
5005 * window under the mouse pointer is not known to GDK (if the window
5006 * belongs to another application and a #GdkWindow hasn't been created
5007 * for it with gdk_window_foreign_new())
5009 * NOTE: For multihead-aware widgets or applications use
5010 * gdk_display_get_window_at_pointer() instead.
5012 * Return value: (transfer none): window under the mouse pointer
5014 * Deprecated: 3.0: Use gdk_device_get_window_at_position() instead.
5017 gdk_window_at_pointer (gint *win_x,
5020 return gdk_display_get_window_at_pointer (gdk_display_get_default (), win_x, win_y);
5024 * gdk_get_default_root_window:
5026 * Obtains the root window (parent all other windows are inside)
5027 * for the default display and screen.
5029 * Return value: (transfer none): the default root window
5032 gdk_get_default_root_window (void)
5034 return gdk_screen_get_root_window (gdk_screen_get_default ());
5038 get_all_native_children (GdkWindow *window,
5044 for (l = window->children; l != NULL; l = l->next)
5048 if (gdk_window_has_impl (child))
5049 *native = g_list_prepend (*native, child);
5051 get_all_native_children (child, native);
5057 gdk_window_raise_internal (GdkWindow *window)
5059 GdkWindow *parent = window->parent;
5061 GList *native_children;
5063 GdkWindowImplClass *impl_class;
5067 parent->children = g_list_remove (parent->children, window);
5068 parent->children = g_list_prepend (parent->children, window);
5071 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5072 /* Just do native raise for toplevels */
5073 if (gdk_window_is_toplevel (window) ||
5074 /* The restack_under codepath should work correctly even if the parent
5075 is native, but it relies on the order of ->children to be correct,
5076 and some apps like SWT reorder the x windows without gdks knowledge,
5077 so we use raise directly in order to make these behave as before
5078 when using native windows */
5079 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5081 impl_class->raise (window);
5083 else if (gdk_window_has_impl (window))
5085 above = find_native_sibling_above (parent, window);
5088 listhead.data = window;
5089 listhead.next = NULL;
5090 listhead.prev = NULL;
5091 impl_class->restack_under ((GdkWindow *)above,
5095 impl_class->raise (window);
5099 native_children = NULL;
5100 get_all_native_children (window, &native_children);
5101 if (native_children != NULL)
5103 above = find_native_sibling_above (parent, window);
5106 impl_class->restack_under (above, native_children);
5109 /* Right order, since native_children is bottom-topmost first */
5110 for (l = native_children; l != NULL; l = l->next)
5111 impl_class->raise (l->data);
5114 g_list_free (native_children);
5120 /* Returns TRUE If the native window was mapped or unmapped */
5122 set_viewable (GdkWindow *w,
5126 GdkWindowImplClass *impl_class;
5129 if (w->viewable == val)
5135 recompute_visible_regions (w, FALSE, FALSE);
5137 for (l = w->children; l != NULL; l = l->next)
5141 if (GDK_WINDOW_IS_MAPPED (child) &&
5142 child->window_type != GDK_WINDOW_FOREIGN)
5143 set_viewable (child, val);
5146 if (!_gdk_native_windows &&
5147 gdk_window_has_impl (w) &&
5148 w->window_type != GDK_WINDOW_FOREIGN &&
5149 !gdk_window_is_toplevel (w))
5151 /* For most native windows we show/hide them not when they are
5152 * mapped/unmapped, because that may not produce the correct results.
5153 * For instance, if a native window have a non-native parent which is
5154 * hidden, but its native parent is viewable then showing the window
5155 * would make it viewable to X but its not viewable wrt the non-native
5156 * hierarchy. In order to handle this we track the gdk side viewability
5157 * and only map really viewable windows.
5159 * There are two exceptions though:
5161 * For foreign windows we don't want ever change the mapped state
5162 * except when explicitly done via gdk_window_show/hide, as this may
5163 * cause problems for client owning the foreign window when its window
5164 * is suddenly mapped or unmapped.
5166 * For toplevel windows embedded in a foreign window (e.g. a plug)
5167 * we sometimes synthesize a map of a window, but the native
5168 * window is really shown by the embedder, so we don't want to
5169 * do the show ourselves. We can't really tell this case from the normal
5170 * toplevel show as such toplevels are seen by gdk as parents of the
5171 * root window, so we make an exception for all toplevels.
5173 * Also, when in GDK_NATIVE_WINDOW mode we never need to play games
5174 * like this, so we just always show/hide directly.
5177 impl_class = GDK_WINDOW_IMPL_GET_CLASS (w->impl);
5179 impl_class->show ((GdkWindow *)w, FALSE);
5181 impl_class->hide ((GdkWindow *)w);
5189 /* Returns TRUE If the native window was mapped or unmapped */
5191 _gdk_window_update_viewable (GdkWindow *window)
5195 if (window->window_type == GDK_WINDOW_FOREIGN ||
5196 window->window_type == GDK_WINDOW_ROOT)
5198 else if (gdk_window_is_toplevel (window) ||
5199 window->parent->viewable)
5200 viewable = GDK_WINDOW_IS_MAPPED (window);
5204 return set_viewable (window, viewable);
5208 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5210 GdkWindowImplClass *impl_class;
5211 gboolean was_mapped, was_viewable;
5214 g_return_if_fail (GDK_IS_WINDOW (window));
5216 if (window->destroyed)
5219 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5220 was_viewable = window->viewable;
5223 /* Keep children in (reverse) stacking order */
5224 gdk_window_raise_internal (window);
5226 if (gdk_window_has_impl (window))
5229 gdk_synthesize_window_state (window,
5230 GDK_WINDOW_STATE_WITHDRAWN,
5238 did_show = _gdk_window_update_viewable (window);
5240 /* If it was already viewable the backend show op won't be called, call it
5241 again to ensure things happen right if the mapped tracking was not right
5242 for e.g. a foreign window.
5243 Dunno if this is strictly needed but its what happened pre-csw.
5244 Also show if not done by gdk_window_update_viewable. */
5245 if (gdk_window_has_impl (window) && (was_viewable || !did_show))
5247 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5248 impl_class->show (window, !did_show ? was_mapped : TRUE);
5251 if (!was_mapped && !gdk_window_has_impl (window))
5253 if (window->event_mask & GDK_STRUCTURE_MASK)
5254 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5256 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5257 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5260 if (!was_mapped || raise)
5262 recompute_visible_regions (window, TRUE, FALSE);
5264 /* If any decendants became visible we need to send visibility notify */
5265 gdk_window_update_visibility_recursively (window, NULL);
5267 if (gdk_window_is_viewable (window))
5269 _gdk_synthesize_crossing_events_for_geometry_change (window);
5270 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5276 * gdk_window_show_unraised:
5277 * @window: a #GdkWindow
5279 * Shows a #GdkWindow onscreen, but does not modify its stacking
5280 * order. In contrast, gdk_window_show() will raise the window
5281 * to the top of the window stack.
5283 * On the X11 platform, in Xlib terms, this function calls
5284 * XMapWindow() (it also updates some internal GDK state, which means
5285 * that you can't really use XMapWindow() directly on a GDK window).
5288 gdk_window_show_unraised (GdkWindow *window)
5290 gdk_window_show_internal (window, FALSE);
5295 * @window: a #GdkWindow
5297 * Raises @window to the top of the Z-order (stacking order), so that
5298 * other windows with the same parent window appear below @window.
5299 * This is true whether or not the windows are visible.
5301 * If @window is a toplevel, the window manager may choose to deny the
5302 * request to move the window in the Z-order, gdk_window_raise() only
5303 * requests the restack, does not guarantee it.
5306 gdk_window_raise (GdkWindow *window)
5308 cairo_region_t *old_region, *new_region;
5310 g_return_if_fail (GDK_IS_WINDOW (window));
5312 if (window->destroyed)
5315 gdk_window_flush_if_exposing (window);
5318 if (gdk_window_is_viewable (window) &&
5319 !window->input_only)
5320 old_region = cairo_region_copy (window->clip_region);
5322 /* Keep children in (reverse) stacking order */
5323 gdk_window_raise_internal (window);
5325 recompute_visible_regions (window, TRUE, FALSE);
5329 new_region = cairo_region_copy (window->clip_region);
5331 cairo_region_subtract (new_region, old_region);
5332 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5334 cairo_region_destroy (old_region);
5335 cairo_region_destroy (new_region);
5340 gdk_window_lower_internal (GdkWindow *window)
5342 GdkWindow *parent = window->parent;
5343 GdkWindowImplClass *impl_class;
5345 GList *native_children;
5350 parent->children = g_list_remove (parent->children, window);
5351 parent->children = g_list_append (parent->children, window);
5354 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5355 /* Just do native lower for toplevels */
5356 if (gdk_window_is_toplevel (window) ||
5357 /* The restack_under codepath should work correctly even if the parent
5358 is native, but it relies on the order of ->children to be correct,
5359 and some apps like SWT reorder the x windows without gdks knowledge,
5360 so we use lower directly in order to make these behave as before
5361 when using native windows */
5362 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5364 impl_class->lower (window);
5366 else if (gdk_window_has_impl (window))
5368 above = find_native_sibling_above (parent, window);
5371 listhead.data = window;
5372 listhead.next = NULL;
5373 listhead.prev = NULL;
5374 impl_class->restack_under ((GdkWindow *)above, &listhead);
5377 impl_class->raise (window);
5381 native_children = NULL;
5382 get_all_native_children (window, &native_children);
5383 if (native_children != NULL)
5385 above = find_native_sibling_above (parent, window);
5388 impl_class->restack_under ((GdkWindow *)above,
5392 /* Right order, since native_children is bottom-topmost first */
5393 for (l = native_children; l != NULL; l = l->next)
5394 impl_class->raise (l->data);
5397 g_list_free (native_children);
5404 gdk_window_invalidate_in_parent (GdkWindow *private)
5406 GdkRectangle r, child;
5408 if (gdk_window_is_toplevel (private))
5411 /* get the visible rectangle of the parent */
5413 r.width = private->parent->width;
5414 r.height = private->parent->height;
5416 child.x = private->x;
5417 child.y = private->y;
5418 child.width = private->width;
5419 child.height = private->height;
5420 gdk_rectangle_intersect (&r, &child, &r);
5422 gdk_window_invalidate_rect_full (private->parent, &r, TRUE, CLEAR_BG_ALL);
5428 * @window: a #GdkWindow
5430 * Lowers @window to the bottom of the Z-order (stacking order), so that
5431 * other windows with the same parent window appear above @window.
5432 * This is true whether or not the other windows are visible.
5434 * If @window is a toplevel, the window manager may choose to deny the
5435 * request to move the window in the Z-order, gdk_window_lower() only
5436 * requests the restack, does not guarantee it.
5438 * Note that gdk_window_show() raises the window again, so don't call this
5439 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5442 gdk_window_lower (GdkWindow *window)
5444 g_return_if_fail (GDK_IS_WINDOW (window));
5446 if (window->destroyed)
5449 gdk_window_flush_if_exposing (window);
5451 /* Keep children in (reverse) stacking order */
5452 gdk_window_lower_internal (window);
5454 recompute_visible_regions (window, TRUE, FALSE);
5456 _gdk_synthesize_crossing_events_for_geometry_change (window);
5457 gdk_window_invalidate_in_parent (window);
5461 * gdk_window_restack:
5462 * @window: a #GdkWindow
5463 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5466 * Changes the position of @window in the Z-order (stacking order), so that
5467 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5470 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5471 * lowers the window.
5473 * If @window is a toplevel, the window manager may choose to deny the
5474 * request to move the window in the Z-order, gdk_window_restack() only
5475 * requests the restack, does not guarantee it.
5480 gdk_window_restack (GdkWindow *window,
5484 GdkWindowImplClass *impl_class;
5486 GdkWindow *above_native;
5487 GList *sibling_link;
5488 GList *native_children;
5491 g_return_if_fail (GDK_IS_WINDOW (window));
5492 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5494 if (window->destroyed)
5497 if (sibling == NULL)
5500 gdk_window_raise (window);
5502 gdk_window_lower (window);
5506 gdk_window_flush_if_exposing (window);
5508 if (gdk_window_is_toplevel (window))
5510 g_return_if_fail (gdk_window_is_toplevel (sibling));
5511 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5512 impl_class->restack_toplevel (window, sibling, above);
5516 parent = window->parent;
5519 sibling_link = g_list_find (parent->children, sibling);
5520 g_return_if_fail (sibling_link != NULL);
5521 if (sibling_link == NULL)
5524 parent->children = g_list_remove (parent->children, window);
5526 parent->children = g_list_insert_before (parent->children,
5530 parent->children = g_list_insert_before (parent->children,
5534 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5535 if (gdk_window_has_impl (window))
5537 above_native = find_native_sibling_above (parent, window);
5540 listhead.data = window;
5541 listhead.next = NULL;
5542 listhead.prev = NULL;
5543 impl_class->restack_under (above_native, &listhead);
5546 impl_class->raise (window);
5550 native_children = NULL;
5551 get_all_native_children (window, &native_children);
5552 if (native_children != NULL)
5554 above_native = find_native_sibling_above (parent, window);
5556 impl_class->restack_under (above_native,
5560 /* Right order, since native_children is bottom-topmost first */
5561 for (l = native_children; l != NULL; l = l->next)
5562 impl_class->raise (l->data);
5565 g_list_free (native_children);
5570 recompute_visible_regions (window, TRUE, FALSE);
5572 _gdk_synthesize_crossing_events_for_geometry_change (window);
5573 gdk_window_invalidate_in_parent (window);
5579 * @window: a #GdkWindow
5581 * Like gdk_window_show_unraised(), but also raises the window to the
5582 * top of the window stack (moves the window to the front of the
5585 * This function maps a window so it's visible onscreen. Its opposite
5586 * is gdk_window_hide().
5588 * When implementing a #GtkWidget, you should call this function on the widget's
5589 * #GdkWindow as part of the "map" method.
5592 gdk_window_show (GdkWindow *window)
5594 gdk_window_show_internal (window, TRUE);
5599 * @window: a #GdkWindow
5601 * For toplevel windows, withdraws them, so they will no longer be
5602 * known to the window manager; for all windows, unmaps them, so
5603 * they won't be displayed. Normally done automatically as
5604 * part of gtk_widget_hide().
5607 gdk_window_hide (GdkWindow *window)
5609 GdkWindowImplClass *impl_class;
5610 gboolean was_mapped, did_hide;
5612 g_return_if_fail (GDK_IS_WINDOW (window));
5614 if (window->destroyed)
5617 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5619 if (gdk_window_has_impl (window))
5622 if (GDK_WINDOW_IS_MAPPED (window))
5623 gdk_synthesize_window_state (window,
5625 GDK_WINDOW_STATE_WITHDRAWN);
5627 else if (was_mapped)
5629 GdkDisplay *display;
5630 GdkDeviceManager *device_manager;
5633 /* May need to break grabs on children */
5634 display = gdk_window_get_display (window);
5635 device_manager = gdk_display_get_device_manager (display);
5637 /* Get all devices */
5638 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5639 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5640 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5642 for (d = devices; d; d = d->next)
5644 GdkDevice *device = d->data;
5646 if (_gdk_display_end_device_grab (display,
5648 _gdk_display_get_next_serial (display),
5651 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5654 window->state = GDK_WINDOW_STATE_WITHDRAWN;
5655 g_list_free (devices);
5658 did_hide = _gdk_window_update_viewable (window);
5660 /* Hide foreign window as those are not handled by update_viewable. */
5661 if (gdk_window_has_impl (window) && (!did_hide))
5663 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5664 impl_class->hide (window);
5667 recompute_visible_regions (window, TRUE, FALSE);
5669 /* all decendants became non-visible, we need to send visibility notify */
5670 gdk_window_update_visibility_recursively (window, NULL);
5672 if (was_mapped && !gdk_window_has_impl (window))
5674 if (window->event_mask & GDK_STRUCTURE_MASK)
5675 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5677 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5678 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5680 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5683 /* Invalidate the rect */
5685 gdk_window_invalidate_in_parent (window);
5689 * gdk_window_withdraw:
5690 * @window: a toplevel #GdkWindow
5692 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5693 * This function is not really useful as gdk_window_hide() automatically
5694 * withdraws toplevel windows before hiding them.
5697 gdk_window_withdraw (GdkWindow *window)
5699 GdkWindowImplClass *impl_class;
5700 gboolean was_mapped;
5702 g_return_if_fail (GDK_IS_WINDOW (window));
5704 if (window->destroyed)
5707 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5709 if (gdk_window_has_impl (window))
5711 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5712 impl_class->withdraw (window);
5716 if (window->event_mask & GDK_STRUCTURE_MASK)
5717 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5719 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5720 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5722 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5725 recompute_visible_regions (window, TRUE, FALSE);
5730 * gdk_window_set_events:
5731 * @window: a #GdkWindow
5732 * @event_mask: event mask for @window
5734 * The event mask for a window determines which events will be reported
5735 * for that window from all master input devices. For example, an event mask
5736 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5737 * press events. The event mask is the bitwise OR of values from the
5738 * #GdkEventMask enumeration.
5741 gdk_window_set_events (GdkWindow *window,
5742 GdkEventMask event_mask)
5744 GdkWindowImplClass *impl_class;
5745 GdkDisplay *display;
5747 g_return_if_fail (GDK_IS_WINDOW (window));
5749 if (window->destroyed)
5752 /* If motion hint is disabled, enable motion events again */
5753 display = gdk_window_get_display (window);
5754 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5755 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5757 GList *devices = window->devices_inside;
5761 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5762 devices = devices->next;
5766 window->event_mask = event_mask;
5768 if (gdk_window_has_impl (window))
5770 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5771 impl_class->set_events (window,
5772 get_native_event_mask (window));
5778 * gdk_window_get_events:
5779 * @window: a #GdkWindow
5781 * Gets the event mask for @window for all master input devices. See
5782 * gdk_window_set_events().
5784 * Return value: event mask for @window
5787 gdk_window_get_events (GdkWindow *window)
5789 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5791 if (window->destroyed)
5794 return window->event_mask;
5798 * gdk_window_set_device_events:
5799 * @window: a #GdkWindow
5800 * @device: #GdkDevice to enable events for.
5801 * @event_mask: event mask for @window
5803 * Sets the event mask for a given device (Normally a floating device, not
5804 * attached to any visible pointer) to @window. For example, an event mask
5805 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5806 * press events. The event mask is the bitwise OR of values from the
5807 * #GdkEventMask enumeration.
5812 gdk_window_set_device_events (GdkWindow *window,
5814 GdkEventMask event_mask)
5816 GdkEventMask device_mask;
5817 GdkDisplay *display;
5820 g_return_if_fail (GDK_IS_WINDOW (window));
5821 g_return_if_fail (GDK_IS_DEVICE (device));
5823 if (GDK_WINDOW_DESTROYED (window))
5826 /* If motion hint is disabled, enable motion events again */
5827 display = gdk_window_get_display (window);
5828 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5829 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5830 _gdk_display_enable_motion_hints (display, device);
5832 if (G_UNLIKELY (!window->device_events))
5833 window->device_events = g_hash_table_new (NULL, NULL);
5835 if (event_mask == 0)
5837 /* FIXME: unsetting events on a master device
5838 * would restore window->event_mask
5840 g_hash_table_remove (window->device_events, device);
5843 g_hash_table_insert (window->device_events, device,
5844 GINT_TO_POINTER (event_mask));
5846 if (_gdk_native_windows)
5849 native = gdk_window_get_toplevel (window);
5851 while (gdk_window_is_offscreen (native))
5853 native = gdk_offscreen_window_get_embedder (native);
5855 if (native == NULL ||
5856 (!_gdk_window_has_impl (native) &&
5857 !gdk_window_is_viewable (native)))
5860 native = gdk_window_get_toplevel (native);
5863 device_mask = get_native_device_event_mask (window, device);
5864 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
5868 * gdk_window_get_device_events:
5869 * @window: a #GdkWindow.
5870 * @device: a #GdkDevice.
5872 * Returns the event mask for @window corresponding to an specific device.
5874 * Returns: device event mask for @window
5879 gdk_window_get_device_events (GdkWindow *window,
5884 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5885 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
5887 if (GDK_WINDOW_DESTROYED (window))
5890 if (!window->device_events)
5893 mask = GPOINTER_TO_INT (g_hash_table_lookup (window->device_events, device));
5895 /* FIXME: device could be controlled by window->event_mask */
5901 gdk_window_move_resize_toplevel (GdkWindow *window,
5908 cairo_region_t *old_region, *new_region;
5909 GdkWindowImplClass *impl_class;
5916 is_resize = (width != -1) || (height != -1);
5918 if (gdk_window_is_viewable (window) &&
5919 !window->input_only)
5922 old_region = cairo_region_copy (window->clip_region);
5925 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5926 impl_class->move_resize (window, with_move, x, y, width, height);
5928 /* Avoid recomputing for pure toplevel moves, for performance reasons */
5930 recompute_visible_regions (window, TRUE, FALSE);
5934 new_region = cairo_region_copy (window->clip_region);
5936 /* This is the newly exposed area (due to any resize),
5937 * X will expose it, but lets do that without the roundtrip
5939 cairo_region_subtract (new_region, old_region);
5940 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
5942 cairo_region_destroy (old_region);
5943 cairo_region_destroy (new_region);
5946 _gdk_synthesize_crossing_events_for_geometry_change (window);
5951 move_native_children (GdkWindow *private)
5955 GdkWindowImplClass *impl_class;
5957 for (l = private->children; l; l = l->next)
5961 if (child->impl != private->impl)
5963 impl_class = GDK_WINDOW_IMPL_GET_CLASS (child->impl);
5964 impl_class->move_resize (child, TRUE,
5966 child->width, child->height);
5969 move_native_children (child);
5974 collect_native_child_region_helper (GdkWindow *window,
5975 GdkWindowImpl *impl,
5976 cairo_region_t **region,
5981 cairo_region_t *tmp;
5984 for (l = window->children; l != NULL; l = l->next)
5988 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
5991 if (child->impl != impl)
5993 tmp = cairo_region_copy (child->clip_region);
5994 cairo_region_translate (tmp,
5995 x_offset + child->x,
5996 y_offset + child->y);
5997 if (*region == NULL)
6001 cairo_region_union (*region, tmp);
6002 cairo_region_destroy (tmp);
6006 collect_native_child_region_helper (child, impl, region,
6007 x_offset + child->x,
6008 y_offset + child->y);
6014 static cairo_region_t *
6015 collect_native_child_region (GdkWindow *window,
6016 gboolean include_this)
6018 cairo_region_t *region;
6020 if (include_this && gdk_window_has_impl (window) && window->viewable)
6021 return cairo_region_copy (window->clip_region);
6025 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6032 gdk_window_move_resize_internal (GdkWindow *window,
6039 cairo_region_t *old_region, *new_region, *copy_area;
6040 cairo_region_t *old_native_child_region, *new_native_child_region;
6041 GdkWindow *impl_window;
6042 GdkWindowImplClass *impl_class;
6044 int old_x, old_y, old_abs_x, old_abs_y;
6047 g_return_if_fail (GDK_IS_WINDOW (window));
6049 if (window->destroyed)
6052 if (gdk_window_is_toplevel (window))
6054 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6058 /* Bail early if no change */
6059 if (window->width == width &&
6060 window->height == height &&
6066 gdk_window_flush_if_exposing (window);
6068 /* Handle child windows */
6073 impl_window = gdk_window_get_impl_window (window);
6078 old_native_child_region = NULL;
6079 if (gdk_window_is_viewable (window) &&
6080 !window->input_only)
6084 old_region = cairo_region_copy (window->clip_region);
6085 /* Adjust region to parent window coords */
6086 cairo_region_translate (old_region, window->x, window->y);
6088 old_native_child_region = collect_native_child_region (window, TRUE);
6089 if (old_native_child_region)
6091 /* Adjust region to parent window coords */
6092 cairo_region_translate (old_native_child_region, window->x, window->y);
6094 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6095 * source or destination for a delayed GdkWindowRegionMove. So, we need
6096 * to flush those here for the parent window and all overlapped subwindows
6097 * of it. And we need to do this before setting the new clips as those will be
6100 gdk_window_flush_recursive (window->parent);
6104 /* Set the new position and size */
6110 if (!(width < 0 && height < 0))
6114 window->width = width;
6117 window->height = height;
6120 dx = window->x - old_x;
6121 dy = window->y - old_y;
6123 old_abs_x = window->abs_x;
6124 old_abs_y = window->abs_y;
6126 recompute_visible_regions (window, TRUE, FALSE);
6128 new_native_child_region = NULL;
6129 if (old_native_child_region)
6131 new_native_child_region = collect_native_child_region (window, TRUE);
6132 /* Adjust region to parent window coords */
6133 cairo_region_translate (new_native_child_region, window->x, window->y);
6136 if (gdk_window_has_impl (window))
6138 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6140 /* Do the actual move after recomputing things, as this will have set the shape to
6141 the now correct one, thus avoiding copying regions that should not be copied. */
6142 impl_class->move_resize (window, TRUE,
6143 window->x, window->y,
6144 window->width, window->height);
6146 else if (old_abs_x != window->abs_x ||
6147 old_abs_y != window->abs_y)
6148 move_native_children (window);
6152 new_region = cairo_region_copy (window->clip_region);
6153 /* Adjust region to parent window coords */
6154 cairo_region_translate (new_region, window->x, window->y);
6157 * Part of the data at the new location can be copied from the
6158 * old location, this area is the intersection of the old region
6159 * moved as the copy will move it and then intersected with
6163 * Everything in the old and new regions that is not copied must be
6164 * invalidated (including children) as this is newly exposed
6166 copy_area = cairo_region_copy (new_region);
6168 cairo_region_union (new_region, old_region);
6170 if (old_native_child_region)
6172 /* Don't copy from inside native children, as this is copied by
6173 * the native window move.
6175 cairo_region_subtract (old_region, old_native_child_region);
6177 cairo_region_translate (old_region, dx, dy);
6179 cairo_region_intersect (copy_area, old_region);
6181 if (new_native_child_region)
6183 /* Don't copy any bits that would cause a read from the moved
6184 native windows, as we can't read that data */
6185 cairo_region_translate (new_native_child_region, dx, dy);
6186 cairo_region_subtract (copy_area, new_native_child_region);
6187 cairo_region_translate (new_native_child_region, -dx, -dy);
6190 cairo_region_subtract (new_region, copy_area);
6192 /* Convert old region to impl coords */
6193 cairo_region_translate (old_region, -dx + window->abs_x - window->x, -dy + window->abs_y - window->y);
6195 /* convert from parent coords to impl */
6196 cairo_region_translate (copy_area, window->abs_x - window->x, window->abs_y - window->y);
6198 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6200 /* Invalidate affected part in the parent window
6201 * (no higher window should be affected)
6202 * We also invalidate any children in that area, which could include
6203 * this window if it still overlaps that area.
6205 if (old_native_child_region)
6207 /* No need to expose the region that the native window move copies */
6208 cairo_region_translate (old_native_child_region, dx, dy);
6209 cairo_region_intersect (old_native_child_region, new_native_child_region);
6210 cairo_region_subtract (new_region, old_native_child_region);
6212 gdk_window_invalidate_region_full (window->parent, new_region, TRUE, CLEAR_BG_ALL);
6214 cairo_region_destroy (old_region);
6215 cairo_region_destroy (new_region);
6218 if (old_native_child_region)
6220 cairo_region_destroy (old_native_child_region);
6221 cairo_region_destroy (new_native_child_region);
6224 _gdk_synthesize_crossing_events_for_geometry_change (window);
6231 * @window: a #GdkWindow
6232 * @x: X coordinate relative to window's parent
6233 * @y: Y coordinate relative to window's parent
6235 * Repositions a window relative to its parent window.
6236 * For toplevel windows, window managers may ignore or modify the move;
6237 * you should probably use gtk_window_move() on a #GtkWindow widget
6238 * anyway, instead of using GDK functions. For child windows,
6239 * the move will reliably succeed.
6241 * If you're also planning to resize the window, use gdk_window_move_resize()
6242 * to both move and resize simultaneously, for a nicer visual effect.
6245 gdk_window_move (GdkWindow *window,
6249 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6253 * gdk_window_resize:
6254 * @window: a #GdkWindow
6255 * @width: new width of the window
6256 * @height: new height of the window
6258 * Resizes @window; for toplevel windows, asks the window manager to resize
6259 * the window. The window manager may not allow the resize. When using GTK+,
6260 * use gtk_window_resize() instead of this low-level GDK function.
6262 * Windows may not be resized below 1x1.
6264 * If you're also planning to move the window, use gdk_window_move_resize()
6265 * to both move and resize simultaneously, for a nicer visual effect.
6268 gdk_window_resize (GdkWindow *window,
6272 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6277 * gdk_window_move_resize:
6278 * @window: a #GdkWindow
6279 * @x: new X position relative to window's parent
6280 * @y: new Y position relative to window's parent
6282 * @height: new height
6284 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6285 * except that both operations are performed at once, avoiding strange
6286 * visual effects. (i.e. the user may be able to see the window first
6287 * move, then resize, if you don't use gdk_window_move_resize().)
6290 gdk_window_move_resize (GdkWindow *window,
6296 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6301 * gdk_window_scroll:
6302 * @window: a #GdkWindow
6303 * @dx: Amount to scroll in the X direction
6304 * @dy: Amount to scroll in the Y direction
6306 * Scroll the contents of @window, both pixels and children, by the
6307 * given amount. @window itself does not move. Portions of the window
6308 * that the scroll operation brings in from offscreen areas are
6309 * invalidated. The invalidated region may be bigger than what would
6310 * strictly be necessary.
6312 * For X11, a minimum area will be invalidated if the window has no
6313 * subwindows, or if the edges of the window's parent do not extend
6314 * beyond the edges of the window. In other cases, a multi-step process
6315 * is used to scroll the window which may produce temporary visual
6316 * artifacts and unnecessary invalidations.
6319 gdk_window_scroll (GdkWindow *window,
6323 GdkWindow *impl_window;
6324 cairo_region_t *copy_area, *noncopy_area;
6325 cairo_region_t *old_native_child_region, *new_native_child_region;
6328 g_return_if_fail (GDK_IS_WINDOW (window));
6330 if (dx == 0 && dy == 0)
6333 if (window->destroyed)
6336 gdk_window_flush_if_exposing (window);
6338 old_native_child_region = collect_native_child_region (window, FALSE);
6339 if (old_native_child_region)
6341 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6342 * source or destination for a delayed GdkWindowRegionMove. So, we need
6343 * to flush those here for the window and all overlapped subwindows
6344 * of it. And we need to do this before setting the new clips as those will be
6347 gdk_window_flush_recursive (window);
6351 /* First move all child windows, without causing invalidation */
6353 tmp_list = window->children;
6356 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6358 /* Just update the positions, the bits will move with the copy */
6362 tmp_list = tmp_list->next;
6365 recompute_visible_regions (window, FALSE, TRUE);
6367 new_native_child_region = NULL;
6368 if (old_native_child_region)
6369 new_native_child_region = collect_native_child_region (window, FALSE);
6371 move_native_children (window);
6373 /* Then copy the actual bits of the window w/ child windows */
6375 impl_window = gdk_window_get_impl_window (window);
6377 /* Calculate the area that can be gotten by copying the old area */
6378 copy_area = cairo_region_copy (window->clip_region);
6379 if (old_native_child_region)
6381 /* Don't copy from inside native children, as this is copied by
6382 * the native window move.
6384 cairo_region_subtract (copy_area, old_native_child_region);
6386 /* Don't copy any bits that would cause a read from the moved
6387 native windows, as we can't read that data */
6388 cairo_region_subtract (copy_area, new_native_child_region);
6390 cairo_region_translate (copy_area, dx, dy);
6391 cairo_region_intersect (copy_area, window->clip_region);
6393 /* And the rest need to be invalidated */
6394 noncopy_area = cairo_region_copy (window->clip_region);
6395 cairo_region_subtract (noncopy_area, copy_area);
6397 /* convert from window coords to impl */
6398 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6400 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6402 /* Invalidate not copied regions */
6403 if (old_native_child_region)
6405 /* No need to expose the region that the native window move copies */
6406 cairo_region_translate (old_native_child_region, dx, dy);
6407 cairo_region_intersect (old_native_child_region, new_native_child_region);
6408 cairo_region_subtract (noncopy_area, old_native_child_region);
6410 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6412 cairo_region_destroy (noncopy_area);
6414 if (old_native_child_region)
6416 cairo_region_destroy (old_native_child_region);
6417 cairo_region_destroy (new_native_child_region);
6420 _gdk_synthesize_crossing_events_for_geometry_change (window);
6424 * gdk_window_move_region:
6425 * @window: a #GdkWindow
6426 * @region: The #cairo_region_t to move
6427 * @dx: Amount to move in the X direction
6428 * @dy: Amount to move in the Y direction
6430 * Move the part of @window indicated by @region by @dy pixels in the Y
6431 * direction and @dx pixels in the X direction. The portions of @region
6432 * that not covered by the new position of @region are invalidated.
6434 * Child windows are not moved.
6439 gdk_window_move_region (GdkWindow *window,
6440 const cairo_region_t *region,
6444 GdkWindow *impl_window;
6445 cairo_region_t *nocopy_area;
6446 cairo_region_t *copy_area;
6448 g_return_if_fail (GDK_IS_WINDOW (window));
6449 g_return_if_fail (region != NULL);
6451 if (dx == 0 && dy == 0)
6454 if (window->destroyed)
6457 impl_window = gdk_window_get_impl_window (window);
6459 /* compute source regions */
6460 copy_area = cairo_region_copy (region);
6461 cairo_region_intersect (copy_area, window->clip_region_with_children);
6463 /* compute destination regions */
6464 cairo_region_translate (copy_area, dx, dy);
6465 cairo_region_intersect (copy_area, window->clip_region_with_children);
6467 /* Invalidate parts of the region (source and dest) not covered
6469 nocopy_area = cairo_region_copy (region);
6470 cairo_region_translate (nocopy_area, dx, dy);
6471 cairo_region_union (nocopy_area, region);
6472 cairo_region_subtract (nocopy_area, copy_area);
6474 /* convert from window coords to impl */
6475 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6476 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6478 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6479 cairo_region_destroy (nocopy_area);
6483 * gdk_window_set_background:
6484 * @window: a #GdkWindow
6485 * @color: a #GdkColor
6487 * Sets the background color of @window. (However, when using GTK+,
6488 * set the background of a widget with gtk_widget_modify_bg() - if
6489 * you're an application - or gtk_style_set_background() - if you're
6490 * implementing a custom widget.)
6492 * See also gdk_window_set_background_pattern().
6495 gdk_window_set_background (GdkWindow *window,
6496 const GdkColor *color)
6498 cairo_pattern_t *pattern;
6500 g_return_if_fail (GDK_IS_WINDOW (window));
6502 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6503 color->green / 65535.,
6504 color->blue / 65535.);
6506 gdk_window_set_background_pattern (window, pattern);
6508 cairo_pattern_destroy (pattern);
6512 * gdk_window_set_background_rgba:
6513 * @window: a #GdkWindow
6514 * @rgba: a #GdkRGBA color
6516 * Sets the background color of @window.
6518 * See also gdk_window_set_background_pattern().
6521 gdk_window_set_background_rgba (GdkWindow *window,
6524 cairo_pattern_t *pattern;
6526 g_return_if_fail (GDK_IS_WINDOW (window));
6527 g_return_if_fail (rgba != NULL);
6529 pattern = cairo_pattern_create_rgba (rgba->red, rgba->green,
6530 rgba->blue, rgba->alpha);
6532 gdk_window_set_background_pattern (window, pattern);
6534 cairo_pattern_destroy (pattern);
6538 * gdk_window_set_background_pattern:
6539 * @window: a #GdkWindow
6540 * @pattern: (allow-none): a pattern to use, or %NULL
6542 * Sets the background of @window.
6544 * A background of %NULL means that the window will inherit its
6545 * background form its parent window.
6547 * The windowing system will normally fill a window with its background
6548 * when the window is obscured then exposed.
6551 gdk_window_set_background_pattern (GdkWindow *window,
6552 cairo_pattern_t *pattern)
6554 g_return_if_fail (GDK_IS_WINDOW (window));
6557 cairo_pattern_reference (pattern);
6558 if (window->background)
6559 cairo_pattern_destroy (window->background);
6560 window->background = pattern;
6562 if (gdk_window_has_impl (window) &&
6563 !window->input_only)
6565 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6566 impl_class->set_background (window, pattern);
6571 * gdk_window_get_background_pattern:
6574 * Gets the pattern used to clear the background on @window. If @window
6575 * does not have its own background and reuses the parent's, %NULL is
6576 * returned and you'll have to query it yourself.
6578 * Returns: (transfer none): The pattern to use for the background or
6579 * %NULL to use the parent's background.
6584 gdk_window_get_background_pattern (GdkWindow *window)
6586 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6588 return window->background;
6592 update_cursor_foreach (GdkDisplay *display,
6594 GdkPointerWindowInfo *pointer_info,
6597 GdkWindow *window = user_data;
6599 if (_gdk_native_windows ||
6600 window->window_type == GDK_WINDOW_ROOT ||
6601 window->window_type == GDK_WINDOW_FOREIGN)
6602 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_device_cursor (window, device, window->cursor);
6603 else if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6604 update_cursor (display, device);
6608 * gdk_window_get_cursor:
6609 * @window: a #GdkWindow
6611 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6612 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6613 * there is no custom cursor set on the specified window, and it is
6614 * using the cursor for its parent window.
6616 * Return value: (transfer none): a #GdkCursor, or %NULL. The returned
6617 * object is owned by the #GdkWindow and should not be unreferenced
6618 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6624 gdk_window_get_cursor (GdkWindow *window)
6626 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6628 return window->cursor;
6632 * gdk_window_set_cursor:
6633 * @window: a #GdkWindow
6634 * @cursor: (allow-none): a cursor
6636 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6637 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6638 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6639 * to gdk_window_set_cursor() means that @window will use the cursor of its
6640 * parent window. Most windows should use this default.
6643 gdk_window_set_cursor (GdkWindow *window,
6646 GdkDisplay *display;
6648 g_return_if_fail (GDK_IS_WINDOW (window));
6650 display = gdk_window_get_display (window);
6654 g_object_unref (window->cursor);
6655 window->cursor = NULL;
6658 if (!GDK_WINDOW_DESTROYED (window))
6661 window->cursor = g_object_ref (cursor);
6663 _gdk_display_pointer_info_foreach (display,
6664 update_cursor_foreach,
6667 g_object_notify (G_OBJECT (window), "cursor");
6672 * gdk_window_get_device_cursor:
6673 * @window: a #GdkWindow.
6674 * @device: a master, pointer #GdkDevice.
6676 * Retrieves a #GdkCursor pointer for the @device currently set on the
6677 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6678 * there is no custom cursor set on the specified window, and it is
6679 * using the cursor for its parent window.
6681 * Returns: (transfer none): a #GdkCursor, or %NULL. The returned
6682 * object is owned by the #GdkWindow and should not be unreferenced
6683 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6689 gdk_window_get_device_cursor (GdkWindow *window,
6692 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6693 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6694 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
6695 g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER, NULL);
6697 return g_hash_table_lookup (window->device_cursor, device);
6701 * gdk_window_set_device_cursor:
6702 * @window: a #Gdkwindow
6703 * @device: a master, pointer #GdkDevice
6704 * @cursor: a #GdkCursor
6706 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6707 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6708 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6709 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6710 * @window will use the cursor of its parent window. Most windows should
6716 gdk_window_set_device_cursor (GdkWindow *window,
6720 GdkDisplay *display;
6722 g_return_if_fail (GDK_IS_WINDOW (window));
6723 g_return_if_fail (GDK_IS_DEVICE (device));
6724 g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
6725 g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
6727 display = gdk_window_get_display (window);
6730 g_hash_table_remove (window->device_cursor, device);
6732 g_hash_table_replace (window->device_cursor, device, g_object_ref (cursor));
6734 if (!GDK_WINDOW_DESTROYED (window))
6736 GdkPointerWindowInfo *pointer_info;
6738 pointer_info = _gdk_display_get_pointer_info (display, device);
6740 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6741 update_cursor (display, device);
6746 * gdk_window_get_geometry:
6747 * @window: a #GdkWindow
6748 * @x: (out) (allow-none): return location for X coordinate of window (relative to its parent)
6749 * @y: (out) (allow-none): return location for Y coordinate of window (relative to its parent)
6750 * @width: (out) (allow-none): return location for width of window
6751 * @height: (out) (allow-none): return location for height of window
6753 * Any of the return location arguments to this function may be %NULL,
6754 * if you aren't interested in getting the value of that field.
6756 * The X and Y coordinates returned are relative to the parent window
6757 * of @window, which for toplevels usually means relative to the
6758 * window decorations (titlebar, etc.) rather than relative to the
6759 * root window (screen-size background window).
6761 * On the X11 platform, the geometry is obtained from the X server,
6762 * so reflects the latest position of @window; this may be out-of-sync
6763 * with the position of @window delivered in the most-recently-processed
6764 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6765 * position from the most recent configure event.
6768 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6769 * to call gdk_window_get_position(), gdk_window_get_width() and
6770 * gdk_window_get_height() instead, because it avoids the roundtrip to
6771 * the X server and because these functions support the full 32-bit
6772 * coordinate space, whereas gdk_window_get_geometry() is restricted to
6773 * the 16-bit coordinates of X11.
6777 gdk_window_get_geometry (GdkWindow *window,
6784 GdkWindowImplClass *impl_class;
6788 GDK_NOTE (MULTIHEAD,
6789 g_message ("gdk_window_get_geometry(): Window needs "
6790 "to be non-NULL to be multi head safe"));
6791 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
6794 g_return_if_fail (GDK_IS_WINDOW (window));
6796 if (!GDK_WINDOW_DESTROYED (window))
6798 if (gdk_window_has_impl (window))
6800 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6801 impl_class->get_geometry (window, x, y,
6803 /* This reports the position wrt to the native parent, we need to convert
6804 it to be relative to the client side parent */
6805 parent = window->parent;
6806 if (parent && !gdk_window_has_impl (parent))
6809 *x -= parent->abs_x;
6811 *y -= parent->abs_y;
6821 *width = window->width;
6823 *height = window->height;
6829 * gdk_window_get_width:
6830 * @window: a #GdkWindow
6832 * Returns the width of the given @window.
6834 * On the X11 platform the returned size is the size reported in the
6835 * most-recently-processed configure event, rather than the current
6836 * size on the X server.
6838 * Returns: The width of @window
6843 gdk_window_get_width (GdkWindow *window)
6845 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6847 return window->width;
6851 * gdk_window_get_height:
6852 * @window: a #GdkWindow
6854 * Returns the height of the given @window.
6856 * On the X11 platform the returned size is the size reported in the
6857 * most-recently-processed configure event, rather than the current
6858 * size on the X server.
6860 * Returns: The height of @window
6865 gdk_window_get_height (GdkWindow *window)
6867 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6869 return window->height;
6873 * gdk_window_get_origin:
6874 * @window: a #GdkWindow
6875 * @x: (out) (allow-none): return location for X coordinate
6876 * @y: (out) (allow-none): return location for Y coordinate
6878 * Obtains the position of a window in root window coordinates.
6879 * (Compare with gdk_window_get_position() and
6880 * gdk_window_get_geometry() which return the position of a window
6881 * relative to its parent window.)
6883 * Return value: not meaningful, ignore
6886 gdk_window_get_origin (GdkWindow *window,
6890 GdkWindowImplClass *impl_class;
6892 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6894 if (GDK_WINDOW_DESTROYED (window))
6903 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6904 impl_class->get_root_coords (window,
6913 * gdk_window_get_root_coords:
6914 * @window: a #GdkWindow
6915 * @x: X coordinate in window
6916 * @y: Y coordinate in window
6917 * @root_x: (out): return location for X coordinate
6918 * @root_y: (out): return location for Y coordinate
6920 * Obtains the position of a window position in root
6921 * window coordinates. This is similar to
6922 * gdk_window_get_origin() but allows you go pass
6923 * in any position in the window, not just the origin.
6928 gdk_window_get_root_coords (GdkWindow *window,
6934 GdkWindowImplClass *impl_class;
6936 g_return_if_fail (GDK_IS_WINDOW (window));
6938 if (GDK_WINDOW_DESTROYED (window))
6947 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6948 impl_class->get_root_coords (window,
6955 * gdk_window_coords_to_parent:
6956 * @window: a child window
6957 * @x: X coordinate in child's coordinate system
6958 * @y: Y coordinate in child's coordinate system
6959 * @parent_x: (out) (allow-none): return location for X coordinate
6960 * in parent's coordinate system, or %NULL
6961 * @parent_y: (out) (allow-none): return location for Y coordinate
6962 * in parent's coordinate system, or %NULL
6964 * Transforms window coordinates from a child window to its parent
6965 * window, where the parent window is the normal parent as returned by
6966 * gdk_window_get_parent() for normal windows, and the window's
6967 * embedder as returned by gdk_offscreen_window_get_embedder() for
6968 * offscreen windows.
6970 * For normal windows, calling this function is equivalent to adding
6971 * the return values of gdk_window_get_position() to the child coordinates.
6972 * For offscreen windows however (which can be arbitrarily transformed),
6973 * this function calls the GdkWindow::to-embedder: signal to translate
6976 * You should always use this function when writing generic code that
6977 * walks up a window hierarchy.
6979 * See also: gdk_window_coords_from_parent()
6984 gdk_window_coords_to_parent (GdkWindow *window,
6990 g_return_if_fail (GDK_IS_WINDOW (window));
6992 if (gdk_window_is_offscreen (window))
6996 to_embedder (window, x, y, &px, &py);
7007 *parent_x = x + window->x;
7010 *parent_y = y + window->y;
7015 * gdk_window_coords_from_parent:
7016 * @window: a child window
7017 * @parent_x: X coordinate in parent's coordinate system
7018 * @parent_y: Y coordinate in parent's coordinate system
7019 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7020 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7022 * Transforms window coordinates from a parent window to a child
7023 * window, where the parent window is the normal parent as returned by
7024 * gdk_window_get_parent() for normal windows, and the window's
7025 * embedder as returned by gdk_offscreen_window_get_embedder() for
7026 * offscreen windows.
7028 * For normal windows, calling this function is equivalent to subtracting
7029 * the return values of gdk_window_get_position() from the parent coordinates.
7030 * For offscreen windows however (which can be arbitrarily transformed),
7031 * this function calls the GdkWindow::from-embedder: signal to translate
7034 * You should always use this function when writing generic code that
7035 * walks down a window hierarchy.
7037 * See also: gdk_window_coords_to_parent()
7042 gdk_window_coords_from_parent (GdkWindow *window,
7048 g_return_if_fail (GDK_IS_WINDOW (window));
7050 if (gdk_window_is_offscreen (window))
7054 from_embedder (window, parent_x, parent_y, &cx, &cy);
7065 *x = parent_x - window->x;
7068 *y = parent_y - window->y;
7073 * gdk_window_shape_combine_region:
7074 * @window: a #GdkWindow
7075 * @shape_region: region of window to be non-transparent
7076 * @offset_x: X position of @shape_region in @window coordinates
7077 * @offset_y: Y position of @shape_region in @window coordinates
7079 * Makes pixels in @window outside @shape_region be transparent,
7080 * so that the window may be nonrectangular.
7082 * If @shape_region is %NULL, the shape will be unset, so the whole
7083 * window will be opaque again. @offset_x and @offset_y are ignored
7084 * if @shape_region is %NULL.
7086 * On the X11 platform, this uses an X server extension which is
7087 * widely available on most common platforms, but not available on
7088 * very old X servers, and occasionally the implementation will be
7089 * buggy. On servers without the shape extension, this function
7092 * This function works on both toplevel and child windows.
7095 gdk_window_shape_combine_region (GdkWindow *window,
7096 const cairo_region_t *shape_region,
7100 cairo_region_t *old_region, *new_region, *diff;
7102 g_return_if_fail (GDK_IS_WINDOW (window));
7104 if (GDK_WINDOW_DESTROYED (window))
7107 if (!window->shape && shape_region == NULL)
7110 window->shaped = (shape_region != NULL);
7113 cairo_region_destroy (window->shape);
7116 if (GDK_WINDOW_IS_MAPPED (window))
7117 old_region = cairo_region_copy (window->clip_region);
7121 window->shape = cairo_region_copy (shape_region);
7122 cairo_region_translate (window->shape, offset_x, offset_y);
7125 window->shape = NULL;
7127 recompute_visible_regions (window, TRUE, FALSE);
7129 if (gdk_window_has_impl (window) &&
7130 !should_apply_clip_as_shape (window))
7131 apply_shape (window, window->shape);
7135 new_region = cairo_region_copy (window->clip_region);
7137 /* New area in the window, needs invalidation */
7138 diff = cairo_region_copy (new_region);
7139 cairo_region_subtract (diff, old_region);
7141 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7143 cairo_region_destroy (diff);
7145 if (!gdk_window_is_toplevel (window))
7147 /* New area in the non-root parent window, needs invalidation */
7148 diff = cairo_region_copy (old_region);
7149 cairo_region_subtract (diff, new_region);
7151 /* Adjust region to parent window coords */
7152 cairo_region_translate (diff, window->x, window->y);
7154 gdk_window_invalidate_region_full (window->parent, diff, TRUE, CLEAR_BG_ALL);
7156 cairo_region_destroy (diff);
7159 cairo_region_destroy (new_region);
7160 cairo_region_destroy (old_region);
7165 do_child_shapes (GdkWindow *window,
7169 cairo_region_t *region;
7173 r.width = window->width;
7174 r.height = window->height;
7176 region = cairo_region_create_rectangle (&r);
7177 remove_child_area (window, NULL, FALSE, region);
7179 if (merge && window->shape)
7180 cairo_region_subtract (region, window->shape);
7182 gdk_window_shape_combine_region (window, region, 0, 0);
7186 * gdk_window_set_child_shapes:
7187 * @window: a #GdkWindow
7189 * Sets the shape mask of @window to the union of shape masks
7190 * for all children of @window, ignoring the shape mask of @window
7191 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7192 * the shape mask of @window in the masks to be merged.
7195 gdk_window_set_child_shapes (GdkWindow *window)
7197 g_return_if_fail (GDK_IS_WINDOW (window));
7199 do_child_shapes (window, FALSE);
7203 * gdk_window_merge_child_shapes:
7204 * @window: a #GdkWindow
7206 * Merges the shape masks for any child windows into the
7207 * shape mask for @window. i.e. the union of all masks
7208 * for @window and its children will become the new mask
7209 * for @window. See gdk_window_shape_combine_region().
7211 * This function is distinct from gdk_window_set_child_shapes()
7212 * because it includes @window's shape mask in the set of shapes to
7216 gdk_window_merge_child_shapes (GdkWindow *window)
7218 g_return_if_fail (GDK_IS_WINDOW (window));
7220 do_child_shapes (window, TRUE);
7224 * gdk_window_input_shape_combine_region:
7225 * @window: a #GdkWindow
7226 * @shape_region: region of window to be non-transparent
7227 * @offset_x: X position of @shape_region in @window coordinates
7228 * @offset_y: Y position of @shape_region in @window coordinates
7230 * Like gdk_window_shape_combine_region(), but the shape applies
7231 * only to event handling. Mouse events which happen while
7232 * the pointer position corresponds to an unset bit in the
7233 * mask will be passed on the window below @window.
7235 * An input shape is typically used with RGBA windows.
7236 * The alpha channel of the window defines which pixels are
7237 * invisible and allows for nicely antialiased borders,
7238 * and the input shape controls where the window is
7241 * On the X11 platform, this requires version 1.1 of the
7244 * On the Win32 platform, this functionality is not present and the
7245 * function does nothing.
7250 gdk_window_input_shape_combine_region (GdkWindow *window,
7251 const cairo_region_t *shape_region,
7255 GdkWindowImplClass *impl_class;
7257 g_return_if_fail (GDK_IS_WINDOW (window));
7259 if (GDK_WINDOW_DESTROYED (window))
7262 if (window->input_shape)
7263 cairo_region_destroy (window->input_shape);
7267 window->input_shape = cairo_region_copy (shape_region);
7268 cairo_region_translate (window->input_shape, offset_x, offset_y);
7271 window->input_shape = NULL;
7273 if (gdk_window_has_impl (window))
7275 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7276 impl_class->input_shape_combine_region (window, window->input_shape, 0, 0);
7279 /* Pointer may have e.g. moved outside window due to the input mask change */
7280 _gdk_synthesize_crossing_events_for_geometry_change (window);
7284 do_child_input_shapes (GdkWindow *window,
7288 cairo_region_t *region;
7292 r.width = window->width;
7293 r.height = window->height;
7295 region = cairo_region_create_rectangle (&r);
7296 remove_child_area (window, NULL, TRUE, region);
7298 if (merge && window->shape)
7299 cairo_region_subtract (region, window->shape);
7300 if (merge && window->input_shape)
7301 cairo_region_subtract (region, window->input_shape);
7303 gdk_window_input_shape_combine_region (window, region, 0, 0);
7308 * gdk_window_set_child_input_shapes:
7309 * @window: a #GdkWindow
7311 * Sets the input shape mask of @window to the union of input shape masks
7312 * for all children of @window, ignoring the input shape mask of @window
7313 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7314 * the input shape mask of @window in the masks to be merged.
7319 gdk_window_set_child_input_shapes (GdkWindow *window)
7321 g_return_if_fail (GDK_IS_WINDOW (window));
7323 do_child_input_shapes (window, FALSE);
7327 * gdk_window_merge_child_input_shapes:
7328 * @window: a #GdkWindow
7330 * Merges the input shape masks for any child windows into the
7331 * input shape mask for @window. i.e. the union of all input masks
7332 * for @window and its children will become the new input mask
7333 * for @window. See gdk_window_input_shape_combine_region().
7335 * This function is distinct from gdk_window_set_child_input_shapes()
7336 * because it includes @window's input shape mask in the set of
7337 * shapes to be merged.
7342 gdk_window_merge_child_input_shapes (GdkWindow *window)
7344 g_return_if_fail (GDK_IS_WINDOW (window));
7346 do_child_input_shapes (window, TRUE);
7351 * gdk_window_set_static_gravities:
7352 * @window: a #GdkWindow
7353 * @use_static: %TRUE to turn on static gravity
7355 * Set the bit gravity of the given window to static, and flag it so
7356 * all children get static subwindow gravity. This is used if you are
7357 * implementing scary features that involve deep knowledge of the
7358 * windowing system. Don't worry about it unless you have to.
7360 * Return value: %TRUE if the server supports static gravity
7363 gdk_window_set_static_gravities (GdkWindow *window,
7364 gboolean use_static)
7366 GdkWindowImplClass *impl_class;
7368 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7370 if (gdk_window_has_impl (window))
7372 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7373 return impl_class->set_static_gravities (window, use_static);
7380 * gdk_window_get_composited:
7381 * @window: a #GdkWindow
7383 * Determines whether @window is composited.
7385 * See gdk_window_set_composited().
7387 * Returns: %TRUE if the window is composited.
7392 gdk_window_get_composited (GdkWindow *window)
7394 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7396 return window->composited;
7400 * gdk_window_set_composited:
7401 * @window: a #GdkWindow
7402 * @composited: %TRUE to set the window as composited
7404 * Sets a #GdkWindow as composited, or unsets it. Composited
7405 * windows do not automatically have their contents drawn to
7406 * the screen. Drawing is redirected to an offscreen buffer
7407 * and an expose event is emitted on the parent of the composited
7408 * window. It is the responsibility of the parent's expose handler
7409 * to manually merge the off-screen content onto the screen in
7410 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7413 * It only makes sense for child windows to be composited; see
7414 * gdk_window_set_opacity() if you need translucent toplevel
7417 * An additional effect of this call is that the area of this
7418 * window is no longer clipped from regions marked for
7419 * invalidation on its parent. Draws done on the parent
7420 * window are also no longer clipped by the child.
7422 * This call is only supported on some systems (currently,
7423 * only X11 with new enough Xcomposite and Xdamage extensions).
7424 * You must call gdk_display_supports_composite() to check if
7425 * setting a window as composited is supported before
7426 * attempting to do so.
7431 gdk_window_set_composited (GdkWindow *window,
7432 gboolean composited)
7434 GdkDisplay *display;
7435 GdkWindowImplClass *impl_class;
7437 g_return_if_fail (GDK_IS_WINDOW (window));
7439 composited = composited != FALSE;
7441 if (window->composited == composited)
7445 gdk_window_ensure_native (window);
7447 display = gdk_window_get_display (window);
7449 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7451 if (composited && (!gdk_display_supports_composite (display) || !impl_class->set_composited))
7453 g_warning ("gdk_window_set_composited called but "
7454 "compositing is not supported");
7458 impl_class->set_composited (window, composited);
7460 recompute_visible_regions (window, TRUE, FALSE);
7462 if (GDK_WINDOW_IS_MAPPED (window))
7463 gdk_window_invalidate_in_parent (window);
7465 window->composited = composited;
7469 * gdk_window_get_modal_hint:
7470 * @window: A toplevel #GdkWindow.
7472 * Determines whether or not the window manager is hinted that @window
7473 * has modal behaviour.
7475 * Return value: whether or not the window has the modal hint set.
7480 gdk_window_get_modal_hint (GdkWindow *window)
7482 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7484 return window->modal_hint;
7488 * gdk_window_get_accept_focus:
7489 * @window: a toplevel #GdkWindow.
7491 * Determines whether or not the desktop environment shuld be hinted that
7492 * the window does not want to receive input focus.
7494 * Return value: whether or not the window should receive input focus.
7499 gdk_window_get_accept_focus (GdkWindow *window)
7501 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7503 return window->accept_focus;
7507 * gdk_window_get_focus_on_map:
7508 * @window: a toplevel #GdkWindow.
7510 * Determines whether or not the desktop environment should be hinted that the
7511 * window does not want to receive input focus when it is mapped.
7513 * Return value: whether or not the window wants to receive input focus when
7519 gdk_window_get_focus_on_map (GdkWindow *window)
7521 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7523 return window->focus_on_map;
7527 * gdk_window_is_input_only:
7528 * @window: a toplevel #GdkWindow
7530 * Determines whether or not the window is an input only window.
7532 * Return value: %TRUE if @window is input only
7537 gdk_window_is_input_only (GdkWindow *window)
7539 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7541 return window->input_only;
7545 * gdk_window_is_shaped:
7546 * @window: a toplevel #GdkWindow
7548 * Determines whether or not the window is shaped.
7550 * Return value: %TRUE if @window is shaped
7555 gdk_window_is_shaped (GdkWindow *window)
7557 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7559 return window->shaped;
7563 window_get_size_rectangle (GdkWindow *window,
7566 rect->x = rect->y = 0;
7567 rect->width = window->width;
7568 rect->height = window->height;
7571 /* Calculates the real clipping region for a window, in window coordinates,
7572 * taking into account other windows, gc clip region and gc clip mask.
7575 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7576 GdkWindow *base_window,
7577 gboolean do_children,
7578 gint *base_x_offset,
7579 gint *base_y_offset)
7581 GdkRectangle visible_rect;
7582 cairo_region_t *real_clip_region;
7583 gint x_offset, y_offset;
7584 GdkWindow *parentwin, *lastwin;
7591 if (!window->viewable || window->input_only)
7592 return cairo_region_create ();
7594 window_get_size_rectangle (window, &visible_rect);
7596 /* real_clip_region is in window coordinates */
7597 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7599 x_offset = y_offset = 0;
7603 parentwin = lastwin;
7605 parentwin = lastwin->parent;
7607 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7608 for (; parentwin != NULL &&
7609 (parentwin == window || lastwin != base_window);
7610 lastwin = parentwin, parentwin = lastwin->parent)
7613 GdkRectangle real_clip_rect;
7615 if (parentwin != window)
7617 x_offset += lastwin->x;
7618 y_offset += lastwin->y;
7621 /* children is ordered in reverse stack order */
7622 for (cur = parentwin->children;
7623 cur && cur->data != lastwin;
7626 GdkWindow *child = cur->data;
7628 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
7631 /* Ignore offscreen children, as they don't draw in their parent and
7632 * don't take part in the clipping */
7633 if (gdk_window_is_offscreen (child))
7636 window_get_size_rectangle (child, &visible_rect);
7638 /* Convert rect to "window" coords */
7639 visible_rect.x += child->x - x_offset;
7640 visible_rect.y += child->y - y_offset;
7642 /* This shortcut is really necessary for performance when there are a lot of windows */
7643 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7644 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7645 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7646 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7647 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7650 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7653 /* Clip to the parent */
7654 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7655 /* Convert rect to "window" coords */
7656 visible_rect.x += - x_offset;
7657 visible_rect.y += - y_offset;
7659 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7663 *base_x_offset = x_offset;
7665 *base_y_offset = y_offset;
7667 return real_clip_region;
7671 _gdk_window_add_damage (GdkWindow *toplevel,
7672 cairo_region_t *damaged_region)
7674 GdkDisplay *display;
7675 GdkEvent event = { 0, };
7676 event.expose.type = GDK_DAMAGE;
7677 event.expose.window = toplevel;
7678 event.expose.send_event = FALSE;
7679 event.expose.region = damaged_region;
7680 cairo_region_get_extents (event.expose.region, &event.expose.area);
7681 display = gdk_window_get_display (event.expose.window);
7682 _gdk_event_queue_append (display, gdk_event_copy (&event));
7685 /* Gets the toplevel for a window as used for events,
7686 i.e. including offscreen parents */
7688 get_event_parent (GdkWindow *window)
7690 if (gdk_window_is_offscreen (window))
7691 return gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7693 return window->parent;
7696 /* Gets the toplevel for a window as used for events,
7697 i.e. including offscreen parents going up to the native
7700 get_event_toplevel (GdkWindow *window)
7704 while ((parent = get_event_parent (window)) != NULL &&
7705 (parent->window_type != GDK_WINDOW_ROOT))
7712 _gdk_window_event_parent_of (GdkWindow *parent,
7723 w = get_event_parent (w);
7730 update_cursor (GdkDisplay *display,
7733 GdkWindow *cursor_window, *parent, *toplevel;
7734 GdkWindow *pointer_window;
7735 GdkWindowImplClass *impl_class;
7736 GdkPointerWindowInfo *pointer_info;
7737 GdkDeviceGrabInfo *grab;
7740 pointer_info = _gdk_display_get_pointer_info (display, device);
7741 pointer_window = pointer_info->window_under_pointer;
7743 /* We ignore the serials here and just pick the last grab
7744 we've sent, as that would shortly be used anyway. */
7745 grab = _gdk_display_get_last_device_grab (display, device);
7748 /* the pointer is not in a descendant of the grab window */
7749 !_gdk_window_event_parent_of (grab->window, pointer_window))
7751 /* use the cursor from the grab window */
7752 cursor_window = grab->window;
7756 /* otherwise use the cursor from the pointer window */
7757 cursor_window = pointer_window;
7760 /* Find the first window with the cursor actually set, as
7761 the cursor is inherited from the parent */
7762 while (cursor_window->cursor == NULL &&
7763 (parent = get_event_parent (cursor_window)) != NULL &&
7764 parent->window_type != GDK_WINDOW_ROOT)
7765 cursor_window = parent;
7767 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
7770 cursor = cursor_window->cursor;
7772 /* Set all cursors on toplevel, otherwise its tricky to keep track of
7773 * which native window has what cursor set. */
7774 toplevel = get_event_toplevel (pointer_window);
7775 impl_class = GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl);
7776 impl_class->set_device_cursor (toplevel, device, cursor);
7780 point_in_window (GdkWindow *window,
7785 x >= 0 && x < window->width &&
7786 y >= 0 && y < window->height &&
7787 (window->shape == NULL ||
7788 cairo_region_contains_point (window->shape,
7790 (window->input_shape == NULL ||
7791 cairo_region_contains_point (window->input_shape,
7796 convert_native_coords_to_toplevel (GdkWindow *window,
7799 gdouble *toplevel_x,
7800 gdouble *toplevel_y)
7807 while (!gdk_window_is_toplevel (window))
7811 window = window->parent;
7821 convert_toplevel_coords_to_window (GdkWindow *window,
7829 GList *children, *l;
7835 while ((parent = get_event_parent (window)) != NULL &&
7836 (parent->window_type != GDK_WINDOW_ROOT))
7838 children = g_list_prepend (children, window);
7842 for (l = children; l != NULL; l = l->next)
7843 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
7845 g_list_free (children);
7852 pick_embedded_child (GdkWindow *window,
7859 g_signal_emit (window,
7860 signals[PICK_EMBEDDED_CHILD], 0,
7867 _gdk_window_find_child_at (GdkWindow *window,
7872 double child_x, child_y;
7875 if (point_in_window (window, x, y))
7877 /* Children is ordered in reverse stack order, i.e. first is topmost */
7878 for (l = window->children; l != NULL; l = l->next)
7882 if (!GDK_WINDOW_IS_MAPPED (sub))
7885 gdk_window_coords_from_parent ((GdkWindow *)sub,
7887 &child_x, &child_y);
7888 if (point_in_window (sub, child_x, child_y))
7889 return (GdkWindow *)sub;
7892 if (window->num_offscreen_children > 0)
7894 sub = pick_embedded_child (window,
7897 return (GdkWindow *)sub;
7905 _gdk_window_find_descendant_at (GdkWindow *window,
7912 gdouble child_x, child_y;
7916 if (point_in_window (window, x, y))
7921 /* Children is ordered in reverse stack order, i.e. first is topmost */
7922 for (l = window->children; l != NULL; l = l->next)
7926 if (!GDK_WINDOW_IS_MAPPED (sub))
7929 gdk_window_coords_from_parent ((GdkWindow *)sub,
7931 &child_x, &child_y);
7932 if (point_in_window (sub, child_x, child_y))
7942 window->num_offscreen_children > 0)
7944 sub = pick_embedded_child (window,
7950 from_embedder (sub, x, y, &x, &y);
7958 /* Not in window at all */
7972 * @window: a toplevel #GdkWindow
7974 * Emits a short beep associated to @window in the appropriate
7975 * display, if supported. Otherwise, emits a short beep on
7976 * the display just as gdk_display_beep().
7981 gdk_window_beep (GdkWindow *window)
7983 GdkDisplay *display;
7984 GdkWindow *toplevel;
7986 g_return_if_fail (GDK_IS_WINDOW (window));
7988 if (GDK_WINDOW_DESTROYED (window))
7991 toplevel = get_event_toplevel (window);
7992 display = gdk_window_get_display (window);
7996 if (GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl)->beep (window))
8000 /* If windows fail to beep, we beep the display. */
8001 gdk_display_beep (display);
8005 * gdk_window_set_support_multidevice:
8006 * @window: a #GdkWindow.
8007 * @support_multidevice: %TRUE to enable multidevice support in @window.
8009 * This function will enable multidevice features in @window.
8011 * Multidevice aware windows will need to handle properly multiple,
8012 * per device enter/leave events, device grabs and grab ownerships.
8017 gdk_window_set_support_multidevice (GdkWindow *window,
8018 gboolean support_multidevice)
8020 g_return_if_fail (GDK_IS_WINDOW (window));
8022 if (GDK_WINDOW_DESTROYED (window))
8025 if (window->support_multidevice == support_multidevice)
8028 window->support_multidevice = support_multidevice;
8030 /* FIXME: What to do if called when some pointers are inside the window ? */
8034 * gdk_window_get_support_multidevice:
8035 * @window: a #GdkWindow.
8037 * Returns %TRUE if the window is aware of the existence of multiple
8040 * Returns: %TRUE if the window handles multidevice features.
8045 gdk_window_get_support_multidevice (GdkWindow *window)
8047 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8049 if (GDK_WINDOW_DESTROYED (window))
8052 return window->support_multidevice;
8055 static const guint type_masks[] = {
8056 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8057 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8058 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8059 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8060 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8061 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8062 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8063 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8064 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8065 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8066 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8067 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8068 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8069 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8070 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8071 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8072 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8073 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8074 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8075 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8076 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8077 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8078 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8079 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8080 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8081 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8082 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8083 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8084 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8085 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8086 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8087 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8088 0, /* GDK_WINDOW_STATE = 32 */
8089 0, /* GDK_SETTING = 33 */
8090 0, /* GDK_OWNER_CHANGE = 34 */
8091 0, /* GDK_GRAB_BROKEN = 35 */
8092 0, /* GDK_DAMAGE = 36 */
8094 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8096 /* send motion events if the right buttons are down */
8098 update_evmask_for_button_motion (guint evmask,
8099 GdkModifierType mask)
8101 if (evmask & GDK_BUTTON_MOTION_MASK &&
8102 mask & (GDK_BUTTON1_MASK |
8107 evmask |= GDK_POINTER_MOTION_MASK;
8109 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8110 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8111 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8112 evmask |= GDK_POINTER_MOTION_MASK;
8118 is_button_type (GdkEventType type)
8120 return type == GDK_BUTTON_PRESS ||
8121 type == GDK_2BUTTON_PRESS ||
8122 type == GDK_3BUTTON_PRESS ||
8123 type == GDK_BUTTON_RELEASE ||
8128 is_motion_type (GdkEventType type)
8130 return type == GDK_MOTION_NOTIFY ||
8131 type == GDK_ENTER_NOTIFY ||
8132 type == GDK_LEAVE_NOTIFY;
8136 find_common_ancestor (GdkWindow *win1,
8140 GList *path1 = NULL, *path2 = NULL;
8141 GList *list1, *list2;
8144 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8146 path1 = g_list_prepend (path1, tmp);
8147 tmp = get_event_parent (tmp);
8151 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8153 path2 = g_list_prepend (path2, tmp);
8154 tmp = get_event_parent (tmp);
8160 while (list1 && list2 && (list1->data == list2->data))
8163 list1 = g_list_next (list1);
8164 list2 = g_list_next (list2);
8166 g_list_free (path1);
8167 g_list_free (path2);
8173 _gdk_make_event (GdkWindow *window,
8175 GdkEvent *event_in_queue,
8176 gboolean before_event)
8178 GdkEvent *event = gdk_event_new (type);
8180 GdkModifierType the_state;
8182 the_time = gdk_event_get_time (event_in_queue);
8183 gdk_event_get_state (event_in_queue, &the_state);
8185 event->any.window = g_object_ref (window);
8186 event->any.send_event = FALSE;
8187 if (event_in_queue && event_in_queue->any.send_event)
8188 event->any.send_event = TRUE;
8192 case GDK_MOTION_NOTIFY:
8193 event->motion.time = the_time;
8194 event->motion.axes = NULL;
8195 event->motion.state = the_state;
8198 case GDK_BUTTON_PRESS:
8199 case GDK_2BUTTON_PRESS:
8200 case GDK_3BUTTON_PRESS:
8201 case GDK_BUTTON_RELEASE:
8202 event->button.time = the_time;
8203 event->button.axes = NULL;
8204 event->button.state = the_state;
8208 event->scroll.time = the_time;
8209 event->scroll.state = the_state;
8213 case GDK_KEY_RELEASE:
8214 event->key.time = the_time;
8215 event->key.state = the_state;
8218 case GDK_ENTER_NOTIFY:
8219 case GDK_LEAVE_NOTIFY:
8220 event->crossing.time = the_time;
8221 event->crossing.state = the_state;
8224 case GDK_PROPERTY_NOTIFY:
8225 event->property.time = the_time;
8226 event->property.state = the_state;
8229 case GDK_SELECTION_CLEAR:
8230 case GDK_SELECTION_REQUEST:
8231 case GDK_SELECTION_NOTIFY:
8232 event->selection.time = the_time;
8235 case GDK_PROXIMITY_IN:
8236 case GDK_PROXIMITY_OUT:
8237 event->proximity.time = the_time;
8240 case GDK_DRAG_ENTER:
8241 case GDK_DRAG_LEAVE:
8242 case GDK_DRAG_MOTION:
8243 case GDK_DRAG_STATUS:
8244 case GDK_DROP_START:
8245 case GDK_DROP_FINISHED:
8246 event->dnd.time = the_time;
8249 case GDK_FOCUS_CHANGE:
8253 case GDK_CLIENT_EVENT:
8254 case GDK_VISIBILITY_NOTIFY:
8265 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8267 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8270 _gdk_event_queue_append (gdk_window_get_display (window), event);
8276 send_crossing_event (GdkDisplay *display,
8277 GdkWindow *toplevel,
8280 GdkCrossingMode mode,
8281 GdkNotifyType notify_type,
8282 GdkWindow *subwindow,
8284 GdkDevice *source_device,
8287 GdkModifierType mask,
8289 GdkEvent *event_in_queue,
8293 guint32 window_event_mask, type_event_mask;
8294 GdkDeviceGrabInfo *grab;
8295 gboolean block_event = FALSE;
8297 grab = _gdk_display_has_device_grab (display, device, serial);
8300 !grab->owner_events)
8302 /* !owner_event => only report events wrt grab window, ignore rest */
8303 if ((GdkWindow *)window != grab->window)
8305 window_event_mask = grab->event_mask;
8308 window_event_mask = window->event_mask;
8310 if (type == GDK_LEAVE_NOTIFY)
8312 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8313 window->devices_inside = g_list_remove (window->devices_inside, device);
8315 if (!window->support_multidevice && window->devices_inside)
8317 /* Block leave events unless it's the last pointer */
8323 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8325 if (!window->support_multidevice && window->devices_inside)
8327 /* Only emit enter events for the first device */
8331 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8332 gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
8333 !g_list_find (window->devices_inside, device))
8334 window->devices_inside = g_list_prepend (window->devices_inside, device);
8340 if (window_event_mask & type_event_mask)
8342 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8343 gdk_event_set_device (event, device);
8346 gdk_event_set_source_device (event, source_device);
8348 event->crossing.time = time_;
8349 event->crossing.subwindow = subwindow;
8351 g_object_ref (subwindow);
8352 convert_toplevel_coords_to_window ((GdkWindow *)window,
8353 toplevel_x, toplevel_y,
8354 &event->crossing.x, &event->crossing.y);
8355 event->crossing.x_root = toplevel_x + toplevel->x;
8356 event->crossing.y_root = toplevel_y + toplevel->y;
8357 event->crossing.mode = mode;
8358 event->crossing.detail = notify_type;
8359 event->crossing.focus = FALSE;
8360 event->crossing.state = mask;
8365 /* The coordinates are in the toplevel window that src/dest are in.
8366 * src and dest are always (if != NULL) in the same toplevel, as
8367 * we get a leave-notify and set the window_under_pointer to null
8368 * before crossing to another toplevel.
8371 _gdk_synthesize_crossing_events (GdkDisplay *display,
8375 GdkDevice *source_device,
8376 GdkCrossingMode mode,
8379 GdkModifierType mask,
8381 GdkEvent *event_in_queue,
8383 gboolean non_linear)
8386 GdkWindow *win, *last, *next;
8390 GdkWindow *toplevel;
8391 GdkNotifyType notify_type;
8393 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8398 return; /* No crossings generated between src and dest */
8400 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8402 if (a && gdk_window_get_device_events (src, device) == 0)
8405 if (b && gdk_window_get_device_events (dest, device) == 0)
8412 c = find_common_ancestor (a, b);
8414 non_linear |= (c != a) && (c != b);
8416 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8418 toplevel = gdk_window_get_toplevel (a);
8420 /* Traverse up from a to (excluding) c sending leave events */
8422 notify_type = GDK_NOTIFY_NONLINEAR;
8424 notify_type = GDK_NOTIFY_INFERIOR;
8426 notify_type = GDK_NOTIFY_ANCESTOR;
8427 send_crossing_event (display, toplevel,
8428 a, GDK_LEAVE_NOTIFY,
8431 NULL, device, source_device,
8432 toplevel_x, toplevel_y,
8440 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8442 notify_type = GDK_NOTIFY_VIRTUAL;
8445 win = get_event_parent (a);
8446 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8448 send_crossing_event (display, toplevel,
8449 win, GDK_LEAVE_NOTIFY,
8453 device, source_device,
8454 toplevel_x, toplevel_y,
8460 win = get_event_parent (win);
8465 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8467 toplevel = gdk_window_get_toplevel ((GdkWindow *)b);
8469 /* Traverse down from c to b */
8473 win = get_event_parent (b);
8474 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8476 path = g_list_prepend (path, win);
8477 win = get_event_parent (win);
8481 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8483 notify_type = GDK_NOTIFY_VIRTUAL;
8489 list = g_list_next (list);
8495 send_crossing_event (display, toplevel,
8496 win, GDK_ENTER_NOTIFY,
8500 device, source_device,
8501 toplevel_x, toplevel_y,
8511 notify_type = GDK_NOTIFY_NONLINEAR;
8513 notify_type = GDK_NOTIFY_ANCESTOR;
8515 notify_type = GDK_NOTIFY_INFERIOR;
8517 send_crossing_event (display, toplevel,
8518 b, GDK_ENTER_NOTIFY,
8522 device, source_device,
8523 toplevel_x, toplevel_y,
8530 /* Returns the window inside the event window with the pointer in it
8531 * at the specified coordinates, or NULL if its not in any child of
8532 * the toplevel. It also takes into account !owner_events grabs.
8535 get_pointer_window (GdkDisplay *display,
8536 GdkWindow *event_window,
8542 GdkWindow *pointer_window;
8543 GdkDeviceGrabInfo *grab;
8544 GdkPointerWindowInfo *pointer_info;
8546 pointer_info = _gdk_display_get_pointer_info (display, device);
8548 if (event_window == pointer_info->toplevel_under_pointer)
8550 _gdk_window_find_descendant_at (event_window,
8551 toplevel_x, toplevel_y,
8554 pointer_window = NULL;
8556 grab = _gdk_display_has_device_grab (display, device, serial);
8558 !grab->owner_events &&
8559 pointer_window != grab->window)
8560 pointer_window = NULL;
8562 return pointer_window;
8566 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8570 GdkPointerWindowInfo *device_info;
8572 /* We don't track this if all native, and it can cause issues
8573 with the update_cursor call below */
8574 if (_gdk_native_windows)
8577 device_info = _gdk_display_get_pointer_info (display, device);
8579 if (device_info->window_under_pointer)
8580 g_object_unref (device_info->window_under_pointer);
8581 device_info->window_under_pointer = window;
8585 g_object_ref (window);
8586 update_cursor (display, device);
8589 _gdk_display_enable_motion_hints (display, device);
8594 * @window: the #GdkWindow which will own the grab (the grab window).
8595 * @owner_events: if %FALSE then all pointer events are reported with respect to
8596 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8597 * events for this application are reported as normal, but pointer events outside
8598 * this application are reported with respect to @window and only if selected by
8599 * @event_mask. In either mode, unreported events are discarded.
8600 * @event_mask: specifies the event mask, which is used in accordance with
8601 * @owner_events. Note that only pointer events (i.e. button and motion events)
8603 * @confine_to: If non-%NULL, the pointer will be confined to this
8604 * window during the grab. If the pointer is outside @confine_to, it will
8605 * automatically be moved to the closest edge of @confine_to and enter
8606 * and leave events will be generated as necessary.
8607 * @cursor: the cursor to display while the grab is active. If this is %NULL then
8608 * the normal cursors are used for @window and its descendants, and the cursor
8609 * for @window is used for all other windows.
8610 * @time_: the timestamp of the event which led to this pointer grab. This usually
8611 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8612 * the time isn't known.
8614 * Grabs the pointer (usually a mouse) so that all events are passed to this
8615 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8616 * the grab window becomes unviewable.
8617 * This overrides any previous pointer grab by this client.
8619 * Pointer grabs are used for operations which need complete control over mouse
8620 * events, even if the mouse leaves the application.
8621 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8622 * the #GtkHPaned and #GtkVPaned widgets.
8624 * Note that if the event mask of an X window has selected both button press and
8625 * button release events, then a button press event will cause an automatic
8626 * pointer grab until the button is released.
8627 * X does this automatically since most applications expect to receive button
8628 * press and release events in pairs.
8629 * It is equivalent to a pointer grab on the window with @owner_events set to
8632 * If you set up anything at the time you take the grab that needs to be cleaned
8633 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8634 * are emitted when the grab ends unvoluntarily.
8636 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8638 * Deprecated: 3.0: Use gdk_device_grab() instead.
8641 gdk_pointer_grab (GdkWindow * window,
8642 gboolean owner_events,
8643 GdkEventMask event_mask,
8644 GdkWindow * confine_to,
8649 GdkDisplay *display;
8650 GdkDeviceManager *device_manager;
8652 GdkGrabStatus res = 0;
8654 GList *devices, *dev;
8656 g_return_val_if_fail (window != NULL, 0);
8657 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8658 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8660 /* We need a native window for confine to to work, ensure we have one */
8663 if (!gdk_window_ensure_native (confine_to))
8665 g_warning ("Can't confine to grabbed window, not native");
8670 /* Non-viewable client side window => fail */
8671 if (!_gdk_window_has_impl (window) &&
8672 !gdk_window_is_viewable (window))
8673 return GDK_GRAB_NOT_VIEWABLE;
8675 if (_gdk_native_windows)
8678 native = gdk_window_get_toplevel (window);
8679 while (gdk_window_is_offscreen (native))
8681 native = gdk_offscreen_window_get_embedder (native);
8683 if (native == NULL ||
8684 (!_gdk_window_has_impl (native) &&
8685 !gdk_window_is_viewable (native)))
8686 return GDK_GRAB_NOT_VIEWABLE;
8688 native = gdk_window_get_toplevel (native);
8691 display = gdk_window_get_display (window);
8693 serial = _gdk_display_get_next_serial (display);
8694 device_manager = gdk_display_get_device_manager (display);
8695 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8697 /* FIXME: Should this be generic to all backends? */
8698 /* FIXME: What happens with extended devices? */
8699 for (dev = devices; dev; dev = dev->next)
8703 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
8706 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
8709 get_native_grab_event_mask (event_mask),
8714 if (res == GDK_GRAB_SUCCESS)
8715 _gdk_display_add_device_grab (display,
8727 /* FIXME: handle errors when grabbing */
8729 g_list_free (devices);
8735 * gdk_keyboard_grab:
8736 * @window: the #GdkWindow which will own the grab (the grab window).
8737 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8738 * @window. If %TRUE then keyboard events for this application are
8739 * reported as normal, but keyboard events outside this application
8740 * are reported with respect to @window. Both key press and key
8741 * release events are always reported, independant of the event mask
8742 * set by the application.
8743 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8746 * Grabs the keyboard so that all events are passed to this
8747 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8748 * This overrides any previous keyboard grab by this client.
8750 * If you set up anything at the time you take the grab that needs to be cleaned
8751 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8752 * are emitted when the grab ends unvoluntarily.
8754 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8756 * Deprecated: 3.0: Use gdk_device_grab() instead.
8759 gdk_keyboard_grab (GdkWindow *window,
8760 gboolean owner_events,
8764 GdkDisplay *display;
8765 GdkDeviceManager *device_manager;
8767 GdkGrabStatus res = 0;
8769 GList *devices, *dev;
8771 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8773 /* Non-viewable client side window => fail */
8774 if (!_gdk_window_has_impl (window) &&
8775 !gdk_window_is_viewable (window))
8776 return GDK_GRAB_NOT_VIEWABLE;
8778 if (_gdk_native_windows)
8781 native = gdk_window_get_toplevel (window);
8783 while (gdk_window_is_offscreen (native))
8785 native = gdk_offscreen_window_get_embedder (native);
8787 if (native == NULL ||
8788 (!_gdk_window_has_impl (native) &&
8789 !gdk_window_is_viewable (native)))
8790 return GDK_GRAB_NOT_VIEWABLE;
8792 native = gdk_window_get_toplevel (native);
8795 display = gdk_window_get_display (window);
8796 serial = _gdk_display_get_next_serial (display);
8797 device_manager = gdk_display_get_device_manager (display);
8798 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8800 /* FIXME: Should this be generic to all backends? */
8801 /* FIXME: What happens with extended devices? */
8802 for (dev = devices; dev; dev = dev->next)
8806 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
8809 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
8812 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
8817 if (res == GDK_GRAB_SUCCESS)
8818 _gdk_display_add_device_grab (display,
8829 /* FIXME: handle errors when grabbing */
8831 g_list_free (devices);
8837 * gdk_window_geometry_changed:
8838 * @window: an embedded offscreen #GdkWindow
8840 * This function informs GDK that the geometry of an embedded
8841 * offscreen window has changed. This is necessary for GDK to keep
8842 * track of which offscreen window the pointer is in.
8847 gdk_window_geometry_changed (GdkWindow *window)
8849 _gdk_synthesize_crossing_events_for_geometry_change (window);
8853 source_events_device_added (GdkDeviceManager *device_manager,
8858 GdkEventMask event_mask;
8859 GdkInputSource source;
8861 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_FLOATING)
8865 source = gdk_device_get_source (device);
8867 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
8868 GINT_TO_POINTER (source)));
8870 gdk_window_set_device_events (window, device, event_mask);
8874 source_events_device_changed (GdkDeviceManager *device_manager,
8879 GdkInputSource source;
8880 GdkEventMask event_mask;
8884 type = gdk_device_get_device_type (device);
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)));
8893 if (type == GDK_DEVICE_TYPE_FLOATING)
8895 /* The device was just floated, enable its event mask */
8896 gdk_window_set_device_events (window, device, event_mask);
8898 else if (type == GDK_DEVICE_TYPE_SLAVE)
8899 gdk_window_set_device_events (window, device, 0);
8903 * gdk_window_set_source_events:
8904 * @window: a #GdkWindow
8905 * @source: a #GdkInputSource to define the source class.
8906 * @event_mask: event mask for @window
8908 * Sets the event mask for any floating device (i.e. not attached to any
8909 * visible pointer) that has the source defined as @source. This event
8910 * mask will be applied both to currently existing, newly added devices
8911 * after this call, and devices being attached/detached.
8916 gdk_window_set_source_events (GdkWindow *window,
8917 GdkInputSource source,
8918 GdkEventMask event_mask)
8920 GdkDeviceManager *device_manager;
8921 GdkDisplay *display;
8925 g_return_if_fail (GDK_IS_WINDOW (window));
8927 display = gdk_window_get_display (window);
8928 device_manager = gdk_display_get_device_manager (display);
8930 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
8932 /* Set event mask for existing devices */
8933 for (d = devices; d; d = d->next)
8935 GdkDevice *device = d->data;
8937 if (source == gdk_device_get_source (device))
8938 gdk_window_set_device_events (window, device, event_mask);
8941 /* Update accounting */
8942 if (G_UNLIKELY (!window->source_event_masks))
8943 window->source_event_masks = g_hash_table_new (NULL, NULL);
8946 g_hash_table_insert (window->source_event_masks,
8947 GUINT_TO_POINTER (source),
8948 GUINT_TO_POINTER (event_mask));
8950 g_hash_table_remove (window->source_event_masks,
8951 GUINT_TO_POINTER (source));
8953 size = g_hash_table_size (window->source_event_masks);
8955 /* Update handler if needed */
8956 if (!window->device_added_handler_id && size > 0)
8958 window->device_added_handler_id =
8959 g_signal_connect (device_manager, "device-added",
8960 G_CALLBACK (source_events_device_added), window);
8961 window->device_changed_handler_id =
8962 g_signal_connect (device_manager, "device-changed",
8963 G_CALLBACK (source_events_device_changed), window);
8965 else if (window->device_added_handler_id && size == 0)
8966 g_signal_handler_disconnect (device_manager, window->device_added_handler_id);
8970 * gdk_window_get_source_events:
8971 * @window: a #GdkWindow
8972 * @source: a #GdkInputSource to define the source class.
8974 * Returns the event mask for @window corresponding to the device class specified
8977 * Returns: source event mask for @window
8980 gdk_window_get_source_events (GdkWindow *window,
8981 GdkInputSource source)
8983 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8985 return GPOINTER_TO_UINT (g_hash_table_lookup (window->source_event_masks,
8986 GUINT_TO_POINTER (source)));
8990 do_synthesize_crossing_event (gpointer data)
8992 GdkDisplay *display;
8993 GdkWindow *changed_toplevel;
8994 GHashTableIter iter;
8995 gpointer key, value;
8998 changed_toplevel = data;
9000 changed_toplevel->synthesize_crossing_event_queued = FALSE;
9002 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9005 display = gdk_window_get_display (changed_toplevel);
9006 serial = _gdk_display_get_next_serial (display);
9007 g_hash_table_iter_init (&iter, display->pointers_info);
9009 while (g_hash_table_iter_next (&iter, &key, &value))
9011 GdkWindow *new_window_under_pointer;
9012 GdkPointerWindowInfo *pointer_info = value;
9013 GdkDevice *device = key;
9015 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9017 new_window_under_pointer =
9018 get_pointer_window (display, changed_toplevel,
9020 pointer_info->toplevel_x,
9021 pointer_info->toplevel_y,
9023 if (new_window_under_pointer != pointer_info->window_under_pointer)
9025 _gdk_synthesize_crossing_events (display,
9026 pointer_info->window_under_pointer,
9027 new_window_under_pointer,
9029 GDK_CROSSING_NORMAL,
9030 pointer_info->toplevel_x,
9031 pointer_info->toplevel_y,
9032 pointer_info->state,
9037 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9046 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9048 GdkWindow *toplevel;
9050 if (_gdk_native_windows)
9051 return; /* We use the native crossing events if all native */
9053 toplevel = get_event_toplevel (changed_window);
9055 if (!toplevel->synthesize_crossing_event_queued)
9057 toplevel->synthesize_crossing_event_queued = TRUE;
9059 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9060 do_synthesize_crossing_event,
9061 g_object_ref (toplevel),
9066 /* Don't use for crossing events */
9068 get_event_window (GdkDisplay *display,
9070 GdkWindow *pointer_window,
9072 GdkModifierType mask,
9077 GdkWindow *grab_window;
9078 GdkDeviceGrabInfo *grab;
9080 grab = _gdk_display_has_device_grab (display, device, serial);
9082 if (grab != NULL && !grab->owner_events)
9084 evmask = grab->event_mask;
9085 evmask = update_evmask_for_button_motion (evmask, mask);
9087 grab_window = grab->window;
9089 if (evmask & type_masks[type])
9092 *evmask_out = evmask;
9099 while (pointer_window != NULL)
9101 evmask = pointer_window->event_mask;
9102 evmask = update_evmask_for_button_motion (evmask, mask);
9104 if (evmask & type_masks[type])
9107 *evmask_out = evmask;
9108 return pointer_window;
9111 pointer_window = get_event_parent (pointer_window);
9117 evmask = grab->event_mask;
9118 evmask = update_evmask_for_button_motion (evmask, mask);
9120 if (evmask & type_masks[type])
9123 *evmask_out = evmask;
9124 return grab->window;
9134 proxy_pointer_event (GdkDisplay *display,
9135 GdkEvent *source_event,
9138 GdkWindow *toplevel_window, *event_window;
9139 GdkWindow *pointer_window;
9140 GdkPointerWindowInfo *pointer_info;
9141 GdkDevice *device, *source_device;
9144 gdouble toplevel_x, toplevel_y;
9146 gboolean non_linear;
9148 event_window = source_event->any.window;
9149 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9150 gdk_event_get_state (source_event, &state);
9151 time_ = gdk_event_get_time (source_event);
9152 device = gdk_event_get_device (source_event);
9153 source_device = gdk_event_get_source_device (source_event);
9154 pointer_info = _gdk_display_get_pointer_info (display, device);
9155 toplevel_window = convert_native_coords_to_toplevel (event_window,
9156 toplevel_x, toplevel_y,
9157 &toplevel_x, &toplevel_y);
9160 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9161 source_event->type == GDK_ENTER_NOTIFY) &&
9162 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9163 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9166 /* If we get crossing events with subwindow unexpectedly being NULL
9167 that means there is a native subwindow that gdk doesn't know about.
9168 We track these and forward them, with the correct virtual window
9170 This is important to get right, as metacity uses gdk for the frame
9171 windows, but gdk doesn't know about the client windows reparented
9173 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9174 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9175 (source_event->type == GDK_ENTER_NOTIFY &&
9176 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9177 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9178 source_event->crossing.subwindow == NULL)
9180 /* Left for an unknown (to gdk) subwindow */
9182 /* Send leave events from window under pointer to event window
9183 that will get the subwindow == NULL window */
9184 _gdk_synthesize_crossing_events (display,
9185 pointer_info->window_under_pointer,
9187 device, source_device,
9188 source_event->crossing.mode,
9189 toplevel_x, toplevel_y,
9195 /* Send subwindow == NULL event */
9196 send_crossing_event (display,
9200 source_event->crossing.mode,
9201 source_event->crossing.detail,
9203 device, source_device,
9204 toplevel_x, toplevel_y,
9209 _gdk_display_set_window_under_pointer (display, device, NULL);
9213 pointer_window = get_pointer_window (display, toplevel_window, device,
9214 toplevel_x, toplevel_y, serial);
9216 if (((source_event->type == GDK_ENTER_NOTIFY &&
9217 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9218 (source_event->type == GDK_LEAVE_NOTIFY &&
9219 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9220 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9221 source_event->crossing.subwindow == NULL)
9223 /* Entered from an unknown (to gdk) subwindow */
9225 /* Send subwindow == NULL event */
9226 send_crossing_event (display,
9230 source_event->crossing.mode,
9231 source_event->crossing.detail,
9233 device, source_device,
9234 toplevel_x, toplevel_y,
9239 /* Send enter events from event window to pointer_window */
9240 _gdk_synthesize_crossing_events (display,
9243 device, source_device,
9244 source_event->crossing.mode,
9245 toplevel_x, toplevel_y,
9248 serial, non_linear);
9249 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9253 if (pointer_info->window_under_pointer != pointer_window)
9255 /* Either a toplevel crossing notify that ended up inside a child window,
9256 or a motion notify that got into another child window */
9258 /* Different than last time, send crossing events */
9259 _gdk_synthesize_crossing_events (display,
9260 pointer_info->window_under_pointer,
9262 device, source_device,
9263 GDK_CROSSING_NORMAL,
9264 toplevel_x, toplevel_y,
9267 serial, non_linear);
9268 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9270 else if (source_event->type == GDK_MOTION_NOTIFY)
9272 GdkWindow *event_win;
9276 event_win = get_event_window (display,
9285 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9286 gdk_window_get_device_events (event_win, device) == 0)
9292 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9294 gulong *device_serial;
9296 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9298 if (!device_serial ||
9299 (*device_serial != 0 &&
9300 serial < *device_serial))
9301 event_win = NULL; /* Ignore event */
9305 *device_serial = G_MAXULONG;
9309 if (event_win && !display->ignore_core_events)
9311 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9312 event->motion.time = time_;
9313 convert_toplevel_coords_to_window (event_win,
9314 toplevel_x, toplevel_y,
9315 &event->motion.x, &event->motion.y);
9316 event->motion.x_root = source_event->motion.x_root;
9317 event->motion.y_root = source_event->motion.y_root;
9318 event->motion.state = state;
9319 event->motion.is_hint = is_hint;
9320 event->motion.device = source_event->motion.device;
9321 event->motion.axes = g_memdup (source_event->motion.axes,
9322 sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
9323 gdk_event_set_source_device (event, source_device);
9327 /* unlink all move events from queue.
9328 We handle our own, including our emulated masks. */
9332 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9333 GDK_BUTTON2_MASK | \
9334 GDK_BUTTON3_MASK | \
9335 GDK_BUTTON4_MASK | \
9339 proxy_button_event (GdkEvent *source_event,
9342 GdkWindow *toplevel_window, *event_window;
9343 GdkWindow *event_win;
9344 GdkWindow *pointer_window;
9350 gdouble toplevel_x, toplevel_y;
9351 GdkDisplay *display;
9353 GdkDevice *device, *source_device;
9355 type = source_event->any.type;
9356 event_window = source_event->any.window;
9357 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9358 gdk_event_get_state (source_event, &state);
9359 time_ = gdk_event_get_time (source_event);
9360 device = gdk_event_get_device (source_event);
9361 source_device = gdk_event_get_source_device (source_event);
9362 display = gdk_window_get_display (source_event->any.window);
9363 toplevel_window = convert_native_coords_to_toplevel (event_window,
9364 toplevel_x, toplevel_y,
9365 &toplevel_x, &toplevel_y);
9367 if (type == GDK_BUTTON_PRESS &&
9368 !source_event->any.send_event &&
9369 _gdk_display_has_device_grab (display, device, serial) == NULL)
9372 _gdk_window_find_descendant_at (toplevel_window,
9373 toplevel_x, toplevel_y,
9376 /* Find the event window, that gets the grab */
9379 (parent = get_event_parent (w)) != NULL &&
9380 parent->window_type != GDK_WINDOW_ROOT)
9382 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9386 pointer_window = (GdkWindow *)w;
9388 _gdk_display_add_device_grab (display,
9394 gdk_window_get_events (pointer_window),
9398 _gdk_display_device_grab_update (display, device, source_device, serial);
9401 pointer_window = get_pointer_window (display, toplevel_window, device,
9402 toplevel_x, toplevel_y,
9405 event_win = get_event_window (display,
9411 if (event_win == NULL || display->ignore_core_events)
9414 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9415 gdk_window_get_device_events (event_win, device) == 0)
9418 event = _gdk_make_event (event_win, type, source_event, FALSE);
9422 case GDK_BUTTON_PRESS:
9423 case GDK_BUTTON_RELEASE:
9424 event->button.button = source_event->button.button;
9425 convert_toplevel_coords_to_window (event_win,
9426 toplevel_x, toplevel_y,
9427 &event->button.x, &event->button.y);
9428 event->button.x_root = source_event->button.x_root;
9429 event->button.y_root = source_event->button.y_root;
9430 event->button.state = state;
9431 event->button.device = source_event->button.device;
9432 event->button.axes = g_memdup (source_event->button.axes,
9433 sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
9435 gdk_event_set_source_device (event, source_device);
9437 if (type == GDK_BUTTON_PRESS)
9438 _gdk_event_button_generate (display, event);
9442 event->scroll.direction = source_event->scroll.direction;
9443 convert_toplevel_coords_to_window (event_win,
9444 toplevel_x, toplevel_y,
9445 &event->scroll.x, &event->scroll.y);
9446 event->scroll.x_root = source_event->scroll.x_root;
9447 event->scroll.y_root = source_event->scroll.y_root;
9448 event->scroll.state = state;
9449 event->scroll.device = source_event->scroll.device;
9450 gdk_event_set_source_device (event, source_device);
9457 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9460 #ifdef DEBUG_WINDOW_PRINTING
9462 gdk_window_print (GdkWindow *window,
9466 const char *window_types[] = {
9476 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9477 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9478 window->x, window->y,
9479 window->width, window->height
9482 if (gdk_window_has_impl (window))
9484 #ifdef GDK_WINDOWING_X11
9485 g_print (" impl(0x%lx)", gdk_x11_window_get_xid (window));
9489 if (window->window_type != GDK_WINDOW_CHILD)
9490 g_print (" %s", window_types[window->window_type]);
9492 if (window->input_only)
9493 g_print (" input-only");
9496 g_print (" shaped");
9498 if (!gdk_window_is_visible ((GdkWindow *)window))
9499 g_print (" hidden");
9501 g_print (" abs[%d,%d]",
9502 window->abs_x, window->abs_y);
9504 cairo_region_get_extents (window->clip_region, &r);
9505 if (cairo_region_is_empty (window->clip_region))
9506 g_print (" clipbox[empty]");
9508 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9515 gdk_window_print_tree (GdkWindow *window,
9517 gboolean include_input_only)
9521 if (window->input_only && !include_input_only)
9524 gdk_window_print (window, indent);
9526 for (l = window->children; l != NULL; l = l->next)
9527 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9530 #endif /* DEBUG_WINDOW_PRINTING */
9533 _gdk_windowing_got_event (GdkDisplay *display,
9538 GdkWindow *event_window;
9540 gboolean unlink_event;
9541 guint old_state, old_button;
9542 GdkDeviceGrabInfo *button_release_grab;
9543 GdkPointerWindowInfo *pointer_info;
9544 GdkDevice *device, *source_device;
9545 gboolean is_toplevel;
9547 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9548 display->last_event_time = gdk_event_get_time (event);
9550 device = gdk_event_get_device (event);
9551 source_device = gdk_event_get_source_device (event);
9557 g_object_get (device, "input-mode", &mode, NULL);
9558 _gdk_display_device_grab_update (display, device, source_device, serial);
9560 if (mode == GDK_MODE_DISABLED ||
9561 !_gdk_display_check_grab_ownership (display, device, serial))
9563 /* Device events are blocked by another
9564 * device grab, or the device is disabled
9566 unlink_event = TRUE;
9571 event_window = event->any.window;
9575 pointer_info = _gdk_display_get_pointer_info (display, device);
9577 #ifdef DEBUG_WINDOW_PRINTING
9578 if (event->type == GDK_KEY_PRESS &&
9579 (event->key.keyval == 0xa7 ||
9580 event->key.keyval == 0xbd))
9582 gdk_window_print_tree (event_window, 0,
9583 event->key.keyval == 0xbd);
9587 if (_gdk_native_windows)
9589 if (event->type == GDK_BUTTON_PRESS &&
9590 !event->any.send_event &&
9591 _gdk_display_has_device_grab (display, device, serial) == NULL)
9593 _gdk_display_add_device_grab (display,
9599 gdk_window_get_events (event_window),
9601 gdk_event_get_time (event),
9603 _gdk_display_device_grab_update (display, device, source_device, serial);
9605 if (event->type == GDK_BUTTON_RELEASE &&
9606 !event->any.send_event)
9608 button_release_grab =
9609 _gdk_display_has_device_grab (display, device, serial);
9610 if (button_release_grab &&
9611 button_release_grab->implicit &&
9612 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9614 button_release_grab->serial_end = serial;
9615 button_release_grab->implicit_ungrab = FALSE;
9616 _gdk_display_device_grab_update (display, device, source_device, serial);
9620 if (event->type == GDK_BUTTON_PRESS)
9621 _gdk_event_button_generate (display, event);
9626 if (event->type == GDK_VISIBILITY_NOTIFY)
9628 event_window->native_visibility = event->visibility.state;
9629 gdk_window_update_visibility_recursively (event_window,
9634 if (!(is_button_type (event->type) ||
9635 is_motion_type (event->type)) ||
9636 event_window->window_type == GDK_WINDOW_ROOT)
9639 is_toplevel = gdk_window_is_toplevel (event_window);
9641 if ((event->type == GDK_ENTER_NOTIFY ||
9642 event->type == GDK_LEAVE_NOTIFY) &&
9643 (event->crossing.mode == GDK_CROSSING_GRAB ||
9644 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9645 (_gdk_display_has_device_grab (display, device, serial) ||
9646 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9648 /* We synthesize all crossing events due to grabs ourselves,
9649 * so we ignore the native ones caused by our native pointer_grab
9650 * calls. Otherwise we would proxy these crossing event and cause
9651 * multiple copies of crossing events for grabs.
9653 * We do want to handle grabs from other clients though, as for
9654 * instance alt-tab in metacity causes grabs like these and
9655 * we want to handle those. Thus the has_pointer_grab check.
9657 * Implicit grabs on child windows create some grabbing events
9658 * that are sent before the button press. This means we can't
9659 * detect these with the has_pointer_grab check (as the implicit
9660 * grab is only noticed when we get button press event), so we
9661 * detect these events by checking for INFERIOR enter or leave
9662 * events. These should never be a problem to filter out.
9665 /* We ended up in this window after some (perhaps other clients)
9666 grab, so update the toplevel_under_window state */
9668 event->type == GDK_ENTER_NOTIFY &&
9669 event->crossing.mode == GDK_CROSSING_UNGRAB)
9671 if (pointer_info->toplevel_under_pointer)
9672 g_object_unref (pointer_info->toplevel_under_pointer);
9673 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9676 unlink_event = TRUE;
9680 /* Track toplevel_under_pointer */
9683 if (event->type == GDK_ENTER_NOTIFY &&
9684 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9686 if (pointer_info->toplevel_under_pointer)
9687 g_object_unref (pointer_info->toplevel_under_pointer);
9688 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9690 else if (event->type == GDK_LEAVE_NOTIFY &&
9691 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9692 pointer_info->toplevel_under_pointer == event_window)
9694 if (pointer_info->toplevel_under_pointer)
9695 g_object_unref (pointer_info->toplevel_under_pointer);
9696 pointer_info->toplevel_under_pointer = NULL;
9700 /* Store last pointer window and position/state */
9701 old_state = pointer_info->state;
9702 old_button = pointer_info->button;
9704 gdk_event_get_coords (event, &x, &y);
9705 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9706 pointer_info->toplevel_x = x;
9707 pointer_info->toplevel_y = y;
9708 gdk_event_get_state (event, &pointer_info->state);
9709 if (event->type == GDK_BUTTON_PRESS ||
9710 event->type == GDK_BUTTON_RELEASE)
9711 pointer_info->button = event->button.button;
9714 (pointer_info->state != old_state ||
9715 pointer_info->button != old_button))
9716 _gdk_display_enable_motion_hints (display, device);
9718 unlink_event = FALSE;
9719 if (is_motion_type (event->type))
9720 unlink_event = proxy_pointer_event (display,
9723 else if (is_button_type (event->type))
9724 unlink_event = proxy_button_event (event,
9727 if (event->type == GDK_BUTTON_RELEASE &&
9728 !event->any.send_event)
9730 button_release_grab =
9731 _gdk_display_has_device_grab (display, device, serial);
9732 if (button_release_grab &&
9733 button_release_grab->implicit &&
9734 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9736 button_release_grab->serial_end = serial;
9737 button_release_grab->implicit_ungrab = FALSE;
9738 _gdk_display_device_grab_update (display, device, source_device, serial);
9745 _gdk_event_queue_remove_link (display, event_link);
9746 g_list_free_1 (event_link);
9747 gdk_event_free (event);
9752 * gdk_window_create_similar_surface:
9753 * @window: window to make new surface similar to
9754 * @content: the content for the new surface
9755 * @width: width of the new surface
9756 * @height: height of the new surface
9758 * Create a new surface that is as compatible as possible with the
9759 * given @window. For example the new surface will have the same
9760 * fallback resolution and font options as @window. Generally, the new
9761 * surface will also use the same backend as @window, unless that is
9762 * not possible for some reason. The type of the returned surface may
9763 * be examined with cairo_surface_get_type().
9765 * Initially the surface contents are all 0 (transparent if contents
9766 * have transparency, black otherwise.)
9768 * Returns: a pointer to the newly allocated surface. The caller
9769 * owns the surface and should call cairo_surface_destroy() when done
9772 * This function always returns a valid pointer, but it will return a
9773 * pointer to a "nil" surface if @other is already in an error state
9774 * or any other error occurs.
9779 gdk_window_create_similar_surface (GdkWindow * window,
9780 cairo_content_t content,
9784 cairo_surface_t *window_surface, *surface;
9786 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9788 window_surface = _gdk_window_ref_cairo_surface (window);
9790 surface = cairo_surface_create_similar (window_surface,
9794 cairo_surface_destroy (window_surface);
9801 * @window: a #GdkWindow
9802 * @timestamp: timestamp of the event triggering the window focus
9804 * Sets keyboard focus to @window. In most cases, gtk_window_present()
9805 * should be used on a #GtkWindow, rather than calling this function.
9809 gdk_window_focus (GdkWindow *window,
9812 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->focus (window, timestamp);
9816 * gdk_window_set_type_hint:
9817 * @window: A toplevel #GdkWindow
9818 * @hint: A hint of the function this window will have
9820 * The application can use this call to provide a hint to the window
9821 * manager about the functionality of a window. The window manager
9822 * can use this information when determining the decoration and behaviour
9825 * The hint must be set before the window is mapped.
9828 gdk_window_set_type_hint (GdkWindow *window,
9829 GdkWindowTypeHint hint)
9831 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_type_hint (window, hint);
9835 * gdk_window_get_type_hint:
9836 * @window: A toplevel #GdkWindow
9838 * This function returns the type hint set for a window.
9840 * Return value: The type hint set for @window
9845 gdk_window_get_type_hint (GdkWindow *window)
9847 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_type_hint (window);
9851 * gdk_window_set_modal_hint:
9852 * @window: A toplevel #GdkWindow
9853 * @modal: %TRUE if the window is modal, %FALSE otherwise.
9855 * The application can use this hint to tell the window manager
9856 * that a certain window has modal behaviour. The window manager
9857 * can use this information to handle modal windows in a special
9860 * You should only use this on windows for which you have
9861 * previously called gdk_window_set_transient_for()
9864 gdk_window_set_modal_hint (GdkWindow *window,
9867 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_modal_hint (window, modal);
9871 * gdk_window_set_skip_taskbar_hint:
9872 * @window: a toplevel #GdkWindow
9873 * @skips_taskbar: %TRUE to skip the taskbar
9875 * Toggles whether a window should appear in a task list or window
9876 * list. If a window's semantic type as specified with
9877 * gdk_window_set_type_hint() already fully describes the window, this
9878 * function should <emphasis>not</emphasis> be called in addition,
9879 * instead you should allow the window to be treated according to
9880 * standard policy for its semantic type.
9885 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
9886 gboolean skips_taskbar)
9888 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_taskbar_hint (window, skips_taskbar);
9892 * gdk_window_set_skip_pager_hint:
9893 * @window: a toplevel #GdkWindow
9894 * @skips_pager: %TRUE to skip the pager
9896 * Toggles whether a window should appear in a pager (workspace
9897 * switcher, or other desktop utility program that displays a small
9898 * thumbnail representation of the windows on the desktop). If a
9899 * window's semantic type as specified with gdk_window_set_type_hint()
9900 * already fully describes the window, this function should
9901 * <emphasis>not</emphasis> be called in addition, instead you should
9902 * allow the window to be treated according to standard policy for
9903 * its semantic type.
9908 gdk_window_set_skip_pager_hint (GdkWindow *window,
9909 gboolean skips_pager)
9911 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_pager_hint (window, skips_pager);
9915 * gdk_window_set_urgency_hint:
9916 * @window: a toplevel #GdkWindow
9917 * @urgent: %TRUE if the window is urgent
9919 * Toggles whether a window needs the user's
9925 gdk_window_set_urgency_hint (GdkWindow *window,
9928 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_urgency_hint (window, urgent);
9932 * gdk_window_set_geometry_hints:
9933 * @window: a toplevel #GdkWindow
9934 * @geometry: geometry hints
9935 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
9937 * Sets the geometry hints for @window. Hints flagged in @geom_mask
9938 * are set, hints not flagged in @geom_mask are unset.
9939 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
9941 * This function provides hints to the windowing system about
9942 * acceptable sizes for a toplevel window. The purpose of
9943 * this is to constrain user resizing, but the windowing system
9944 * will typically (but is not required to) also constrain the
9945 * current size of the window to the provided values and
9946 * constrain programatic resizing via gdk_window_resize() or
9947 * gdk_window_move_resize().
9949 * Note that on X11, this effect has no effect on windows
9950 * of type %GDK_WINDOW_TEMP or windows where override redirect
9951 * has been turned on via gdk_window_set_override_redirect()
9952 * since these windows are not resizable by the user.
9954 * Since you can't count on the windowing system doing the
9955 * constraints for programmatic resizes, you should generally
9956 * call gdk_window_constrain_size() yourself to determine
9957 * appropriate sizes.
9961 gdk_window_set_geometry_hints (GdkWindow *window,
9962 const GdkGeometry *geometry,
9963 GdkWindowHints geom_mask)
9965 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_geometry_hints (window, geometry, geom_mask);
9969 * gdk_window_set_title:
9970 * @window: a toplevel #GdkWindow
9971 * @title: title of @window
9973 * Sets the title of a toplevel window, to be displayed in the titlebar.
9974 * If you haven't explicitly set the icon name for the window
9975 * (using gdk_window_set_icon_name()), the icon name will be set to
9976 * @title as well. @title must be in UTF-8 encoding (as with all
9977 * user-readable strings in GDK/GTK+). @title may not be %NULL.
9980 gdk_window_set_title (GdkWindow *window,
9983 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_title (window, title);
9987 * gdk_window_set_role:
9988 * @window: a toplevel #GdkWindow
9989 * @role: a string indicating its role
9991 * When using GTK+, typically you should use gtk_window_set_role() instead
9992 * of this low-level function.
9994 * The window manager and session manager use a window's role to
9995 * distinguish it from other kinds of window in the same application.
9996 * When an application is restarted after being saved in a previous
9997 * session, all windows with the same title and role are treated as
9998 * interchangeable. So if you have two windows with the same title
9999 * that should be distinguished for session management purposes, you
10000 * should set the role on those windows. It doesn't matter what string
10001 * you use for the role, as long as you have a different role for each
10002 * non-interchangeable kind of window.
10006 gdk_window_set_role (GdkWindow *window,
10009 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_role (window, role);
10013 * gdk_window_set_startup_id:
10014 * @window: a toplevel #GdkWindow
10015 * @startup_id: a string with startup-notification identifier
10017 * When using GTK+, typically you should use gtk_window_set_startup_id()
10018 * instead of this low-level function.
10024 gdk_window_set_startup_id (GdkWindow *window,
10025 const gchar *startup_id)
10027 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_startup_id (window, startup_id);
10031 * gdk_window_set_transient_for:
10032 * @window: a toplevel #GdkWindow
10033 * @parent: another toplevel #GdkWindow
10035 * Indicates to the window manager that @window is a transient dialog
10036 * associated with the application window @parent. This allows the
10037 * window manager to do things like center @window on @parent and
10038 * keep @window above @parent.
10040 * See gtk_window_set_transient_for() if you're using #GtkWindow or
10044 gdk_window_set_transient_for (GdkWindow *window,
10047 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_transient_for (window, parent);
10051 * gdk_window_get_root_origin:
10052 * @window: a toplevel #GdkWindow
10053 * @x: (out): return location for X position of window frame
10054 * @y: (out): return location for Y position of window frame
10056 * Obtains the top-left corner of the window manager frame in root
10057 * window coordinates.
10061 gdk_window_get_root_origin (GdkWindow *window,
10065 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_root_origin (window, x, y);
10069 * gdk_window_get_frame_extents:
10070 * @window: a toplevel #GdkWindow
10071 * @rect: rectangle to fill with bounding box of the window frame
10073 * Obtains the bounding box of the window, including window manager
10074 * titlebar/borders if any. The frame position is given in root window
10075 * coordinates. To get the position of the window itself (rather than
10076 * the frame) in root window coordinates, use gdk_window_get_origin().
10080 gdk_window_get_frame_extents (GdkWindow *window,
10081 GdkRectangle *rect)
10083 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_frame_extents (window, rect);
10087 * gdk_window_set_override_redirect:
10088 * @window: a toplevel #GdkWindow
10089 * @override_redirect: %TRUE if window should be override redirect
10091 * An override redirect window is not under the control of the window manager.
10092 * This means it won't have a titlebar, won't be minimizable, etc. - it will
10093 * be entirely under the control of the application. The window manager
10094 * can't see the override redirect window at all.
10096 * Override redirect should only be used for short-lived temporary
10097 * windows, such as popup menus. #GtkMenu uses an override redirect
10098 * window in its implementation, for example.
10102 gdk_window_set_override_redirect (GdkWindow *window,
10103 gboolean override_redirect)
10105 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_override_redirect (window, override_redirect);
10109 * gdk_window_set_accept_focus:
10110 * @window: a toplevel #GdkWindow
10111 * @accept_focus: %TRUE if the window should receive input focus
10113 * Setting @accept_focus to %FALSE hints the desktop environment that the
10114 * window doesn't want to receive input focus.
10116 * On X, it is the responsibility of the window manager to interpret this
10117 * hint. ICCCM-compliant window manager usually respect it.
10122 gdk_window_set_accept_focus (GdkWindow *window,
10123 gboolean accept_focus)
10125 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_accept_focus (window, accept_focus);
10129 * gdk_window_set_focus_on_map:
10130 * @window: a toplevel #GdkWindow
10131 * @focus_on_map: %TRUE if the window should receive input focus when mapped
10133 * Setting @focus_on_map to %FALSE hints the desktop environment that the
10134 * window doesn't want to receive input focus when it is mapped.
10135 * focus_on_map should be turned off for windows that aren't triggered
10136 * interactively (such as popups from network activity).
10138 * On X, it is the responsibility of the window manager to interpret
10139 * this hint. Window managers following the freedesktop.org window
10140 * manager extension specification should respect it.
10145 gdk_window_set_focus_on_map (GdkWindow *window,
10146 gboolean focus_on_map)
10148 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_focus_on_map (window, focus_on_map);
10152 * gdk_window_set_icon_list:
10153 * @window: The #GdkWindow toplevel window to set the icon of.
10154 * @pixbufs: (transfer none) (element-type GdkPixbuf):
10155 * A list of pixbufs, of different sizes.
10157 * Sets a list of icons for the window. One of these will be used
10158 * to represent the window when it has been iconified. The icon is
10159 * usually shown in an icon box or some sort of task bar. Which icon
10160 * size is shown depends on the window manager. The window manager
10161 * can scale the icon but setting several size icons can give better
10162 * image quality since the window manager may only need to scale the
10163 * icon by a small amount or not at all.
10167 gdk_window_set_icon_list (GdkWindow *window,
10170 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_list (window, pixbufs);
10174 * gdk_window_set_icon_name:
10175 * @window: a toplevel #GdkWindow
10176 * @name: name of window while iconified (minimized)
10178 * Windows may have a name used while minimized, distinct from the
10179 * name they display in their titlebar. Most of the time this is a bad
10180 * idea from a user interface standpoint. But you can set such a name
10181 * with this function, if you like.
10183 * After calling this with a non-%NULL @name, calls to gdk_window_set_title()
10184 * will not update the icon title.
10186 * Using %NULL for @name unsets the icon title; further calls to
10187 * gdk_window_set_title() will again update the icon title as well.
10190 gdk_window_set_icon_name (GdkWindow *window,
10193 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_name (window, name);
10197 * gdk_window_iconify:
10198 * @window: a toplevel #GdkWindow
10200 * Asks to iconify (minimize) @window. The window manager may choose
10201 * to ignore the request, but normally will honor it. Using
10202 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
10204 * This function only makes sense when @window is a toplevel window.
10208 gdk_window_iconify (GdkWindow *window)
10210 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->iconify (window);
10214 * gdk_window_deiconify:
10215 * @window: a toplevel #GdkWindow
10217 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
10218 * choose to ignore the request to deiconify. When using GTK+,
10219 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
10220 * you probably want to use gtk_window_present(), which raises the window, focuses it,
10221 * unminimizes it, and puts it on the current desktop.
10225 gdk_window_deiconify (GdkWindow *window)
10227 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->deiconify (window);
10231 * gdk_window_stick:
10232 * @window: a toplevel #GdkWindow
10234 * "Pins" a window such that it's on all workspaces and does not scroll
10235 * with viewports, for window managers that have scrollable viewports.
10236 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
10238 * On the X11 platform, this function depends on window manager
10239 * support, so may have no effect with many window managers. However,
10240 * GDK will do the best it can to convince the window manager to stick
10241 * the window. For window managers that don't support this operation,
10242 * there's nothing you can do to force it to happen.
10246 gdk_window_stick (GdkWindow *window)
10248 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->stick (window);
10252 * gdk_window_unstick:
10253 * @window: a toplevel #GdkWindow
10255 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
10256 * and gtk_window_unstick().
10260 gdk_window_unstick (GdkWindow *window)
10262 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unstick (window);
10266 * gdk_window_maximize:
10267 * @window: a toplevel #GdkWindow
10269 * Maximizes the window. If the window was already maximized, then
10270 * this function does nothing.
10272 * On X11, asks the window manager to maximize @window, if the window
10273 * manager supports this operation. Not all window managers support
10274 * this, and some deliberately ignore it or don't have a concept of
10275 * "maximized"; so you can't rely on the maximization actually
10276 * happening. But it will happen with most standard window managers,
10277 * and GDK makes a best effort to get it to happen.
10279 * On Windows, reliably maximizes the window.
10283 gdk_window_maximize (GdkWindow *window)
10285 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->maximize (window);
10289 * gdk_window_unmaximize:
10290 * @window: a toplevel #GdkWindow
10292 * Unmaximizes the window. If the window wasn't maximized, then this
10293 * function does nothing.
10295 * On X11, asks the window manager to unmaximize @window, if the
10296 * window manager supports this operation. Not all window managers
10297 * support this, and some deliberately ignore it or don't have a
10298 * concept of "maximized"; so you can't rely on the unmaximization
10299 * actually happening. But it will happen with most standard window
10300 * managers, and GDK makes a best effort to get it to happen.
10302 * On Windows, reliably unmaximizes the window.
10306 gdk_window_unmaximize (GdkWindow *window)
10308 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unmaximize (window);
10312 * gdk_window_fullscreen:
10313 * @window: a toplevel #GdkWindow
10315 * Moves the window into fullscreen mode. This means the
10316 * window covers the entire screen and is above any panels
10319 * If the window was already fullscreen, then this function does nothing.
10321 * On X11, asks the window manager to put @window in a fullscreen
10322 * state, if the window manager supports this operation. Not all
10323 * window managers support this, and some deliberately ignore it or
10324 * don't have a concept of "fullscreen"; so you can't rely on the
10325 * fullscreenification actually happening. But it will happen with
10326 * most standard window managers, and GDK makes a best effort to get
10332 gdk_window_fullscreen (GdkWindow *window)
10334 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->fullscreen (window);
10338 * gdk_window_unfullscreen:
10339 * @window: a toplevel #GdkWindow
10341 * Moves the window out of fullscreen mode. If the window was not
10342 * fullscreen, does nothing.
10344 * On X11, asks the window manager to move @window out of the fullscreen
10345 * state, if the window manager supports this operation. Not all
10346 * window managers support this, and some deliberately ignore it or
10347 * don't have a concept of "fullscreen"; so you can't rely on the
10348 * unfullscreenification actually happening. But it will happen with
10349 * most standard window managers, and GDK makes a best effort to get
10355 gdk_window_unfullscreen (GdkWindow *window)
10357 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unfullscreen (window);
10361 * gdk_window_set_keep_above:
10362 * @window: a toplevel #GdkWindow
10363 * @setting: whether to keep @window above other windows
10365 * Set if @window must be kept above other windows. If the
10366 * window was already above, then this function does nothing.
10368 * On X11, asks the window manager to keep @window above, if the window
10369 * manager supports this operation. Not all window managers support
10370 * this, and some deliberately ignore it or don't have a concept of
10371 * "keep above"; so you can't rely on the window being kept above.
10372 * But it will happen with most standard window managers,
10373 * and GDK makes a best effort to get it to happen.
10378 gdk_window_set_keep_above (GdkWindow *window,
10381 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_above (window, setting);
10385 * gdk_window_set_keep_below:
10386 * @window: a toplevel #GdkWindow
10387 * @setting: whether to keep @window below other windows
10389 * Set if @window must be kept below other windows. If the
10390 * window was already below, then this function does nothing.
10392 * On X11, asks the window manager to keep @window below, if the window
10393 * manager supports this operation. Not all window managers support
10394 * this, and some deliberately ignore it or don't have a concept of
10395 * "keep below"; so you can't rely on the window being kept below.
10396 * But it will happen with most standard window managers,
10397 * and GDK makes a best effort to get it to happen.
10402 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
10404 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_below (window, setting);
10408 * gdk_window_get_group:
10409 * @window: a toplevel #GdkWindow
10411 * Returns the group leader window for @window. See gdk_window_set_group().
10413 * Return value: (transfer none): the group leader window for @window
10418 gdk_window_get_group (GdkWindow *window)
10420 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_group (window);
10424 * gdk_window_set_group:
10425 * @window: a toplevel #GdkWindow
10426 * @leader: group leader window, or %NULL to restore the default group leader window
10428 * Sets the group leader window for @window. By default,
10429 * GDK sets the group leader for all toplevel windows
10430 * to a global window implicitly created by GDK. With this function
10431 * you can override this default.
10433 * The group leader window allows the window manager to distinguish
10434 * all windows that belong to a single application. It may for example
10435 * allow users to minimize/unminimize all windows belonging to an
10436 * application at once. You should only set a non-default group window
10437 * if your application pretends to be multiple applications.
10440 gdk_window_set_group (GdkWindow *window,
10443 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_group (window, leader);
10447 * gdk_window_set_decorations:
10448 * @window: a toplevel #GdkWindow
10449 * @decorations: decoration hint mask
10451 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
10452 * This function sets the traditional Motif window manager hints that tell the
10453 * window manager which decorations you would like your window to have.
10454 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
10455 * using the GDK function directly.
10457 * The @decorations argument is the logical OR of the fields in
10458 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
10459 * mask, the other bits indicate which decorations should be turned off.
10460 * If #GDK_DECOR_ALL is not included, then the other bits indicate
10461 * which decorations should be turned on.
10463 * Most window managers honor a decorations hint of 0 to disable all decorations,
10464 * but very few honor all possible combinations of bits.
10468 gdk_window_set_decorations (GdkWindow *window,
10469 GdkWMDecoration decorations)
10471 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_decorations (window, decorations);
10475 * gdk_window_get_decorations:
10476 * @window: The toplevel #GdkWindow to get the decorations from
10477 * @decorations: (out): The window decorations will be written here
10479 * Returns the decorations set on the GdkWindow with
10480 * gdk_window_set_decorations().
10482 * Returns: %TRUE if the window has decorations set, %FALSE otherwise.
10485 gdk_window_get_decorations(GdkWindow *window,
10486 GdkWMDecoration *decorations)
10488 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_decorations (window, decorations);
10492 * gdk_window_set_functions:
10493 * @window: a toplevel #GdkWindow
10494 * @functions: bitmask of operations to allow on @window
10496 * Sets hints about the window management functions to make available
10497 * via buttons on the window frame.
10499 * On the X backend, this function sets the traditional Motif window
10500 * manager hint for this purpose. However, few window managers do
10501 * anything reliable or interesting with this hint. Many ignore it
10504 * The @functions argument is the logical OR of values from the
10505 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
10506 * then the other bits indicate which functions to disable; if
10507 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
10512 gdk_window_set_functions (GdkWindow *window,
10513 GdkWMFunction functions)
10515 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_functions (window, functions);
10519 * gdk_window_begin_resize_drag:
10520 * @window: a toplevel #GdkWindow
10521 * @edge: the edge or corner from which the drag is started
10522 * @button: the button being used to drag
10523 * @root_x: root window X coordinate of mouse click that began the drag
10524 * @root_y: root window Y coordinate of mouse click that began the drag
10525 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
10527 * Begins a window resize operation (for a toplevel window).
10528 * You might use this function to implement a "window resize grip," for
10529 * example; in fact #GtkStatusbar uses it. The function works best
10530 * with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a
10531 * fallback implementation for other window managers.
10535 gdk_window_begin_resize_drag (GdkWindow *window,
10536 GdkWindowEdge edge,
10542 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_resize_drag (window, edge, button, root_x, root_y, timestamp);
10546 * gdk_window_begin_move_drag:
10547 * @window: a toplevel #GdkWindow
10548 * @button: the button being used to drag
10549 * @root_x: root window X coordinate of mouse click that began the drag
10550 * @root_y: root window Y coordinate of mouse click that began the drag
10551 * @timestamp: timestamp of mouse click that began the drag
10553 * Begins a window move operation (for a toplevel window). You might
10554 * use this function to implement a "window move grip," for
10555 * example. The function works best with window managers that support
10556 * the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
10557 * Window Manager Hints</ulink>, but has a fallback implementation for
10558 * other window managers.
10562 gdk_window_begin_move_drag (GdkWindow *window,
10568 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_move_drag (window, button, root_x, root_y, timestamp);
10572 * gdk_window_enable_synchronized_configure:
10573 * @window: a toplevel #GdkWindow
10575 * Indicates that the application will cooperate with the window
10576 * system in synchronizing the window repaint with the window
10577 * manager during resizing operations. After an application calls
10578 * this function, it must call gdk_window_configure_finished() every
10579 * time it has finished all processing associated with a set of
10580 * Configure events. Toplevel GTK+ windows automatically use this
10583 * On X, calling this function makes @window participate in the
10584 * _NET_WM_SYNC_REQUEST window manager protocol.
10589 gdk_window_enable_synchronized_configure (GdkWindow *window)
10591 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->enable_synchronized_configure (window);
10595 * gdk_window_configure_finished:
10596 * @window: a toplevel #GdkWindow
10598 * Signal to the window system that the application has finished
10599 * handling Configure events it has received. Window Managers can
10600 * use this to better synchronize the frame repaint with the
10601 * application. GTK+ applications will automatically call this
10602 * function when appropriate.
10604 * This function can only be called if gdk_window_enable_synchronized_configure()
10605 * was called previously.
10610 gdk_window_configure_finished (GdkWindow *window)
10612 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->configure_finished (window);
10616 * gdk_window_set_opacity:
10617 * @window: a top-level #GdkWindow
10618 * @opacity: opacity
10620 * Request the windowing system to make @window partially transparent,
10621 * with opacity 0 being fully transparent and 1 fully opaque. (Values
10622 * of the opacity parameter are clamped to the [0,1] range.)
10624 * On X11, this works only on X screens with a compositing manager
10627 * For setting up per-pixel alpha, see gdk_screen_get_rgba_visual().
10628 * For making non-toplevel windows translucent, see
10629 * gdk_window_set_composited().
10634 gdk_window_set_opacity (GdkWindow *window,
10637 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_opacity (window, opacity);
10640 /* This function is called when the XWindow is really gone.
10643 gdk_window_destroy_notify (GdkWindow *window)
10645 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->destroy_notify (window);
10649 * gdk_window_register_dnd:
10650 * @window: a #GdkWindow.
10652 * Registers a window as a potential drop destination.
10655 gdk_window_register_dnd (GdkWindow *window)
10657 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->register_dnd (window);
10661 * gdk_window_get_drag_protocol:
10662 * @window: the destination window
10663 * @target: (out) (allow-none) (transfer full): location of the window
10664 * where the drop should happen. This may be @window or a proxy window,
10665 * or %NULL if @window does not support Drag and Drop.
10667 * Finds out the DND protocol supported by a window.
10669 * Returns: the supported DND protocol.
10674 gdk_window_get_drag_protocol (GdkWindow *window,
10675 GdkWindow **target)
10677 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_DRAG_PROTO_NONE);
10679 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_drag_protocol (window, target);
10684 * @window: the source window for this drag.
10685 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
10686 * as list of #GdkAtoms
10688 * Starts a drag and creates a new drag context for it.
10689 * This function assumes that the drag is controlled by the
10690 * client pointer device, use gdk_drag_begin_for_device() to
10691 * begin a drag with a different device.
10693 * This function is called by the drag source.
10695 * Return value: (transfer full): a newly created #GdkDragContext
10698 gdk_drag_begin (GdkWindow *window,
10701 GdkDeviceManager *device_manager;
10704 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
10705 device = gdk_device_manager_get_client_pointer (device_manager);
10707 return gdk_drag_begin_for_device (window, device, targets);
10711 * gdk_drag_begin_for_device:
10712 * @window: the source window for this drag
10713 * @device: the device that controls this drag
10714 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
10715 * as list of #GdkAtoms
10717 * Starts a drag and creates a new drag context for it.
10719 * This function is called by the drag source.
10721 * Return value: (transfer full): a newly created #GdkDragContext
10724 gdk_drag_begin_for_device (GdkWindow *window,
10728 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, targets);
10732 * gdk_test_render_sync:
10733 * @window: a mapped #GdkWindow
10735 * Retrieves a pixel from @window to force the windowing
10736 * system to carry out any pending rendering commands.
10738 * This function is intended to be used to synchronize with rendering
10739 * pipelines, to benchmark windowing system rendering operations.
10744 gdk_test_render_sync (GdkWindow *window)
10746 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->sync_rendering (window);
10750 * gdk_test_simulate_key:
10751 * @window: a #GdkWindow to simulate a key event for
10752 * @x: x coordinate within @window for the key event
10753 * @y: y coordinate within @window for the key event
10754 * @keyval: A GDK keyboard value
10755 * @modifiers: Keyboard modifiers the event is setup with
10756 * @key_pressrelease: either %GDK_KEY_PRESS or %GDK_KEY_RELEASE
10758 * This function is intended to be used in GTK+ test programs.
10759 * If (@x,@y) are > (-1,-1), it will warp the mouse pointer to
10760 * the given (@x,@y) coordinates within @window and simulate a
10761 * key press or release event.
10763 * When the mouse pointer is warped to the target location, use
10764 * of this function outside of test programs that run in their
10765 * own virtual windowing system (e.g. Xvfb) is not recommended.
10766 * If (@x,@y) are passed as (-1,-1), the mouse pointer will not
10767 * be warped and @window origin will be used as mouse pointer
10768 * location for the event.
10770 * Also, gdk_test_simulate_key() is a fairly low level function,
10771 * for most testing purposes, gtk_test_widget_send_key() is the
10772 * right function to call which will generate a key press event
10773 * followed by its accompanying key release event.
10775 * Returns: whether all actions necessary for a key event simulation
10776 * were carried out successfully
10781 gdk_test_simulate_key (GdkWindow *window,
10785 GdkModifierType modifiers,
10786 GdkEventType key_pressrelease)
10788 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10789 ->simulate_key (window, x, y, keyval, modifiers, key_pressrelease);
10793 * gdk_test_simulate_button:
10794 * @window: a #GdkWindow to simulate a button event for
10795 * @x: x coordinate within @window for the button event
10796 * @y: y coordinate within @window for the button event
10797 * @button: Number of the pointer button for the event, usually 1, 2 or 3
10798 * @modifiers: Keyboard modifiers the event is setup with
10799 * @button_pressrelease: either %GDK_BUTTON_PRESS or %GDK_BUTTON_RELEASE
10801 * This function is intended to be used in GTK+ test programs.
10802 * It will warp the mouse pointer to the given (@x,@y) coordinates
10803 * within @window and simulate a button press or release event.
10804 * Because the mouse pointer needs to be warped to the target
10805 * location, use of this function outside of test programs that
10806 * run in their own virtual windowing system (e.g. Xvfb) is not
10809 * Also, gdk_test_simulate_button() is a fairly low level function,
10810 * for most testing purposes, gtk_test_widget_click() is the right
10811 * function to call which will generate a button press event followed
10812 * by its accompanying button release event.
10814 * Returns: whether all actions necessary for a button event simulation
10815 * were carried out successfully
10820 gdk_test_simulate_button (GdkWindow *window,
10823 guint button, /*1..3*/
10824 GdkModifierType modifiers,
10825 GdkEventType button_pressrelease)
10827 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10828 ->simulate_button (window, x, y, button, modifiers, button_pressrelease);
10832 * gdk_property_get:
10833 * @window: a #GdkWindow
10834 * @property: the property to retrieve
10835 * @type: the desired property type, or %GDK_NONE, if any type of data
10836 * is acceptable. If this does not match the actual
10837 * type, then @actual_format and @actual_length will
10838 * be filled in, a warning will be printed to stderr
10839 * and no data will be returned.
10840 * @offset: the offset into the property at which to begin
10841 * retrieving data, in 4 byte units.
10842 * @length: the length of the data to retrieve in bytes. Data is
10843 * considered to be retrieved in 4 byte chunks, so @length
10844 * will be rounded up to the next highest 4 byte boundary
10845 * (so be careful not to pass a value that might overflow
10846 * when rounded up).
10847 * @pdelete: if %TRUE, delete the property after retrieving the
10849 * @actual_property_type: (out) (transfer none): location to store the
10850 * actual type of the property.
10851 * @actual_format: (out): location to store the actual return format of the
10852 * data; either 8, 16 or 32 bits.
10853 * @actual_length: location to store the length of the retrieved data, in
10854 * bytes. Data returned in the 32 bit format is stored
10855 * in a long variable, so the actual number of 32 bit
10856 * elements should be be calculated via
10857 * @actual_length / sizeof(glong) to ensure portability to
10859 * @data: (out) (array length=actual_length) (transfer full): location
10860 * to store a pointer to the data. The retrieved data should be
10861 * freed with g_free() when you are finished using it.
10863 * Retrieves a portion of the contents of a property. If the
10864 * property does not exist, then the function returns %FALSE,
10865 * and %GDK_NONE will be stored in @actual_property_type.
10869 * The XGetWindowProperty() function that gdk_property_get()
10870 * uses has a very confusing and complicated set of semantics.
10871 * uses has a very confusing and complicated set of semantics.
10872 * Unfortunately, gdk_property_get() makes the situation
10873 * worse instead of better (the semantics should be considered
10874 * undefined), and also prints warnings to stderr in cases where it
10875 * should return a useful error to the program. You are advised to use
10876 * XGetWindowProperty() directly until a replacement function for
10877 * gdk_property_get()
10882 * Returns: %TRUE if data was successfully received and stored
10883 * in @data, otherwise %FALSE.
10886 gdk_property_get (GdkWindow *window,
10892 GdkAtom *actual_property_type,
10893 gint *actual_format_type,
10894 gint *actual_length,
10897 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10898 ->get_property (window, property, type, offset, length, pdelete,
10899 actual_property_type, actual_format_type,
10900 actual_length, data);
10904 * gdk_property_change: (skip)
10905 * @window: a #GdkWindow
10906 * @property: the property to change
10907 * @type: the new type for the property. If @mode is
10908 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
10909 * must match the existing type or an error will occur.
10910 * @format: the new format for the property. If @mode is
10911 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
10912 * must match the existing format or an error will occur.
10913 * @mode: a value describing how the new data is to be combined
10914 * with the current data.
10915 * @data: the data (a <literal>guchar *</literal>
10916 * <literal>gushort *</literal>, or <literal>gulong *</literal>,
10917 * depending on @format), cast to a <literal>guchar *</literal>.
10918 * @nelements: the number of elements of size determined by the format,
10919 * contained in @data.
10921 * Changes the contents of a property on a window.
10924 gdk_property_change (GdkWindow *window,
10929 const guchar *data,
10932 GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10933 ->change_property (window, property, type, format, mode, data, nelements);
10937 * gdk_property_delete:
10938 * @window: a #GdkWindow
10939 * @property: the property to delete
10941 * Deletes a property from a window.
10944 gdk_property_delete (GdkWindow *window,
10947 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->delete_property (window, property);