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 (usually) rectangular region on the screen.
55 * It's a low-level object, used to implement high-level objects such as
56 * #GtkWidget and #GtkWindow on the GTK+ level. A #GtkWindow is a toplevel
57 * window, the thing a user might think of as a "window" with a titlebar and
58 * so on; a #GtkWindow may contain many #GdkWindows. For example, each
59 * #GtkButton has a #GdkWindow associated with it.
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 * its 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;
211 cairo_region_t *dest_region; /* The destination region */
212 int dx, dy; /* The amount that the source was moved to reach dest_region */
213 } GdkWindowRegionMove;
217 static void gdk_window_drop_cairo_surface (GdkWindow *private);
219 static void gdk_window_free_paint_stack (GdkWindow *window);
221 static void gdk_window_finalize (GObject *object);
223 static void gdk_window_set_property (GObject *object,
227 static void gdk_window_get_property (GObject *object,
232 static void gdk_window_clear_backing_region (GdkWindow *window,
233 cairo_region_t *region);
235 static void recompute_visible_regions (GdkWindow *private,
236 gboolean recalculate_siblings,
237 gboolean recalculate_children);
238 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
239 static void gdk_window_flush_recursive (GdkWindow *window);
240 static void do_move_region_bits_on_impl (GdkWindow *window,
241 cairo_region_t *region, /* In impl window coords */
243 static void gdk_window_invalidate_in_parent (GdkWindow *private);
244 static void move_native_children (GdkWindow *private);
245 static void update_cursor (GdkDisplay *display,
247 static void impl_window_add_update_area (GdkWindow *impl_window,
248 cairo_region_t *region);
249 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
250 static void gdk_window_invalidate_region_full (GdkWindow *window,
251 const cairo_region_t *region,
252 gboolean invalidate_children,
254 static void gdk_window_invalidate_rect_full (GdkWindow *window,
255 const GdkRectangle *rect,
256 gboolean invalidate_children,
259 static guint signals[LAST_SIGNAL] = { 0 };
261 static gpointer parent_class = NULL;
263 static const cairo_user_data_key_t gdk_window_cairo_key;
265 G_DEFINE_ABSTRACT_TYPE (GdkWindow, gdk_window, G_TYPE_OBJECT)
268 _gdk_paintable_get_type (void)
270 static GType paintable_type = 0;
274 const GTypeInfo paintable_info =
276 sizeof (GdkPaintableIface), /* class_size */
277 NULL, /* base_init */
278 NULL, /* base_finalize */
281 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
282 g_intern_static_string ("GdkPaintable"),
285 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
288 return paintable_type;
292 gdk_window_init (GdkWindow *window)
294 /* 0-initialization is good for all other fields. */
296 window->window_type = GDK_WINDOW_CHILD;
298 window->state = GDK_WINDOW_STATE_WITHDRAWN;
301 window->toplevel_window_type = -1;
303 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
304 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
305 /* Default to unobscured since some backends don't send visibility events */
306 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
308 window->device_cursor = g_hash_table_new_full (NULL, NULL,
309 NULL, g_object_unref);
312 /* Stop and return on the first non-NULL parent */
314 accumulate_get_window (GSignalInvocationHint *ihint,
316 const GValue *handler_return,
319 g_value_copy (handler_return, return_accu);
320 /* Continue while returning NULL */
321 return g_value_get_object (handler_return) == NULL;
325 create_surface_accumulator (GSignalInvocationHint *ihint,
327 const GValue *handler_return,
330 g_value_copy (handler_return, return_accu);
332 /* Stop on the first non-NULL return value */
333 return g_value_get_boxed (handler_return) == NULL;
336 static GQuark quark_pointer_window = 0;
339 gdk_window_class_init (GdkWindowClass *klass)
341 GObjectClass *object_class = G_OBJECT_CLASS (klass);
343 parent_class = g_type_class_peek_parent (klass);
345 object_class->finalize = gdk_window_finalize;
346 object_class->set_property = gdk_window_set_property;
347 object_class->get_property = gdk_window_get_property;
349 klass->create_surface = _gdk_offscreen_window_create_surface;
351 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
359 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
360 * gdk_window_get_cursor() for details.
364 g_object_class_install_property (object_class,
366 g_param_spec_object ("cursor",
373 * GdkWindow::pick-embedded-child:
374 * @window: the window on which the signal is emitted
375 * @x: x coordinate in the window
376 * @y: y coordinate in the window
378 * The ::pick-embedded-child signal is emitted to find an embedded
379 * child at the given position.
381 * Returns: (transfer none): the #GdkWindow of the embedded child at
386 signals[PICK_EMBEDDED_CHILD] =
387 g_signal_new (g_intern_static_string ("pick-embedded-child"),
388 G_OBJECT_CLASS_TYPE (object_class),
390 G_STRUCT_OFFSET (GdkWindowClass, pick_embedded_child),
391 accumulate_get_window, NULL,
392 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
399 * GdkWindow::to-embedder:
400 * @window: the offscreen window on which the signal is emitted
401 * @offscreen-x: x coordinate in the offscreen window
402 * @offscreen-y: y coordinate in the offscreen window
403 * @embedder-x: (out) (type double): return location for the x
404 * coordinate in the embedder window
405 * @embedder-y: (out) (type double): return location for the y
406 * coordinate in the embedder window
408 * The ::to-embedder signal is emitted to translate coordinates
409 * in an offscreen window to its embedder.
411 * See also #GtkWindow::from-embedder.
415 signals[TO_EMBEDDER] =
416 g_signal_new (g_intern_static_string ("to-embedder"),
417 G_OBJECT_CLASS_TYPE (object_class),
419 G_STRUCT_OFFSET (GdkWindowClass, to_embedder),
421 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
430 * GdkWindow::from-embedder:
431 * @window: the offscreen window on which the signal is emitted
432 * @embedder-x: x coordinate in the embedder window
433 * @embedder-y: y coordinate in the embedder window
434 * @offscreen-x: (out) (type double): return location for the x
435 * coordinate in the offscreen window
436 * @offscreen-y: (out) (type double): return location for the y
437 * coordinate in the offscreen window
439 * The ::from-embedder signal is emitted to translate coordinates
440 * in the embedder of an offscreen window to the offscreen window.
442 * See also #GtkWindow::to-embedder.
446 signals[FROM_EMBEDDER] =
447 g_signal_new (g_intern_static_string ("from-embedder"),
448 G_OBJECT_CLASS_TYPE (object_class),
450 G_STRUCT_OFFSET (GdkWindowClass, from_embedder),
452 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
461 * GdkWindow::create-surface:
462 * @window: the offscreen window on which the signal is emitted
463 * @width: the width of the offscreen surface to create
464 * @height: the height of the offscreen surface to create
466 * The ::create-surface signal is emitted when an offscreen window
467 * needs its surface (re)created, which happens either when the the
468 * window is first drawn to, or when the window is being
469 * resized. The first signal handler that returns a non-%NULL
470 * surface will stop any further signal emission, and its surface
473 * Note that it is not possible to access the window's previous
474 * surface from within any callback of this signal. Calling
475 * gdk_offscreen_window_get_surface() will lead to a crash.
477 * Returns: the newly created #cairo_surface_t for the offscreen window
481 signals[CREATE_SURFACE] =
482 g_signal_new (g_intern_static_string ("create-surface"),
483 G_OBJECT_CLASS_TYPE (object_class),
485 G_STRUCT_OFFSET (GdkWindowClass, create_surface),
486 create_surface_accumulator, NULL,
487 _gdk_marshal_BOXED__INT_INT,
488 CAIRO_GOBJECT_TYPE_SURFACE,
495 device_removed_cb (GdkDeviceManager *device_manager,
499 window->devices_inside = g_list_remove (window->devices_inside, device);
500 g_hash_table_remove (window->device_cursor, device);
502 if (window->device_events)
503 g_hash_table_remove (window->device_events, device);
507 gdk_window_finalize (GObject *object)
509 GdkWindow *window = GDK_WINDOW (object);
510 GdkDeviceManager *device_manager;
512 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
513 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
515 if (!GDK_WINDOW_DESTROYED (window))
517 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
519 g_warning ("losing last reference to undestroyed window\n");
520 _gdk_window_destroy (window, FALSE);
523 /* We use TRUE here, to keep us from actually calling
524 * XDestroyWindow() on the window
526 _gdk_window_destroy (window, TRUE);
529 gdk_window_drop_cairo_surface (window);
533 g_object_unref (window->impl);
537 if (window->impl_window != window)
539 g_object_unref (window->impl_window);
540 window->impl_window = NULL;
544 cairo_region_destroy (window->shape);
546 if (window->input_shape)
547 cairo_region_destroy (window->input_shape);
550 g_object_unref (window->cursor);
552 if (window->device_cursor)
553 g_hash_table_destroy (window->device_cursor);
555 if (window->device_events)
556 g_hash_table_destroy (window->device_events);
558 if (window->source_event_masks)
559 g_hash_table_destroy (window->source_event_masks);
561 if (window->devices_inside)
562 g_list_free (window->devices_inside);
564 G_OBJECT_CLASS (parent_class)->finalize (object);
568 gdk_window_set_property (GObject *object,
573 GdkWindow *window = (GdkWindow *)object;
578 gdk_window_set_cursor (window, g_value_get_object (value));
582 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
588 gdk_window_get_property (GObject *object,
593 GdkWindow *window = (GdkWindow *) object;
598 g_value_set_object (value, gdk_window_get_cursor (window));
602 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
608 gdk_window_is_offscreen (GdkWindow *window)
610 return window->window_type == GDK_WINDOW_OFFSCREEN;
614 gdk_window_get_impl_window (GdkWindow *window)
616 return window->impl_window;
620 _gdk_window_get_impl_window (GdkWindow *window)
622 return gdk_window_get_impl_window (window);
626 gdk_window_has_impl (GdkWindow *window)
628 return window->impl_window == window;
632 gdk_window_is_toplevel (GdkWindow *window)
635 window->parent == NULL ||
636 window->parent->window_type == GDK_WINDOW_ROOT;
640 _gdk_window_has_impl (GdkWindow *window)
642 return gdk_window_has_impl (window);
646 gdk_window_has_no_impl (GdkWindow *window)
648 return window->impl_window != window;
652 remove_child_area (GdkWindow *private,
655 cairo_region_t *region)
658 cairo_region_t *child_region;
661 cairo_region_t *shape;
663 for (l = private->children; l; l = l->next)
670 /* If region is empty already, no need to do
671 anything potentially costly */
672 if (cairo_region_is_empty (region))
675 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
678 /* Ignore offscreen children, as they don't draw in their parent and
679 * don't take part in the clipping */
680 if (gdk_window_is_offscreen (child))
685 r.width = child->width;
686 r.height = child->height;
688 /* Bail early if child totally outside region */
689 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
692 child_region = cairo_region_create_rectangle (&r);
696 /* Adjust shape region to parent window coords */
697 cairo_region_translate (child->shape, child->x, child->y);
698 cairo_region_intersect (child_region, child->shape);
699 cairo_region_translate (child->shape, -child->x, -child->y);
701 else if (private->window_type == GDK_WINDOW_FOREIGN)
703 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_shape (child);
706 cairo_region_intersect (child_region, shape);
707 cairo_region_destroy (shape);
713 if (child->input_shape)
714 cairo_region_intersect (child_region, child->input_shape);
715 else if (private->window_type == GDK_WINDOW_FOREIGN)
717 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_input_shape (child);
720 cairo_region_intersect (child_region, shape);
721 cairo_region_destroy (shape);
726 cairo_region_subtract (region, child_region);
727 cairo_region_destroy (child_region);
732 static GdkVisibilityState
733 effective_visibility (GdkWindow *window)
735 GdkVisibilityState native;
737 if (!gdk_window_is_viewable (window))
738 return GDK_VISIBILITY_NOT_VIEWABLE;
740 native = window->impl_window->native_visibility;
742 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
743 window->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
744 return GDK_VISIBILITY_FULLY_OBSCURED;
745 else if (native == GDK_VISIBILITY_UNOBSCURED)
746 return window->visibility;
747 else /* native PARTIAL, private partial or unobscured */
748 return GDK_VISIBILITY_PARTIAL;
752 gdk_window_update_visibility (GdkWindow *window)
754 GdkVisibilityState new_visibility;
757 new_visibility = effective_visibility (window);
759 if (new_visibility != window->effective_visibility)
761 window->effective_visibility = new_visibility;
763 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
764 window->event_mask & GDK_VISIBILITY_NOTIFY)
766 event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY,
768 event->visibility.state = new_visibility;
774 gdk_window_update_visibility_recursively (GdkWindow *window,
775 GdkWindow *only_for_impl)
780 gdk_window_update_visibility (window);
781 for (l = window->children; l != NULL; l = l->next)
784 if ((only_for_impl == NULL) ||
785 (only_for_impl == child->impl_window))
786 gdk_window_update_visibility_recursively (child, only_for_impl);
791 should_apply_clip_as_shape (GdkWindow *window)
794 gdk_window_has_impl (window) &&
795 /* Not for offscreens */
796 !gdk_window_is_offscreen (window) &&
797 /* or for toplevels */
798 !gdk_window_is_toplevel (window) &&
799 /* or for foreign windows */
800 window->window_type != GDK_WINDOW_FOREIGN &&
801 /* or for the root window */
802 window->window_type != GDK_WINDOW_ROOT;
806 apply_shape (GdkWindow *window,
807 cairo_region_t *region)
809 GdkWindowImplClass *impl_class;
811 /* We trash whether we applied a shape so that
812 we can avoid unsetting it many times, which
813 could happen in e.g. apply_clip_as_shape as
814 windows get resized */
815 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
817 impl_class->shape_combine_region (window,
819 else if (window->applied_shape)
820 impl_class->shape_combine_region (window,
823 window->applied_shape = region != NULL;
827 region_rect_equal (const cairo_region_t *region,
828 const GdkRectangle *rect)
830 GdkRectangle extents;
832 if (cairo_region_num_rectangles (region) != 1)
835 cairo_region_get_extents (region, &extents);
837 return extents.x == rect->x &&
838 extents.y == rect->y &&
839 extents.width == rect->width &&
840 extents.height == rect->height;
844 apply_clip_as_shape (GdkWindow *window)
849 r.width = window->width;
850 r.height = window->height;
852 /* We only apply the clip region if would differ
853 from the actual clip region implied by the size
854 of the window. This is to avoid unneccessarily
855 adding meaningless shapes to all native subwindows */
856 if (!region_rect_equal (window->clip_region, &r))
857 apply_shape (window, window->clip_region);
859 apply_shape (window, NULL);
863 recompute_visible_regions_internal (GdkWindow *private,
864 gboolean recalculate_clip,
865 gboolean recalculate_siblings,
866 gboolean recalculate_children)
871 cairo_region_t *new_clip, *old_clip_region_with_children;
872 gboolean clip_region_changed;
873 gboolean abs_pos_changed;
874 int old_abs_x, old_abs_y;
876 old_abs_x = private->abs_x;
877 old_abs_y = private->abs_y;
879 /* Update absolute position */
880 if (gdk_window_has_impl (private))
882 /* Native window starts here */
888 private->abs_x = private->parent->abs_x + private->x;
889 private->abs_y = private->parent->abs_y + private->y;
893 private->abs_x != old_abs_x ||
894 private->abs_y != old_abs_y;
896 /* Update clip region based on:
899 * siblings in parents above window
901 clip_region_changed = FALSE;
902 if (recalculate_clip)
904 if (private->viewable)
906 /* Calculate visible region (sans children) in parent window coords */
909 r.width = private->width;
910 r.height = private->height;
911 new_clip = cairo_region_create_rectangle (&r);
913 if (!gdk_window_is_toplevel (private))
915 cairo_region_intersect (new_clip, private->parent->clip_region);
917 /* Remove all overlapping children from parent. */
918 remove_child_area (private->parent, private, FALSE, new_clip);
921 /* Convert from parent coords to window coords */
922 cairo_region_translate (new_clip, -private->x, -private->y);
925 cairo_region_intersect (new_clip, private->shape);
928 new_clip = cairo_region_create ();
930 if (private->clip_region == NULL ||
931 !cairo_region_equal (private->clip_region, new_clip))
932 clip_region_changed = TRUE;
934 if (private->clip_region)
935 cairo_region_destroy (private->clip_region);
936 private->clip_region = new_clip;
938 old_clip_region_with_children = private->clip_region_with_children;
939 private->clip_region_with_children = cairo_region_copy (private->clip_region);
940 if (private->window_type != GDK_WINDOW_ROOT)
941 remove_child_area (private, NULL, FALSE, private->clip_region_with_children);
943 if (old_clip_region_with_children)
944 cairo_region_destroy (old_clip_region_with_children);
947 if (clip_region_changed)
949 GdkVisibilityState visibility;
950 gboolean fully_visible;
952 if (cairo_region_is_empty (private->clip_region))
953 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
958 fully_visible = cairo_region_equal (private->clip_region,
965 r.width = private->width;
966 r.height = private->height;
967 fully_visible = region_rect_equal (private->clip_region, &r);
971 visibility = GDK_VISIBILITY_UNOBSCURED;
973 visibility = GDK_VISIBILITY_PARTIAL;
976 if (private->visibility != visibility)
978 private->visibility = visibility;
979 gdk_window_update_visibility (private);
983 /* Update all children, recursively (except for root, where children are not exact). */
984 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
985 private->window_type != GDK_WINDOW_ROOT)
987 for (l = private->children; l; l = l->next)
990 /* Only recalculate clip if the the clip region changed, otherwise
991 * there is no way the child clip region could change (its has not e.g. moved)
992 * Except if recalculate_children is set to force child updates
994 recompute_visible_regions_internal (child,
995 recalculate_clip && (clip_region_changed || recalculate_children),
1000 if (clip_region_changed &&
1001 should_apply_clip_as_shape (private))
1002 apply_clip_as_shape (private);
1004 if (recalculate_siblings &&
1005 !gdk_window_is_toplevel (private))
1007 /* If we moved a child window in parent or changed the stacking order, then we
1008 * need to recompute the visible area of all the other children in the parent
1010 for (l = private->parent->children; l; l = l->next)
1014 if (child != private)
1015 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1018 /* We also need to recompute the _with_children clip for the parent */
1019 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1022 if (private->cairo_surface && gdk_window_has_impl (private))
1024 GdkWindowImplClass *iface = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1026 private->cairo_surface = iface->resize_cairo_surface (private,
1027 private->cairo_surface,
1031 else if (private->cairo_surface)
1032 gdk_window_drop_cairo_surface (private);
1035 /* Call this when private has changed in one or more of these ways:
1039 * stacking order of window changed
1042 * It will recalculate abs_x/y and the clip regions
1044 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1045 * for recalculate_siblings. (Mostly used internally for the recursion)
1047 * If a child window was removed (and you can't use that child for
1048 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1051 recompute_visible_regions (GdkWindow *private,
1052 gboolean recalculate_siblings,
1053 gboolean recalculate_children)
1055 recompute_visible_regions_internal (private,
1057 recalculate_siblings,
1058 recalculate_children);
1062 _gdk_window_update_size (GdkWindow *window)
1064 recompute_visible_regions (window, TRUE, FALSE);
1067 /* Find the native window that would be just above "child"
1068 * in the native stacking order if "child" was a native window
1069 * (it doesn't have to be native). If there is no such native
1070 * window inside this native parent then NULL is returned.
1071 * If child is NULL, find lowest native window in parent.
1074 find_native_sibling_above_helper (GdkWindow *parent,
1082 l = g_list_find (parent->children, child);
1083 g_assert (l != NULL); /* Better be a child of its parent... */
1084 l = l->prev; /* Start looking at the one above the child */
1087 l = g_list_last (parent->children);
1089 for (; l != NULL; l = l->prev)
1093 if (gdk_window_has_impl (w))
1096 g_assert (parent != w);
1097 w = find_native_sibling_above_helper (w, NULL);
1107 find_native_sibling_above (GdkWindow *parent,
1112 w = find_native_sibling_above_helper (parent, child);
1116 if (gdk_window_has_impl (parent))
1119 return find_native_sibling_above (parent->parent, parent);
1123 get_native_device_event_mask (GdkWindow *private,
1126 GdkEventMask event_mask;
1129 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1131 event_mask = private->event_mask;
1133 if (private->window_type == GDK_WINDOW_ROOT ||
1134 private->window_type == GDK_WINDOW_FOREIGN)
1140 /* Do whatever the app asks to, since the app
1141 * may be asking for weird things for native windows,
1142 * but don't use motion hints as that may affect non-native
1143 * child windows that don't want it. Also, we need to
1144 * set all the app-specified masks since they will be picked
1145 * up by any implicit grabs (i.e. if they were not set as
1146 * native we would not get the events we need). */
1147 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1149 /* We need thse for all native windows so we can
1150 emulate events on children: */
1153 GDK_VISIBILITY_NOTIFY_MASK |
1154 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1156 /* Additionally we select for pointer and button events
1157 * for toplevels as we need to get these to emulate
1158 * them for non-native subwindows. Even though we don't
1159 * select on them for all native windows we will get them
1160 * as the events are propagated out to the first window
1161 * that select for them.
1162 * Not selecting for button press on all windows is an
1163 * important thing, because in X only one client can do
1164 * so, and we don't want to unexpectedly prevent another
1165 * client from doing it.
1167 * We also need to do the same if the app selects for button presses
1168 * because then we will get implicit grabs for this window, and the
1169 * event mask used for that grab is based on the rest of the mask
1170 * for the window, but we might need more events than this window
1171 * lists due to some non-native child window.
1173 if (gdk_window_is_toplevel (private) ||
1174 mask & GDK_BUTTON_PRESS_MASK)
1176 GDK_POINTER_MOTION_MASK |
1177 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1185 get_native_grab_event_mask (GdkEventMask grab_mask)
1187 /* Similar to the above but for pointer events only */
1189 GDK_POINTER_MOTION_MASK |
1190 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1191 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1194 ~GDK_POINTER_MOTION_HINT_MASK);
1198 get_native_event_mask (GdkWindow *private)
1200 return get_native_device_event_mask (private, NULL);
1203 /* Puts the native window in the right order wrt the other native windows
1204 * in the hierarchy, given the position it has in the client side data.
1205 * This is useful if some operation changed the stacking order.
1206 * This calls assumes the native window is now topmost in its native parent.
1209 sync_native_window_stack_position (GdkWindow *window)
1212 GdkWindowImplClass *impl_class;
1213 GList listhead = {0};
1215 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1217 above = find_native_sibling_above (window->parent, window);
1220 listhead.data = window;
1221 impl_class->restack_under (above, &listhead);
1226 * gdk_window_new: (constructor)
1227 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1228 * the default root window for the default display.
1229 * @attributes: attributes of the new window
1230 * @attributes_mask: mask indicating which fields in @attributes are valid
1232 * Creates a new #GdkWindow using the attributes from
1233 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1234 * more details. Note: to use this on displays other than the default
1235 * display, @parent must be specified.
1237 * Return value: (transfer full): the new #GdkWindow
1240 gdk_window_new (GdkWindow *parent,
1241 GdkWindowAttr *attributes,
1242 gint attributes_mask)
1246 GdkDisplay *display;
1249 GdkEventMask event_mask;
1250 GdkWindow *real_parent;
1251 GdkDeviceManager *device_manager;
1253 g_return_val_if_fail (attributes != NULL, NULL);
1257 GDK_NOTE (MULTIHEAD,
1258 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1260 screen = gdk_screen_get_default ();
1261 parent = gdk_screen_get_root_window (screen);
1264 screen = gdk_window_get_screen (parent);
1266 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1268 if (GDK_WINDOW_DESTROYED (parent))
1270 g_warning ("gdk_window_new(): parent is destroyed\n");
1274 display = gdk_screen_get_display (screen);
1276 window = _gdk_display_create_window (display);
1278 /* Windows with a foreign parent are treated as if they are children
1279 * of the root window, except for actual creation.
1281 real_parent = parent;
1282 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1283 parent = gdk_screen_get_root_window (screen);
1285 window->parent = parent;
1287 window->accept_focus = TRUE;
1288 window->focus_on_map = TRUE;
1290 if (attributes_mask & GDK_WA_X)
1295 if (attributes_mask & GDK_WA_Y)
1302 window->width = (attributes->width > 1) ? (attributes->width) : (1);
1303 window->height = (attributes->height > 1) ? (attributes->height) : (1);
1305 if (attributes->wclass == GDK_INPUT_ONLY)
1307 /* Backwards compatiblity - we've always ignored
1308 * attributes->window_type for input-only windows
1311 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1312 window->window_type = GDK_WINDOW_TEMP;
1314 window->window_type = GDK_WINDOW_CHILD;
1317 window->window_type = attributes->window_type;
1320 switch (window->window_type)
1322 case GDK_WINDOW_TOPLEVEL:
1323 case GDK_WINDOW_TEMP:
1324 case GDK_WINDOW_OFFSCREEN:
1325 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1326 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1327 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1328 case GDK_WINDOW_CHILD:
1332 g_warning (G_STRLOC "cannot make windows of type %d", window->window_type);
1336 if (attributes_mask & GDK_WA_VISUAL)
1337 window->visual = attributes->visual;
1339 window->visual = gdk_screen_get_system_visual (screen);
1341 window->event_mask = attributes->event_mask;
1343 if (attributes->wclass == GDK_INPUT_OUTPUT)
1345 window->input_only = FALSE;
1346 window->depth = window->visual->depth;
1348 /* XXX: Cache this somehow? */
1349 window->background = cairo_pattern_create_rgb (0, 0, 0);
1354 window->input_only = TRUE;
1358 window->parent->children = g_list_prepend (window->parent->children, window);
1361 if (window->parent->window_type == GDK_WINDOW_ROOT)
1362 native = TRUE; /* Always use native windows for toplevels */
1363 else if (!window->input_only &&
1364 (attributes_mask & GDK_WA_VISUAL &&
1365 attributes->visual != gdk_window_get_visual (window->parent)))
1366 native = TRUE; /* InputOutput window with different visual than parent, needs native window */
1368 if (gdk_window_is_offscreen (window))
1370 _gdk_offscreen_window_new (window, attributes, attributes_mask);
1371 window->impl_window = window;
1375 event_mask = get_native_event_mask (window);
1377 /* Create the impl */
1378 _gdk_display_create_window_impl (display, window, real_parent, screen, event_mask, attributes, attributes_mask);
1379 window->impl_window = window;
1381 /* This will put the native window topmost in the native parent, which may
1382 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1383 if (!_gdk_window_has_impl (real_parent))
1384 sync_native_window_stack_position (window);
1388 window->impl_window = g_object_ref (window->parent->impl_window);
1389 window->impl = g_object_ref (window->impl_window->impl);
1392 recompute_visible_regions (window, TRUE, FALSE);
1394 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1395 (attributes->cursor) :
1398 device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent));
1399 g_signal_connect (device_manager, "device-removed",
1400 G_CALLBACK (device_removed_cb), window);
1406 is_parent_of (GdkWindow *parent,
1417 w = gdk_window_get_parent (w);
1424 change_impl (GdkWindow *private,
1425 GdkWindow *impl_window,
1430 GdkWindowImpl *old_impl;
1431 GdkWindow *old_impl_window;
1433 old_impl = private->impl;
1434 old_impl_window = private->impl_window;
1435 if (private != impl_window)
1436 private->impl_window = g_object_ref (impl_window);
1438 private->impl_window = private;
1439 private->impl = g_object_ref (new);
1440 if (old_impl_window != private)
1441 g_object_unref (old_impl_window);
1442 g_object_unref (old_impl);
1444 for (l = private->children; l != NULL; l = l->next)
1448 if (child->impl == old_impl)
1449 change_impl (child, impl_window, new);
1454 reparent_to_impl (GdkWindow *private)
1459 GdkWindowImplClass *impl_class;
1461 impl_class = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1463 /* Enumerate in reverse order so we get the right order for the native
1464 windows (first in childrens list is topmost, and reparent places on top) */
1465 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1469 if (child->impl == private->impl)
1470 reparent_to_impl (child);
1473 show = impl_class->reparent ((GdkWindow *)child,
1474 (GdkWindow *)private,
1475 child->x, child->y);
1477 gdk_window_show_unraised ((GdkWindow *)child);
1484 * gdk_window_reparent:
1485 * @window: a #GdkWindow
1486 * @new_parent: new parent to move @window into
1487 * @x: X location inside the new parent
1488 * @y: Y location inside the new parent
1490 * Reparents @window into the given @new_parent. The window being
1491 * reparented will be unmapped as a side effect.
1495 gdk_window_reparent (GdkWindow *window,
1496 GdkWindow *new_parent,
1500 GdkWindow *old_parent;
1502 gboolean show, was_mapped, applied_clip_as_shape;
1503 gboolean do_reparent_to_impl;
1504 GdkEventMask old_native_event_mask;
1505 GdkWindowImplClass *impl_class;
1507 g_return_if_fail (GDK_IS_WINDOW (window));
1508 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1509 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1511 if (GDK_WINDOW_DESTROYED (window) ||
1512 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1515 screen = gdk_window_get_screen (window);
1517 new_parent = gdk_screen_get_root_window (screen);
1519 /* No input-output children of input-only windows */
1520 if (new_parent->input_only && !window->input_only)
1523 /* Don't create loops in hierarchy */
1524 if (is_parent_of (window, new_parent))
1527 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1528 To make sure we're ok, just wipe it. */
1529 gdk_window_drop_cairo_surface (window);
1531 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1532 old_parent = window->parent;
1534 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1537 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1538 if (new_parent->window_type == GDK_WINDOW_ROOT ||
1539 new_parent->window_type == GDK_WINDOW_FOREIGN)
1540 gdk_window_ensure_native (window);
1542 applied_clip_as_shape = should_apply_clip_as_shape (window);
1544 old_native_event_mask = 0;
1545 do_reparent_to_impl = FALSE;
1546 if (gdk_window_has_impl (window))
1548 old_native_event_mask = get_native_event_mask (window);
1550 show = impl_class->reparent (window, new_parent, x, y);
1554 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1555 g_assert (new_parent->window_type != GDK_WINDOW_ROOT &&
1556 new_parent->window_type != GDK_WINDOW_FOREIGN);
1559 gdk_window_hide (window);
1561 do_reparent_to_impl = TRUE;
1562 change_impl (window,
1563 new_parent->impl_window,
1567 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1570 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1572 new_parent = gdk_screen_get_root_window (screen);
1576 old_parent->children = g_list_remove (old_parent->children, window);
1578 window->parent = new_parent;
1582 new_parent->children = g_list_prepend (new_parent->children, window);
1584 /* Switch the window type as appropriate */
1586 switch (GDK_WINDOW_TYPE (new_parent))
1588 case GDK_WINDOW_ROOT:
1589 case GDK_WINDOW_FOREIGN:
1590 if (window->toplevel_window_type != -1)
1591 GDK_WINDOW_TYPE (window) = window->toplevel_window_type;
1592 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1593 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1595 case GDK_WINDOW_OFFSCREEN:
1596 case GDK_WINDOW_TOPLEVEL:
1597 case GDK_WINDOW_CHILD:
1598 case GDK_WINDOW_TEMP:
1599 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1600 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1602 /* Save the original window type so we can restore it if the
1603 * window is reparented back to be a toplevel
1605 window->toplevel_window_type = GDK_WINDOW_TYPE (window);
1606 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1610 /* We might have changed window type for a native windows, so we
1611 need to change the event mask too. */
1612 if (gdk_window_has_impl (window))
1614 GdkEventMask native_event_mask = get_native_event_mask (window);
1616 if (native_event_mask != old_native_event_mask)
1617 impl_class->set_events (window, native_event_mask);
1620 _gdk_window_update_viewable (window);
1622 recompute_visible_regions (window, TRUE, FALSE);
1623 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1624 recompute_visible_regions (old_parent, FALSE, TRUE);
1626 /* We used to apply the clip as the shape, but no more.
1627 Reset this to the real shape */
1628 if (gdk_window_has_impl (window) &&
1629 applied_clip_as_shape &&
1630 !should_apply_clip_as_shape (window))
1631 apply_shape (window, window->shape);
1633 if (do_reparent_to_impl)
1634 reparent_to_impl (window);
1637 /* The reparent will have put the native window topmost in the native parent,
1638 * which may be wrong wrt other native windows in the non-native hierarchy,
1640 if (!gdk_window_has_impl (new_parent))
1641 sync_native_window_stack_position (window);
1645 gdk_window_show_unraised (window);
1647 _gdk_synthesize_crossing_events_for_geometry_change (window);
1651 * gdk_window_ensure_native:
1652 * @window: a #GdkWindow
1654 * Tries to ensure that there is a window-system native window for this
1655 * GdkWindow. This may fail in some situations, returning %FALSE.
1657 * Offscreen window and children of them can never have native windows.
1659 * Some backends may not support native child windows.
1661 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1666 gdk_window_ensure_native (GdkWindow *window)
1668 GdkWindow *impl_window;
1669 GdkWindowImpl *new_impl, *old_impl;
1670 GdkDisplay *display;
1674 GdkWindowImplClass *impl_class;
1676 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1678 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1679 GDK_WINDOW_DESTROYED (window))
1682 impl_window = gdk_window_get_impl_window (window);
1684 if (gdk_window_is_offscreen (impl_window))
1685 return FALSE; /* native in offscreens not supported */
1687 if (impl_window == window)
1688 /* Already has an impl, and its not offscreen . */
1691 /* Need to create a native window */
1693 gdk_window_drop_cairo_surface (window);
1695 screen = gdk_window_get_screen (window);
1696 display = gdk_screen_get_display (screen);
1698 old_impl = window->impl;
1699 _gdk_display_create_window_impl (display,
1700 window, window->parent,
1702 get_native_event_mask (window),
1704 new_impl = window->impl;
1706 window->impl = old_impl;
1707 change_impl (window, window, new_impl);
1709 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1711 /* Native window creation will put the native window topmost in the
1712 * native parent, which may be wrong wrt the position of the previous
1713 * non-native window wrt to the other non-native children, so correct this.
1715 above = find_native_sibling_above (window->parent, window);
1718 listhead.data = window;
1719 listhead.prev = NULL;
1720 listhead.next = NULL;
1721 impl_class->restack_under ((GdkWindow *)above, &listhead);
1724 recompute_visible_regions (window, FALSE, FALSE);
1726 /* The shape may not have been set, as the clip region doesn't actually
1727 change, so do it here manually */
1728 if (should_apply_clip_as_shape (window))
1729 apply_clip_as_shape (window);
1731 reparent_to_impl (window);
1733 if (!window->input_only)
1734 impl_class->set_background (window, window->background);
1736 impl_class->input_shape_combine_region (window,
1737 window->input_shape,
1740 if (gdk_window_is_viewable (window))
1741 impl_class->show (window, FALSE);
1747 * _gdk_event_filter_unref:
1748 * @window: (allow-none): A #GdkWindow, or %NULL to be the global window
1749 * @filter: A window filter
1751 * Release a reference to @filter. Note this function may
1752 * mutate the list storage, so you need to handle this
1753 * if iterating over a list of filters.
1756 _gdk_event_filter_unref (GdkWindow *window,
1757 GdkEventFilter *filter)
1763 filters = &_gdk_default_filters;
1765 filters = &window->filters;
1767 tmp_list = *filters;
1770 GdkEventFilter *iter_filter = tmp_list->data;
1774 tmp_list = tmp_list->next;
1776 if (iter_filter != filter)
1779 g_assert (iter_filter->ref_count > 0);
1781 filter->ref_count--;
1782 if (filter->ref_count != 0)
1785 *filters = g_list_remove_link (*filters, node);
1787 g_list_free_1 (node);
1792 window_remove_filters (GdkWindow *window)
1794 while (window->filters)
1795 _gdk_event_filter_unref (window, window->filters->data);
1799 update_pointer_info_foreach (GdkDisplay *display,
1801 GdkPointerWindowInfo *pointer_info,
1804 GdkWindow *window = user_data;
1806 if (pointer_info->toplevel_under_pointer == window)
1808 g_object_unref (pointer_info->toplevel_under_pointer);
1809 pointer_info->toplevel_under_pointer = NULL;
1814 window_remove_from_pointer_info (GdkWindow *window,
1815 GdkDisplay *display)
1817 _gdk_display_pointer_info_foreach (display,
1818 update_pointer_info_foreach,
1823 * _gdk_window_destroy_hierarchy:
1824 * @window: a #GdkWindow
1825 * @recursing: If TRUE, then this is being called because a parent
1827 * @recursing_native: If TRUE, then this is being called because a native parent
1828 * was destroyed. This generally means that the call to the
1829 * windowing system to destroy the window can be omitted, since
1830 * it will be destroyed as a result of the parent being destroyed.
1831 * Unless @foreign_destroy.
1832 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1833 * external agency. The window has already been destroyed and no
1834 * windowing system calls should be made. (This may never happen
1835 * for some windowing systems.)
1837 * Internal function to destroy a window. Like gdk_window_destroy(),
1838 * but does not drop the reference count created by gdk_window_new().
1841 _gdk_window_destroy_hierarchy (GdkWindow *window,
1843 gboolean recursing_native,
1844 gboolean foreign_destroy)
1846 GdkWindowImplClass *impl_class;
1847 GdkWindow *temp_window;
1849 GdkDisplay *display;
1853 g_return_if_fail (GDK_IS_WINDOW (window));
1855 if (GDK_WINDOW_DESTROYED (window))
1858 display = gdk_window_get_display (window);
1859 screen = gdk_window_get_screen (window);
1860 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
1861 if (temp_window == window)
1862 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
1865 switch (window->window_type)
1867 case GDK_WINDOW_ROOT:
1868 if (!screen->closed)
1870 g_error ("attempted to destroy root window");
1873 /* else fall thru */
1874 case GDK_WINDOW_TOPLEVEL:
1875 case GDK_WINDOW_CHILD:
1876 case GDK_WINDOW_TEMP:
1877 case GDK_WINDOW_FOREIGN:
1878 case GDK_WINDOW_OFFSCREEN:
1879 if (window->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
1881 /* Logically, it probably makes more sense to send
1882 * a "destroy yourself" message to the foreign window
1883 * whether or not it's in our hierarchy; but for historical
1884 * reasons, we only send "destroy yourself" messages to
1885 * foreign windows in our hierarchy.
1889 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1891 if (gdk_window_has_impl (window))
1892 impl_class->destroy_foreign (window);
1895 /* Also for historical reasons, we remove any filters
1896 * on a foreign window when it or a parent is destroyed;
1897 * this likely causes problems if two separate portions
1898 * of code are maintaining filter lists on a foreign window.
1900 window_remove_filters (window);
1906 if (window->parent->children)
1907 window->parent->children = g_list_remove (window->parent->children, window);
1910 GDK_WINDOW_IS_MAPPED (window))
1912 recompute_visible_regions (window, TRUE, FALSE);
1913 gdk_window_invalidate_in_parent (window);
1917 gdk_window_free_paint_stack (window);
1919 if (window->background)
1921 cairo_pattern_destroy (window->background);
1922 window->background = NULL;
1925 if (window->window_type == GDK_WINDOW_FOREIGN)
1926 g_assert (window->children == NULL);
1929 children = tmp = window->children;
1930 window->children = NULL;
1934 temp_window = tmp->data;
1938 _gdk_window_destroy_hierarchy (temp_window,
1940 recursing_native || gdk_window_has_impl (window),
1944 g_list_free (children);
1947 _gdk_window_clear_update_area (window);
1949 gdk_window_drop_cairo_surface (window);
1951 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1953 if (gdk_window_has_impl (window))
1954 impl_class->destroy (window, recursing_native,
1958 /* hide to make sure we repaint and break grabs */
1959 gdk_window_hide (window);
1962 window->state |= GDK_WINDOW_STATE_WITHDRAWN;
1963 window->parent = NULL;
1964 window->destroyed = TRUE;
1966 window_remove_filters (window);
1968 window_remove_from_pointer_info (window, display);
1970 if (window->clip_region)
1972 cairo_region_destroy (window->clip_region);
1973 window->clip_region = NULL;
1976 if (window->clip_region_with_children)
1978 cairo_region_destroy (window->clip_region_with_children);
1979 window->clip_region_with_children = NULL;
1982 if (window->outstanding_moves)
1984 g_list_foreach (window->outstanding_moves, (GFunc)gdk_window_region_move_free, NULL);
1985 g_list_free (window->outstanding_moves);
1986 window->outstanding_moves = NULL;
1994 * _gdk_window_destroy:
1995 * @window: a #GdkWindow
1996 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1997 * external agency. The window has already been destroyed and no
1998 * windowing system calls should be made. (This may never happen
1999 * for some windowing systems.)
2001 * Internal function to destroy a window. Like gdk_window_destroy(),
2002 * but does not drop the reference count created by gdk_window_new().
2005 _gdk_window_destroy (GdkWindow *window,
2006 gboolean foreign_destroy)
2008 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2012 * gdk_window_destroy:
2013 * @window: a #GdkWindow
2015 * Destroys the window system resources associated with @window and decrements @window's
2016 * reference count. The window system resources for all children of @window are also
2017 * destroyed, but the children's reference counts are not decremented.
2019 * Note that a window will not be destroyed automatically when its reference count
2020 * reaches zero. You must call this function yourself before that happens.
2024 gdk_window_destroy (GdkWindow *window)
2026 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2027 g_object_unref (window);
2031 * gdk_window_set_user_data:
2032 * @window: a #GdkWindow
2033 * @user_data: (allow-none) (type GObject.Object): user data
2035 * For most purposes this function is deprecated in favor of
2036 * g_object_set_data(). However, for historical reasons GTK+ stores
2037 * the #GtkWidget that owns a #GdkWindow as user data on the
2038 * #GdkWindow. So, custom widget implementations should use
2039 * this function for that. If GTK+ receives an event for a #GdkWindow,
2040 * and the user data for the window is non-%NULL, GTK+ will assume the
2041 * user data is a #GtkWidget, and forward the event to that widget.
2045 gdk_window_set_user_data (GdkWindow *window,
2048 g_return_if_fail (GDK_IS_WINDOW (window));
2050 window->user_data = user_data;
2054 * gdk_window_get_user_data:
2055 * @window: a #GdkWindow
2056 * @data: (out): return location for user data
2058 * Retrieves the user data for @window, which is normally the widget
2059 * that @window belongs to. See gdk_window_set_user_data().
2063 gdk_window_get_user_data (GdkWindow *window,
2066 g_return_if_fail (GDK_IS_WINDOW (window));
2068 *data = window->user_data;
2072 * gdk_window_get_window_type:
2073 * @window: a #GdkWindow
2075 * Gets the type of the window. See #GdkWindowType.
2077 * Return value: type of window
2080 gdk_window_get_window_type (GdkWindow *window)
2082 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2084 return GDK_WINDOW_TYPE (window);
2088 * gdk_window_get_visual:
2089 * @window: a #GdkWindow
2091 * Gets the #GdkVisual describing the pixel format of @window.
2093 * Return value: (transfer none): a #GdkVisual
2098 gdk_window_get_visual (GdkWindow *window)
2100 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2102 return window->visual;
2106 * gdk_window_get_screen:
2107 * @window: a #GdkWindow
2109 * Gets the #GdkScreen associated with a #GdkWindow.
2111 * Return value: (transfer none): the #GdkScreen associated with @window
2116 gdk_window_get_screen (GdkWindow *window)
2118 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2120 return gdk_visual_get_screen (window->visual);
2124 * gdk_window_get_display:
2125 * @window: a #GdkWindow
2127 * Gets the #GdkDisplay associated with a #GdkWindow.
2129 * Return value: (transfer none): the #GdkDisplay associated with @window
2134 gdk_window_get_display (GdkWindow *window)
2136 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2138 return gdk_screen_get_display (gdk_visual_get_screen (window->visual));
2141 * gdk_window_is_destroyed:
2142 * @window: a #GdkWindow
2144 * Check to see if a window is destroyed..
2146 * Return value: %TRUE if the window is destroyed
2151 gdk_window_is_destroyed (GdkWindow *window)
2153 return GDK_WINDOW_DESTROYED (window);
2157 to_embedder (GdkWindow *window,
2158 gdouble offscreen_x,
2159 gdouble offscreen_y,
2160 gdouble *embedder_x,
2161 gdouble *embedder_y)
2163 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2164 offscreen_x, offscreen_y,
2165 embedder_x, embedder_y);
2169 from_embedder (GdkWindow *window,
2172 gdouble *offscreen_x,
2173 gdouble *offscreen_y)
2175 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2176 embedder_x, embedder_y,
2177 offscreen_x, offscreen_y);
2181 * gdk_window_has_native:
2182 * @window: a #GdkWindow
2184 * Checks whether the window has a native window or not. Note that
2185 * you can use gdk_window_ensure_native() if a native window is needed.
2187 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2192 gdk_window_has_native (GdkWindow *window)
2194 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2196 return window->parent == NULL || window->parent->impl != window->impl;
2200 * gdk_window_get_position:
2201 * @window: a #GdkWindow
2202 * @x: (out) (allow-none): X coordinate of window
2203 * @y: (out) (allow-none): Y coordinate of window
2205 * Obtains the position of the window as reported in the
2206 * most-recently-processed #GdkEventConfigure. Contrast with
2207 * gdk_window_get_geometry() which queries the X server for the
2208 * current window position, regardless of which events have been
2209 * received or processed.
2211 * The position coordinates are relative to the window's parent window.
2215 gdk_window_get_position (GdkWindow *window,
2219 g_return_if_fail (GDK_IS_WINDOW (window));
2228 * gdk_window_get_parent:
2229 * @window: a #GdkWindow
2231 * Obtains the parent of @window, as known to GDK. Does not query the
2232 * X server; thus this returns the parent as passed to gdk_window_new(),
2233 * not the actual parent. This should never matter unless you're using
2234 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2235 * matter for toplevel windows, because the window manager may choose
2238 * Note that you should use gdk_window_get_effective_parent() when
2239 * writing generic code that walks up a window hierarchy, because
2240 * gdk_window_get_parent() will most likely not do what you expect if
2241 * there are offscreen windows in the hierarchy.
2243 * Return value: (transfer none): parent of @window
2246 gdk_window_get_parent (GdkWindow *window)
2248 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2250 return window->parent;
2254 * gdk_window_get_effective_parent:
2255 * @window: a #GdkWindow
2257 * Obtains the parent of @window, as known to GDK. Works like
2258 * gdk_window_get_parent() for normal windows, but returns the
2259 * window's embedder for offscreen windows.
2261 * See also: gdk_offscreen_window_get_embedder()
2263 * Return value: (transfer none): effective parent of @window
2268 gdk_window_get_effective_parent (GdkWindow *window)
2270 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2272 if (gdk_window_is_offscreen (window))
2273 return gdk_offscreen_window_get_embedder (window);
2275 return window->parent;
2279 * gdk_window_get_toplevel:
2280 * @window: a #GdkWindow
2282 * Gets the toplevel window that's an ancestor of @window.
2284 * Any window type but %GDK_WINDOW_CHILD is considered a
2285 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2286 * has a root window as parent.
2288 * Note that you should use gdk_window_get_effective_toplevel() when
2289 * you want to get to a window's toplevel as seen on screen, because
2290 * gdk_window_get_toplevel() will most likely not do what you expect
2291 * if there are offscreen windows in the hierarchy.
2293 * Return value: (transfer none): the toplevel window containing @window
2296 gdk_window_get_toplevel (GdkWindow *window)
2298 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2300 while (window->window_type == GDK_WINDOW_CHILD)
2302 if (gdk_window_is_toplevel (window))
2304 window = window->parent;
2311 * gdk_window_get_effective_toplevel:
2312 * @window: a #GdkWindow
2314 * Gets the toplevel window that's an ancestor of @window.
2316 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2317 * embedder as its parent, using gdk_window_get_effective_parent().
2319 * See also: gdk_offscreen_window_get_embedder()
2321 * Return value: (transfer none): the effective toplevel window containing @window
2326 gdk_window_get_effective_toplevel (GdkWindow *window)
2330 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2332 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2333 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2340 * gdk_window_get_children:
2341 * @window: a #GdkWindow
2343 * Gets the list of children of @window known to GDK.
2344 * This function only returns children created via GDK,
2345 * so for example it's useless when used with the root window;
2346 * it only returns windows an application created itself.
2348 * The returned list must be freed, but the elements in the
2351 * Return value: (transfer container) (element-type GdkWindow):
2352 * list of child windows inside @window
2355 gdk_window_get_children (GdkWindow *window)
2357 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2359 if (GDK_WINDOW_DESTROYED (window))
2362 return g_list_copy (window->children);
2366 * gdk_window_peek_children:
2367 * @window: a #GdkWindow
2369 * Like gdk_window_get_children(), but does not copy the list of
2370 * children, so the list does not need to be freed.
2372 * Return value: (transfer none) (element-type GdkWindow):
2373 * a reference to the list of child windows in @window
2376 gdk_window_peek_children (GdkWindow *window)
2378 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2380 if (GDK_WINDOW_DESTROYED (window))
2383 return window->children;
2387 * gdk_window_add_filter: (skip)
2388 * @window: (allow-none): a #GdkWindow
2389 * @function: filter callback
2390 * @data: data to pass to filter callback
2392 * Adds an event filter to @window, allowing you to intercept events
2393 * before they reach GDK. This is a low-level operation and makes it
2394 * easy to break GDK and/or GTK+, so you have to know what you're
2395 * doing. Pass %NULL for @window to get all events for all windows,
2396 * instead of events for a specific window.
2398 * If you are interested in X GenericEvents, bear in mind that
2399 * XGetEventData() has been already called on the event, and
2400 * XFreeEventData() must not be called within @function.
2403 gdk_window_add_filter (GdkWindow *window,
2404 GdkFilterFunc function,
2408 GdkEventFilter *filter;
2410 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2412 if (window && GDK_WINDOW_DESTROYED (window))
2415 /* Filters are for the native events on the native window, so
2416 ensure there is a native window. */
2418 gdk_window_ensure_native (window);
2421 tmp_list = window->filters;
2423 tmp_list = _gdk_default_filters;
2427 filter = (GdkEventFilter *)tmp_list->data;
2428 if ((filter->function == function) && (filter->data == data))
2430 filter->ref_count++;
2433 tmp_list = tmp_list->next;
2436 filter = g_new (GdkEventFilter, 1);
2437 filter->function = function;
2438 filter->data = data;
2439 filter->ref_count = 1;
2443 window->filters = g_list_append (window->filters, filter);
2445 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2449 * gdk_window_remove_filter: (skip)
2450 * @window: a #GdkWindow
2451 * @function: previously-added filter function
2452 * @data: user data for previously-added filter function
2454 * Remove a filter previously added with gdk_window_add_filter().
2457 gdk_window_remove_filter (GdkWindow *window,
2458 GdkFilterFunc function,
2462 GdkEventFilter *filter;
2464 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2467 tmp_list = window->filters;
2469 tmp_list = _gdk_default_filters;
2473 filter = (GdkEventFilter *)tmp_list->data;
2474 tmp_list = tmp_list->next;
2476 if ((filter->function == function) && (filter->data == data))
2478 filter->flags |= GDK_EVENT_FILTER_REMOVED;
2480 _gdk_event_filter_unref (window, filter);
2488 * gdk_screen_get_toplevel_windows:
2489 * @screen: The #GdkScreen where the toplevels are located.
2491 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2492 * A toplevel window is a child of the root window (see
2493 * gdk_get_default_root_window()).
2495 * The returned list should be freed with g_list_free(), but
2496 * its elements need not be freed.
2498 * Return value: (transfer container) (element-type GdkWindow):
2499 * list of toplevel windows, free with g_list_free()
2504 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2506 GdkWindow * root_window;
2507 GList *new_list = NULL;
2510 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2512 root_window = gdk_screen_get_root_window (screen);
2514 tmp_list = root_window->children;
2517 GdkWindow *w = tmp_list->data;
2519 if (w->window_type != GDK_WINDOW_FOREIGN)
2520 new_list = g_list_prepend (new_list, w);
2521 tmp_list = tmp_list->next;
2528 * gdk_window_is_visible:
2529 * @window: a #GdkWindow
2531 * Checks whether the window has been mapped (with gdk_window_show() or
2532 * gdk_window_show_unraised()).
2534 * Return value: %TRUE if the window is mapped
2537 gdk_window_is_visible (GdkWindow *window)
2539 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2541 return GDK_WINDOW_IS_MAPPED (window);
2545 * gdk_window_is_viewable:
2546 * @window: a #GdkWindow
2548 * Check if the window and all ancestors of the window are
2549 * mapped. (This is not necessarily "viewable" in the X sense, since
2550 * we only check as far as we have GDK window parents, not to the root
2553 * Return value: %TRUE if the window is viewable
2556 gdk_window_is_viewable (GdkWindow *window)
2558 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2560 if (window->destroyed)
2563 return window->viewable;
2567 * gdk_window_get_state:
2568 * @window: a #GdkWindow
2570 * Gets the bitwise OR of the currently active window state flags,
2571 * from the #GdkWindowState enumeration.
2573 * Return value: window state bitfield
2576 gdk_window_get_state (GdkWindow *window)
2578 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2580 return window->state;
2583 static cairo_content_t
2584 gdk_window_get_content (GdkWindow *window)
2586 cairo_surface_t *surface;
2587 cairo_content_t content;
2589 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2591 surface = _gdk_window_ref_cairo_surface (window);
2592 content = cairo_surface_get_content (surface);
2593 cairo_surface_destroy (surface);
2598 /* This creates an empty "implicit" paint region for the impl window.
2599 * By itself this does nothing, but real paints to this window
2600 * or children of it can use this surface as backing to avoid allocating
2601 * multiple surfaces for subwindow rendering. When doing so they
2602 * add to the region of the implicit paint region, which will be
2603 * pushed to the window when the implicit paint region is ended.
2604 * Such paints should not copy anything to the window on paint end, but
2605 * should rely on the implicit paint end.
2606 * The implicit paint will be automatically ended if someone draws
2607 * directly to the window or a child window.
2610 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect)
2612 GdkWindowPaint *paint;
2614 g_assert (gdk_window_has_impl (window));
2616 if (GDK_IS_PAINTABLE (window->impl))
2617 return FALSE; /* Implementation does double buffering */
2619 if (window->paint_stack != NULL ||
2620 window->implicit_paint != NULL)
2621 return FALSE; /* Don't stack implicit paints */
2623 /* Never do implicit paints for foreign windows, they don't need
2624 * double buffer combination since they have no client side children,
2625 * and creating surfaces for them is risky since they could disappear
2628 if (window->window_type == GDK_WINDOW_FOREIGN)
2631 paint = g_new (GdkWindowPaint, 1);
2632 paint->region = cairo_region_create (); /* Empty */
2633 paint->uses_implicit = FALSE;
2634 paint->flushed = FALSE;
2635 paint->surface = gdk_window_create_similar_surface (window,
2636 gdk_window_get_content (window),
2637 MAX (rect->width, 1),
2638 MAX (rect->height, 1));
2639 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2641 window->implicit_paint = paint;
2646 static cairo_surface_t *
2647 gdk_window_ref_impl_surface (GdkWindow *window)
2649 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->ref_cairo_surface (gdk_window_get_impl_window (window));
2653 gdk_cairo_create_for_impl (GdkWindow *window)
2655 cairo_surface_t *surface;
2658 surface = gdk_window_ref_impl_surface (window);
2659 cr = cairo_create (surface);
2661 cairo_surface_destroy (surface);
2666 /* Ensure that all content related to this (sub)window is pushed to the
2667 native region. If there is an active paint then that area is not
2668 pushed, in order to not show partially finished double buffers. */
2670 gdk_window_flush_implicit_paint (GdkWindow *window)
2672 GdkWindow *impl_window;
2673 GdkWindowPaint *paint;
2674 cairo_region_t *region;
2677 impl_window = gdk_window_get_impl_window (window);
2678 if (impl_window->implicit_paint == NULL)
2681 paint = impl_window->implicit_paint;
2682 paint->flushed = TRUE;
2683 region = cairo_region_copy (window->clip_region_with_children);
2685 /* Don't flush active double buffers, as that may show partially done
2687 for (list = window->paint_stack; list != NULL; list = list->next)
2689 GdkWindowPaint *tmp_paint = list->data;
2691 cairo_region_subtract (region, tmp_paint->region);
2694 cairo_region_translate (region, -window->abs_x, -window->abs_y);
2695 cairo_region_intersect (region, paint->region);
2697 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (region))
2701 /* Remove flushed region from the implicit paint */
2702 cairo_region_subtract (paint->region, region);
2704 /* Some regions are valid, push these to window now */
2705 cr = gdk_cairo_create_for_impl (window);
2706 gdk_cairo_region (cr, region);
2708 cairo_set_source_surface (cr, paint->surface, 0, 0);
2709 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2714 cairo_region_destroy (region);
2717 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2719 gdk_window_end_implicit_paint (GdkWindow *window)
2721 GdkWindowPaint *paint;
2723 g_assert (gdk_window_has_impl (window));
2725 g_assert (window->implicit_paint != NULL);
2727 paint = window->implicit_paint;
2729 window->implicit_paint = NULL;
2731 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region))
2735 /* Some regions are valid, push these to window now */
2736 cr = gdk_cairo_create_for_impl (window);
2737 gdk_cairo_region (cr, paint->region);
2739 cairo_set_source_surface (cr, paint->surface, 0, 0);
2740 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2745 cairo_region_destroy (paint->region);
2747 cairo_surface_destroy (paint->surface);
2752 * gdk_window_begin_paint_rect:
2753 * @window: a #GdkWindow
2754 * @rectangle: rectangle you intend to draw to
2756 * A convenience wrapper around gdk_window_begin_paint_region() which
2757 * creates a rectangular region for you. See
2758 * gdk_window_begin_paint_region() for details.
2762 gdk_window_begin_paint_rect (GdkWindow *window,
2763 const GdkRectangle *rectangle)
2765 cairo_region_t *region;
2767 g_return_if_fail (GDK_IS_WINDOW (window));
2769 region = cairo_region_create_rectangle (rectangle);
2770 gdk_window_begin_paint_region (window, region);
2771 cairo_region_destroy (region);
2775 * gdk_window_begin_paint_region:
2776 * @window: a #GdkWindow
2777 * @region: region you intend to draw to
2779 * Indicates that you are beginning the process of redrawing @region.
2780 * A backing store (offscreen buffer) large enough to contain @region
2781 * will be created. The backing store will be initialized with the
2782 * background color or background surface for @window. Then, all
2783 * drawing operations performed on @window will be diverted to the
2784 * backing store. When you call gdk_window_end_paint(), the backing
2785 * store will be copied to @window, making it visible onscreen. Only
2786 * the part of @window contained in @region will be modified; that is,
2787 * drawing operations are clipped to @region.
2789 * The net result of all this is to remove flicker, because the user
2790 * sees the finished product appear all at once when you call
2791 * gdk_window_end_paint(). If you draw to @window directly without
2792 * calling gdk_window_begin_paint_region(), the user may see flicker
2793 * as individual drawing operations are performed in sequence. The
2794 * clipping and background-initializing features of
2795 * gdk_window_begin_paint_region() are conveniences for the
2796 * programmer, so you can avoid doing that work yourself.
2798 * When using GTK+, the widget system automatically places calls to
2799 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
2800 * emissions of the expose_event signal. That is, if you're writing an
2801 * expose event handler, you can assume that the exposed area in
2802 * #GdkEventExpose has already been cleared to the window background,
2803 * is already set as the clip region, and already has a backing store.
2804 * Therefore in most cases, application code need not call
2805 * gdk_window_begin_paint_region(). (You can disable the automatic
2806 * calls around expose events on a widget-by-widget basis by calling
2807 * gtk_widget_set_double_buffered().)
2809 * If you call this function multiple times before calling the
2810 * matching gdk_window_end_paint(), the backing stores are pushed onto
2811 * a stack. gdk_window_end_paint() copies the topmost backing store
2812 * onscreen, subtracts the topmost region from all other regions in
2813 * the stack, and pops the stack. All drawing operations affect only
2814 * the topmost backing store in the stack. One matching call to
2815 * gdk_window_end_paint() is required for each call to
2816 * gdk_window_begin_paint_region().
2820 gdk_window_begin_paint_region (GdkWindow *window,
2821 const cairo_region_t *region)
2823 #ifdef USE_BACKING_STORE
2824 GdkRectangle clip_box;
2825 GdkWindowPaint *paint, *implicit_paint;
2826 GdkWindow *impl_window;
2829 g_return_if_fail (GDK_IS_WINDOW (window));
2831 if (GDK_WINDOW_DESTROYED (window))
2834 if (GDK_IS_PAINTABLE (window->impl))
2836 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
2838 if (iface->begin_paint_region)
2839 iface->begin_paint_region ((GdkPaintable*)window->impl, window, region);
2844 impl_window = gdk_window_get_impl_window (window);
2845 implicit_paint = impl_window->implicit_paint;
2847 paint = g_new (GdkWindowPaint, 1);
2848 paint->region = cairo_region_copy (region);
2850 cairo_region_intersect (paint->region, window->clip_region_with_children);
2851 cairo_region_get_extents (paint->region, &clip_box);
2853 cairo_region_translate (paint->region, window->abs_x, window->abs_y);
2855 /* Mark the region as valid on the implicit paint */
2858 cairo_region_union (implicit_paint->region, paint->region);
2860 /* Convert back to normal coords */
2861 cairo_region_translate (paint->region, -window->abs_x, -window->abs_y);
2865 paint->uses_implicit = TRUE;
2866 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
2867 window->abs_x + clip_box.x,
2868 window->abs_y + clip_box.y,
2869 MAX (clip_box.width, 1),
2870 MAX (clip_box.height, 1));
2874 paint->uses_implicit = FALSE;
2875 paint->surface = gdk_window_create_similar_surface (window,
2876 gdk_window_get_content (window),
2877 MAX (clip_box.width, 1),
2878 MAX (clip_box.height, 1));
2880 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
2882 for (list = window->paint_stack; list != NULL; list = list->next)
2884 GdkWindowPaint *tmp_paint = list->data;
2886 cairo_region_subtract (tmp_paint->region, paint->region);
2889 window->paint_stack = g_slist_prepend (window->paint_stack, paint);
2891 if (!cairo_region_is_empty (paint->region))
2893 gdk_window_clear_backing_region (window,
2897 #endif /* USE_BACKING_STORE */
2901 * gdk_window_end_paint:
2902 * @window: a #GdkWindow
2904 * Indicates that the backing store created by the most recent call to
2905 * gdk_window_begin_paint_region() should be copied onscreen and
2906 * deleted, leaving the next-most-recent backing store or no backing
2907 * store at all as the active paint region. See
2908 * gdk_window_begin_paint_region() for full details. It is an error to
2909 * call this function without a matching
2910 * gdk_window_begin_paint_region() first.
2914 gdk_window_end_paint (GdkWindow *window)
2916 #ifdef USE_BACKING_STORE
2917 GdkWindow *composited;
2918 GdkWindowPaint *paint;
2919 GdkRectangle clip_box;
2920 cairo_region_t *full_clip;
2922 g_return_if_fail (GDK_IS_WINDOW (window));
2924 if (GDK_WINDOW_DESTROYED (window))
2927 if (GDK_IS_PAINTABLE (window->impl))
2929 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
2931 if (iface->end_paint)
2932 iface->end_paint ((GdkPaintable*)window->impl);
2936 if (window->paint_stack == NULL)
2938 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
2942 paint = window->paint_stack->data;
2944 window->paint_stack = g_slist_delete_link (window->paint_stack,
2945 window->paint_stack);
2947 cairo_region_get_extents (paint->region, &clip_box);
2949 if (!paint->uses_implicit)
2953 gdk_window_flush_outstanding_moves (window);
2955 full_clip = cairo_region_copy (window->clip_region_with_children);
2956 cairo_region_intersect (full_clip, paint->region);
2958 cr = gdk_cairo_create (window);
2959 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2960 cairo_set_source_surface (cr, paint->surface, 0, 0);
2961 gdk_cairo_region (cr, full_clip);
2965 cairo_region_destroy (full_clip);
2968 cairo_surface_destroy (paint->surface);
2969 cairo_region_destroy (paint->region);
2972 /* find a composited window in our hierarchy to signal its
2973 * parent to redraw, calculating the clip box as we go...
2975 * stop if parent becomes NULL since then we'd have nowhere
2976 * to draw (ie: 'composited' will always be non-NULL here).
2978 for (composited = window;
2980 composited = composited->parent)
2982 clip_box.x += composited->x;
2983 clip_box.y += composited->y;
2984 clip_box.width = MIN (clip_box.width, composited->parent->width - clip_box.x);
2985 clip_box.height = MIN (clip_box.height, composited->parent->height - clip_box.y);
2987 if (composited->composited)
2989 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
2994 #endif /* USE_BACKING_STORE */
2998 gdk_window_free_paint_stack (GdkWindow *window)
3000 if (window->paint_stack)
3002 GSList *tmp_list = window->paint_stack;
3006 GdkWindowPaint *paint = tmp_list->data;
3008 if (tmp_list == window->paint_stack)
3009 cairo_surface_destroy (paint->surface);
3011 cairo_region_destroy (paint->region);
3014 tmp_list = tmp_list->next;
3017 g_slist_free (window->paint_stack);
3018 window->paint_stack = NULL;
3023 do_move_region_bits_on_impl (GdkWindow *impl_window,
3024 cairo_region_t *dest_region, /* In impl window coords */
3027 GdkWindowImplClass *impl_class;
3029 impl_class = GDK_WINDOW_IMPL_GET_CLASS (impl_window->impl);
3031 impl_class->translate (impl_window, dest_region, dx, dy);
3034 static GdkWindowRegionMove *
3035 gdk_window_region_move_new (cairo_region_t *region,
3038 GdkWindowRegionMove *move;
3040 move = g_slice_new (GdkWindowRegionMove);
3041 move->dest_region = cairo_region_copy (region);
3049 gdk_window_region_move_free (GdkWindowRegionMove *move)
3051 cairo_region_destroy (move->dest_region);
3052 g_slice_free (GdkWindowRegionMove, move);
3056 append_move_region (GdkWindow *impl_window,
3057 cairo_region_t *new_dest_region,
3060 GdkWindowRegionMove *move, *old_move;
3061 cairo_region_t *new_total_region, *old_total_region;
3062 cairo_region_t *source_overlaps_destination;
3063 cairo_region_t *non_overwritten;
3064 gboolean added_move;
3067 if (cairo_region_is_empty (new_dest_region))
3070 /* In principle this could just append the move to the list of outstanding
3071 moves that will be replayed before drawing anything when we're handling
3072 exposes. However, we'd like to do a bit better since its commonly the case
3073 that we get multiple copies where A is copied to B and then B is copied
3074 to C, and we'd like to express this as a simple copy A to C operation. */
3076 /* We approach this by taking the new move and pushing it ahead of moves
3077 starting at the end of the list and stopping when its not safe to do so.
3078 It's not safe to push past a move if either the source of the new move
3079 is in the destination of the old move, or if the destination of the new
3080 move is in the source of the new move, or if the destination of the new
3081 move overlaps the destination of the old move. We simplify this by
3082 just comparing the total regions (src + dest) */
3083 new_total_region = cairo_region_copy (new_dest_region);
3084 cairo_region_translate (new_total_region, -dx, -dy);
3085 cairo_region_union (new_total_region, new_dest_region);
3088 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3093 old_total_region = cairo_region_copy (old_move->dest_region);
3094 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3095 cairo_region_union (old_total_region, old_move->dest_region);
3097 cairo_region_intersect (old_total_region, new_total_region);
3098 /* If these regions intersect then its not safe to push the
3099 new region before the old one */
3100 if (!cairo_region_is_empty (old_total_region))
3102 /* The area where the new moves source overlaps the old ones
3104 source_overlaps_destination = cairo_region_copy (new_dest_region);
3105 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3106 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3107 cairo_region_translate (source_overlaps_destination, dx, dy);
3109 /* We can do all sort of optimizations here, but to do things safely it becomes
3110 quite complicated. However, a very common case is that you copy something first,
3111 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3112 in the same direction). We'd like to detect this case and optimize it to one
3114 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3116 /* This means we might be able to replace the old move and the new one
3117 with the new one read from the old ones source, and a second copy of
3118 the non-overwritten parts of the old move. However, such a split
3119 is only valid if the source in the old move isn't overwritten
3120 by the destination of the new one */
3122 /* the new destination of old move if split is ok: */
3123 non_overwritten = cairo_region_copy (old_move->dest_region);
3124 cairo_region_subtract (non_overwritten, new_dest_region);
3125 /* move to source region */
3126 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3128 cairo_region_intersect (non_overwritten, new_dest_region);
3129 if (cairo_region_is_empty (non_overwritten))
3132 move = gdk_window_region_move_new (new_dest_region,
3136 impl_window->outstanding_moves =
3137 g_list_insert_before (impl_window->outstanding_moves,
3139 cairo_region_subtract (old_move->dest_region, new_dest_region);
3141 cairo_region_destroy (non_overwritten);
3144 cairo_region_destroy (source_overlaps_destination);
3145 cairo_region_destroy (old_total_region);
3148 cairo_region_destroy (old_total_region);
3151 cairo_region_destroy (new_total_region);
3155 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3158 impl_window->outstanding_moves =
3159 g_list_prepend (impl_window->outstanding_moves,
3162 impl_window->outstanding_moves =
3163 g_list_insert_before (impl_window->outstanding_moves,
3168 /* Moves bits and update area by dx/dy in impl window.
3169 Takes ownership of region to avoid copy (because we may change it) */
3171 move_region_on_impl (GdkWindow *impl_window,
3172 cairo_region_t *region, /* In impl window coords */
3175 if ((dx == 0 && dy == 0) ||
3176 cairo_region_is_empty (region))
3178 cairo_region_destroy (region);
3182 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3184 /* Move any old invalid regions in the copy source area by dx/dy */
3185 if (impl_window->update_area)
3187 cairo_region_t *update_area;
3189 update_area = cairo_region_copy (region);
3191 /* Convert from target to source */
3192 cairo_region_translate (update_area, -dx, -dy);
3193 cairo_region_intersect (update_area, impl_window->update_area);
3194 /* We only copy the area, so keep the old update area invalid.
3195 It would be safe to remove it too, as code that uses
3196 move_region_on_impl generally also invalidate the source
3197 area. However, it would just use waste cycles. */
3200 cairo_region_translate (update_area, dx, dy);
3201 cairo_region_union (impl_window->update_area, update_area);
3203 /* This area of the destination is now invalid,
3204 so no need to copy to it. */
3205 cairo_region_subtract (region, update_area);
3207 cairo_region_destroy (update_area);
3210 /* If we're currently exposing this window, don't copy to this
3211 destination, as it will be overdrawn when the expose is done,
3212 instead invalidate it and repaint later. */
3213 if (impl_window->implicit_paint)
3215 GdkWindowPaint *implicit_paint = impl_window->implicit_paint;
3216 cairo_region_t *exposing;
3218 exposing = cairo_region_copy (implicit_paint->region);
3219 cairo_region_intersect (exposing, region);
3220 cairo_region_subtract (region, exposing);
3222 impl_window_add_update_area (impl_window, exposing);
3223 cairo_region_destroy (exposing);
3226 append_move_region (impl_window, region, dx, dy);
3228 cairo_region_destroy (region);
3231 /* Flushes all outstanding changes to the window, call this
3232 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3235 gdk_window_flush_outstanding_moves (GdkWindow *window)
3237 GdkWindow *impl_window;
3238 GList *l, *outstanding;
3239 GdkWindowRegionMove *move;
3241 impl_window = gdk_window_get_impl_window (window);
3242 outstanding = impl_window->outstanding_moves;
3243 impl_window->outstanding_moves = NULL;
3245 for (l = outstanding; l != NULL; l = l->next)
3249 do_move_region_bits_on_impl (impl_window,
3250 move->dest_region, move->dx, move->dy);
3252 gdk_window_region_move_free (move);
3255 g_list_free (outstanding);
3260 * @window: a #GdkWindow
3262 * Flush all outstanding cached operations on a window, leaving the
3263 * window in a state which reflects all that has been drawn before.
3265 * Gdk uses multiple kinds of caching to get better performance and
3266 * nicer drawing. For instance, during exposes all paints to a window
3267 * using double buffered rendering are keep on a surface until the last
3268 * window has been exposed. It also delays window moves/scrolls until
3269 * as long as possible until next update to avoid tearing when moving
3272 * Normally this should be completely invisible to applications, as
3273 * we automatically flush the windows when required, but this might
3274 * be needed if you for instance mix direct native drawing with
3275 * gdk drawing. For Gtk widgets that don't use double buffering this
3276 * will be called automatically before sending the expose event.
3281 gdk_window_flush (GdkWindow *window)
3283 gdk_window_flush_outstanding_moves (window);
3284 gdk_window_flush_implicit_paint (window);
3287 /* If we're about to move/resize or otherwise change the
3288 * hierarchy of a client side window in an impl and we're
3289 * called from an expose event handler then we need to
3290 * flush any already painted parts of the implicit paint
3291 * that are not part of the current paint, as these may
3292 * be used when scrolling or may overdraw the changes
3293 * caused by the hierarchy change.
3296 gdk_window_flush_if_exposing (GdkWindow *window)
3298 GdkWindow *impl_window;
3300 impl_window = gdk_window_get_impl_window (window);
3302 /* If we're in an implicit paint (i.e. in an expose handler, flush
3303 all the already finished exposes to get things to an uptodate state. */
3304 if (impl_window->implicit_paint)
3305 gdk_window_flush (window);
3310 gdk_window_flush_recursive_helper (GdkWindow *window,
3311 GdkWindowImpl *impl)
3316 for (l = window->children; l != NULL; l = l->next)
3320 if (child->impl == impl)
3321 /* Same impl, ignore */
3322 gdk_window_flush_recursive_helper (child, impl);
3324 gdk_window_flush_recursive (child);
3329 gdk_window_flush_recursive (GdkWindow *window)
3331 gdk_window_flush (window);
3332 gdk_window_flush_recursive_helper (window, window->impl);
3336 * gdk_window_get_clip_region:
3337 * @window: a #GdkWindow
3339 * Computes the region of a window that potentially can be written
3340 * to by drawing primitives. This region may not take into account
3341 * other factors such as if the window is obscured by other windows,
3342 * but no area outside of this region will be affected by drawing
3345 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3346 * when you are done.
3349 gdk_window_get_clip_region (GdkWindow *window)
3351 cairo_region_t *result;
3353 g_return_val_if_fail (GDK_WINDOW (window), NULL);
3355 result = cairo_region_copy (window->clip_region);
3357 if (window->paint_stack)
3359 cairo_region_t *paint_region = cairo_region_create ();
3360 GSList *tmp_list = window->paint_stack;
3364 GdkWindowPaint *paint = tmp_list->data;
3366 cairo_region_union (paint_region, paint->region);
3368 tmp_list = tmp_list->next;
3371 cairo_region_intersect (result, paint_region);
3372 cairo_region_destroy (paint_region);
3379 * gdk_window_get_visible_region:
3380 * @window: a #GdkWindow
3382 * Computes the region of the @window that is potentially visible.
3383 * This does not necessarily take into account if the window is
3384 * obscured by other windows, but no area outside of this region
3387 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3388 * when you are done.
3391 gdk_window_get_visible_region (GdkWindow *window)
3393 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3395 return cairo_region_copy (window->clip_region);
3399 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint, int x_offset_cairo, int y_offset_cairo)
3401 GdkWindow *bg_window;
3402 cairo_pattern_t *pattern = NULL;
3403 int x_offset = 0, y_offset = 0;
3406 cr = cairo_create (paint->surface);
3408 for (bg_window = window; bg_window; bg_window = bg_window->parent)
3410 pattern = gdk_window_get_background_pattern (bg_window);
3414 x_offset += bg_window->x;
3415 y_offset += bg_window->y;
3420 cairo_translate (cr, -x_offset, -y_offset);
3421 cairo_set_source (cr, pattern);
3422 cairo_translate (cr, x_offset, y_offset);
3425 cairo_set_source_rgb (cr, 0, 0, 0);
3431 gdk_window_clear_backing_region (GdkWindow *window,
3432 cairo_region_t *region)
3434 GdkWindowPaint *paint = window->paint_stack->data;
3435 cairo_region_t *clip;
3436 GdkRectangle clipbox;
3439 if (GDK_WINDOW_DESTROYED (window))
3442 cr = setup_backing_rect (window, paint, 0, 0);
3444 clip = cairo_region_copy (paint->region);
3445 cairo_region_intersect (clip, region);
3446 cairo_region_get_extents (clip, &clipbox);
3448 gdk_cairo_region (cr, clip);
3453 cairo_region_destroy (clip);
3457 gdk_window_clear_backing_region_direct (GdkWindow *window,
3458 cairo_region_t *region)
3460 GdkWindowPaint paint;
3461 cairo_region_t *clip;
3462 GdkRectangle clipbox;
3465 if (GDK_WINDOW_DESTROYED (window))
3468 paint.surface = _gdk_window_ref_cairo_surface (window);
3470 cr = setup_backing_rect (window, &paint, 0, 0);
3472 clip = cairo_region_copy (window->clip_region_with_children);
3473 cairo_region_intersect (clip, region);
3474 cairo_region_get_extents (clip, &clipbox);
3476 gdk_cairo_region (cr, clip);
3481 cairo_region_destroy (clip);
3482 cairo_surface_destroy (paint.surface);
3487 gdk_window_clear_region_internal (GdkWindow *window,
3488 cairo_region_t *region)
3490 if (window->paint_stack)
3491 gdk_window_clear_backing_region (window, region);
3493 gdk_window_clear_backing_region_direct (window, region);
3497 gdk_window_drop_cairo_surface (GdkWindow *window)
3499 if (window->cairo_surface)
3501 cairo_surface_finish (window->cairo_surface);
3502 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3504 window->cairo_surface = NULL;
3509 gdk_window_cairo_surface_destroy (void *data)
3511 GdkWindow *window = data;
3513 window->cairo_surface = NULL;
3516 static cairo_surface_t *
3517 gdk_window_create_cairo_surface (GdkWindow *window,
3521 cairo_surface_t *surface, *subsurface;
3523 surface = gdk_window_ref_impl_surface (window);
3524 if (gdk_window_has_impl (window))
3527 subsurface = cairo_surface_create_for_rectangle (surface,
3532 cairo_surface_destroy (surface);
3538 _gdk_window_ref_cairo_surface (GdkWindow *window)
3540 cairo_surface_t *surface;
3542 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3544 if (window->paint_stack)
3546 GdkWindowPaint *paint = window->paint_stack->data;
3548 surface = paint->surface;
3549 cairo_surface_reference (surface);
3554 /* This will be drawing directly to the window, so flush implicit paint */
3555 gdk_window_flush (window);
3557 if (!window->cairo_surface)
3559 window->cairo_surface = gdk_window_create_cairo_surface (window,
3563 if (window->cairo_surface)
3565 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3566 window, gdk_window_cairo_surface_destroy);
3570 cairo_surface_reference (window->cairo_surface);
3572 surface = window->cairo_surface;
3580 * @window: a #GdkWindow
3582 * Creates a Cairo context for drawing to @window.
3585 * Note that calling cairo_reset_clip() on the resulting #cairo_t will
3586 * produce undefined results, so avoid it at all costs.
3589 * Return value: A newly created Cairo context. Free with
3590 * cairo_destroy() when you are done drawing.
3595 gdk_cairo_create (GdkWindow *window)
3597 cairo_surface_t *surface;
3600 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3602 surface = _gdk_window_ref_cairo_surface (window);
3603 cr = cairo_create (surface);
3605 if (!window->paint_stack)
3607 gdk_cairo_region (cr, window->clip_region_with_children);
3612 GdkWindowPaint *paint = window->paint_stack->data;
3614 /* Only needs to clip to region if piggybacking
3615 on an implicit paint */
3616 if (paint->uses_implicit)
3618 gdk_cairo_region (cr, paint->region);
3623 cairo_surface_destroy (surface);
3628 /* Code for dirty-region queueing
3630 static GSList *update_windows = NULL;
3631 static guint update_idle = 0;
3632 static gboolean debug_updates = FALSE;
3634 static inline gboolean
3635 gdk_window_is_ancestor (GdkWindow *window,
3636 GdkWindow *ancestor)
3640 GdkWindow *parent = window->parent;
3642 if (parent == ancestor)
3652 gdk_window_add_update_window (GdkWindow *window)
3655 GSList *prev = NULL;
3656 gboolean has_ancestor_in_list = FALSE;
3658 for (tmp = update_windows; tmp; tmp = tmp->next)
3660 GdkWindow *parent = window->parent;
3662 /* check if tmp is an ancestor of "window"; if it is, set a
3663 * flag indicating that all following windows are either
3664 * children of "window" or from a differen hierarchy
3666 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3667 has_ancestor_in_list = TRUE;
3669 /* insert in reverse stacking order when adding around siblings,
3670 * so processing updates properly paints over lower stacked windows
3672 if (parent == GDK_WINDOW (tmp->data)->parent)
3674 gint index = g_list_index (parent->children, window);
3675 for (; tmp && parent == GDK_WINDOW (tmp->data)->parent; tmp = tmp->next)
3677 gint sibling_index = g_list_index (parent->children, tmp->data);
3678 if (index > sibling_index)
3682 /* here, tmp got advanced past all lower stacked siblings */
3683 tmp = g_slist_prepend (tmp, window);
3687 update_windows = tmp;
3691 /* if "window" has an ancestor in the list and tmp is one of
3692 * "window's" children, insert "window" before tmp
3694 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3696 tmp = g_slist_prepend (tmp, window);
3701 update_windows = tmp;
3705 /* if we're at the end of the list and had an ancestor it it,
3706 * append to the list
3708 if (! tmp->next && has_ancestor_in_list)
3710 tmp = g_slist_append (tmp, window);
3717 /* if all above checks failed ("window" is from a different
3718 * hierarchy than what is already in the list) or the list is
3721 update_windows = g_slist_prepend (update_windows, window);
3725 gdk_window_remove_update_window (GdkWindow *window)
3727 update_windows = g_slist_remove (update_windows, window);
3731 gdk_window_update_idle (gpointer data)
3733 gdk_window_process_all_updates ();
3739 gdk_window_is_toplevel_frozen (GdkWindow *window)
3741 GdkWindow *toplevel;
3743 toplevel = gdk_window_get_toplevel (window);
3745 return toplevel->update_and_descendants_freeze_count > 0;
3749 gdk_window_schedule_update (GdkWindow *window)
3752 (window->update_freeze_count ||
3753 gdk_window_is_toplevel_frozen (window)))
3758 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
3759 gdk_window_update_idle,
3764 _gdk_window_process_updates_recurse (GdkWindow *window,
3765 cairo_region_t *expose_region)
3768 cairo_region_t *child_region;
3770 GList *l, *children;
3772 if (cairo_region_is_empty (expose_region))
3775 if (gdk_window_is_offscreen (window->impl_window) &&
3776 window == window->impl_window)
3777 _gdk_window_add_damage ((GdkWindow *) window->impl_window, expose_region);
3779 /* Make this reentrancy safe for expose handlers freeing windows */
3780 children = g_list_copy (window->children);
3781 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3783 /* Iterate over children, starting at topmost */
3784 for (l = children; l != NULL; l = l->next)
3788 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3791 /* Ignore offscreen children, as they don't draw in their parent and
3792 * don't take part in the clipping */
3793 if (gdk_window_is_offscreen (child))
3798 r.width = child->width;
3799 r.height = child->height;
3801 child_region = cairo_region_create_rectangle (&r);
3804 /* Adjust shape region to parent window coords */
3805 cairo_region_translate (child->shape, child->x, child->y);
3806 cairo_region_intersect (child_region, child->shape);
3807 cairo_region_translate (child->shape, -child->x, -child->y);
3810 if (child->impl == window->impl)
3812 /* Client side child, expose */
3813 cairo_region_intersect (child_region, expose_region);
3814 cairo_region_subtract (expose_region, child_region);
3815 cairo_region_translate (child_region, -child->x, -child->y);
3816 _gdk_window_process_updates_recurse ((GdkWindow *)child, child_region);
3820 /* Native child, just remove area from expose region */
3821 cairo_region_subtract (expose_region, child_region);
3823 cairo_region_destroy (child_region);
3826 g_list_foreach (children, (GFunc)g_object_unref, NULL);
3827 g_list_free (children);
3829 if (!cairo_region_is_empty (expose_region) &&
3832 if (window->event_mask & GDK_EXPOSURE_MASK)
3836 event.expose.type = GDK_EXPOSE;
3837 event.expose.window = g_object_ref (window);
3838 event.expose.send_event = FALSE;
3839 event.expose.count = 0;
3840 event.expose.region = expose_region;
3841 cairo_region_get_extents (expose_region, &event.expose.area);
3843 _gdk_event_emit (&event);
3845 g_object_unref (window);
3847 else if (window->window_type != GDK_WINDOW_FOREIGN)
3849 /* No exposure mask set, so nothing will be drawn, the
3850 * app relies on the background being what it specified
3851 * for the window. So, we need to clear this manually.
3853 * For foreign windows if expose is not set that generally
3854 * means some other client paints them, so don't clear
3857 * We use begin/end_paint around the clear so that we can
3858 * piggyback on the implicit paint */
3860 gdk_window_begin_paint_region (window, expose_region);
3861 gdk_window_clear_region_internal (window, expose_region);
3862 gdk_window_end_paint (window);
3867 /* Process and remove any invalid area on the native window by creating
3868 * expose events for the window and all non-native descendants.
3869 * Also processes any outstanding moves on the window before doing
3870 * any drawing. Note that its possible to have outstanding moves without
3871 * any invalid area as we use the update idle mechanism to coalesce
3872 * multiple moves as well as multiple invalidations.
3875 gdk_window_process_updates_internal (GdkWindow *window)
3877 GdkWindowImplClass *impl_class;
3878 gboolean save_region = FALSE;
3879 GdkRectangle clip_box;
3881 /* Ensure the window lives while updating it */
3882 g_object_ref (window);
3884 /* If an update got queued during update processing, we can get a
3885 * window in the update queue that has an empty update_area.
3888 if (window->update_area)
3890 cairo_region_t *update_area = window->update_area;
3891 window->update_area = NULL;
3893 if (gdk_window_is_viewable (window))
3895 cairo_region_t *expose_region;
3896 gboolean end_implicit;
3898 /* Clip to part visible in toplevel */
3899 cairo_region_intersect (update_area, window->clip_region);
3903 /* Make sure we see the red invalid area before redrawing. */
3904 gdk_display_sync (gdk_window_get_display (window));
3908 /* At this point we will be completely redrawing all of update_area.
3909 * If we have any outstanding moves that end up moving stuff inside
3910 * this area we don't actually need to move that as that part would
3911 * be overdrawn by the expose anyway. So, in order to copy less data
3912 * we remove these areas from the outstanding moves.
3914 if (window->outstanding_moves)
3916 GdkWindowRegionMove *move;
3917 cairo_region_t *remove;
3920 remove = cairo_region_copy (update_area);
3921 /* We iterate backwards, starting from the state that would be
3922 if we had applied all the moves. */
3923 for (l = g_list_last (window->outstanding_moves); l != NULL; l = prev)
3928 /* Don't need this area */
3929 cairo_region_subtract (move->dest_region, remove);
3931 /* However if any of the destination we do need has a source
3932 in the updated region we do need that as a destination for
3933 the earlier moves */
3934 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
3935 cairo_region_subtract (remove, move->dest_region);
3937 if (cairo_region_is_empty (move->dest_region))
3939 gdk_window_region_move_free (move);
3940 window->outstanding_moves =
3941 g_list_delete_link (window->outstanding_moves, l);
3943 else /* move back */
3944 cairo_region_translate (move->dest_region, move->dx, move->dy);
3946 cairo_region_destroy (remove);
3949 /* By now we a set of window moves that should be applied, and then
3950 * an update region that should be repainted. A trivial implementation
3951 * would just do that in order, however in order to get nicer drawing
3952 * we do some tricks:
3954 * First of all, each subwindow expose may be double buffered by
3955 * itself (depending on widget setting) via
3956 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
3957 * creating a single surface the size of the invalid area on the
3958 * native window which all the individual normal paints will draw
3959 * into. This way in the normal case there will be only one surface
3960 * allocated and only once surface draw done for all the windows
3961 * in this native window.
3962 * There are a couple of reasons this may fail, for instance, some
3963 * backends (like quartz) do its own double buffering, so we disable
3964 * gdk double buffering there. Secondly, some subwindow could be
3965 * non-double buffered and draw directly to the window outside a
3966 * begin/end_paint pair. That will be lead to a gdk_window_flush
3967 * which immediately executes all outstanding moves and paints+removes
3968 * the implicit paint (further paints will allocate their own surfaces).
3970 * Secondly, in the case of implicit double buffering we expose all
3971 * the child windows into the implicit surface before we execute
3972 * the outstanding moves. This way we minimize the time between
3973 * doing the moves and rendering the new update area, thus minimizing
3974 * flashing. Of course, if any subwindow is non-double buffered we
3975 * well flush earlier than that.
3977 * Thirdly, after having done the outstanding moves we queue an
3978 * "antiexpose" on the area that will be drawn by the expose, which
3979 * means that any invalid region on the native window side before
3980 * the first expose drawing operation will be discarded, as it
3981 * has by then been overdrawn with valid data. This means we can
3982 * avoid doing the unnecessary repaint any outstanding expose events.
3985 cairo_region_get_extents (update_area, &clip_box);
3986 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
3987 expose_region = cairo_region_copy (update_area);
3988 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
3991 /* Rendering is not double buffered by gdk, do outstanding
3992 * moves and queue antiexposure immediately. No need to do
3994 gdk_window_flush_outstanding_moves (window);
3995 save_region = impl_class->queue_antiexpose (window, update_area);
3997 /* Render the invalid areas to the implicit paint, by sending exposes.
3998 * May flush if non-double buffered widget draw. */
3999 impl_class->process_updates_recurse (window, expose_region);
4003 /* Do moves right before exposes are rendered to the window */
4004 gdk_window_flush_outstanding_moves (window);
4006 /* By this time we know that any outstanding expose for this
4007 * area is invalid and we can avoid it, so queue an antiexpose.
4008 * we have already started drawing to the window, so it would
4009 * be to late to anti-expose now. Since this is merely an
4010 * optimization we just avoid doing it at all in that case.
4012 if (window->implicit_paint != NULL && !window->implicit_paint->flushed)
4013 save_region = impl_class->queue_antiexpose (window, update_area);
4015 gdk_window_end_implicit_paint (window);
4017 cairo_region_destroy (expose_region);
4020 cairo_region_destroy (update_area);
4023 if (window->outstanding_moves)
4025 /* Flush any outstanding moves, may happen if we moved a window but got
4026 no actual invalid area */
4027 gdk_window_flush_outstanding_moves (window);
4030 g_object_unref (window);
4034 flush_all_displays (void)
4036 GSList *displays, *l;
4038 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4039 for (l = displays; l; l = l->next)
4040 gdk_display_flush (l->data);
4042 g_slist_free (displays);
4046 before_process_all_updates (void)
4048 GSList *displays, *l;
4049 GdkDisplayClass *display_class;
4051 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4052 display_class = GDK_DISPLAY_GET_CLASS (displays->data);
4053 for (l = displays; l; l = l->next)
4054 display_class->before_process_all_updates (l->data);
4056 g_slist_free (displays);
4060 after_process_all_updates (void)
4062 GSList *displays, *l;
4063 GdkDisplayClass *display_class;
4065 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4066 display_class = GDK_DISPLAY_GET_CLASS (displays->data);
4067 for (l = displays; l; l = l->next)
4068 display_class->after_process_all_updates (l->data);
4070 g_slist_free (displays);
4073 /* Currently it is not possible to override
4074 * gdk_window_process_all_updates in the same manner as
4075 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4076 * by implementing the GdkPaintable interface. If in the future a
4077 * backend would need this, the right solution would be to add a
4078 * method to GdkDisplay that can be optionally
4079 * NULL. gdk_window_process_all_updates can then walk the list of open
4080 * displays and call the mehod.
4084 * gdk_window_process_all_updates:
4086 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4087 * in the application.
4091 gdk_window_process_all_updates (void)
4093 GSList *old_update_windows = update_windows;
4094 GSList *tmp_list = update_windows;
4095 static gboolean in_process_all_updates = FALSE;
4096 static gboolean got_recursive_update = FALSE;
4098 if (in_process_all_updates)
4100 /* We can't do this now since that would recurse, so
4101 delay it until after the recursion is done. */
4102 got_recursive_update = TRUE;
4107 in_process_all_updates = TRUE;
4108 got_recursive_update = FALSE;
4111 g_source_remove (update_idle);
4113 update_windows = NULL;
4116 before_process_all_updates ();
4118 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4122 GdkWindow *window = tmp_list->data;
4124 if (!GDK_WINDOW_DESTROYED (window))
4126 if (window->update_freeze_count ||
4127 gdk_window_is_toplevel_frozen (window))
4128 gdk_window_add_update_window (window);
4130 gdk_window_process_updates_internal (window);
4133 g_object_unref (window);
4134 tmp_list = tmp_list->next;
4137 g_slist_free (old_update_windows);
4139 flush_all_displays ();
4141 after_process_all_updates ();
4143 in_process_all_updates = FALSE;
4145 /* If we ignored a recursive call, schedule a
4146 redraw now so that it eventually happens,
4147 otherwise we could miss an update if nothing
4148 else schedules an update. */
4149 if (got_recursive_update && !update_idle)
4151 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4152 gdk_window_update_idle,
4157 * gdk_window_process_updates:
4158 * @window: a #GdkWindow
4159 * @update_children: whether to also process updates for child windows
4161 * Sends one or more expose events to @window. The areas in each
4162 * expose event will cover the entire update area for the window (see
4163 * gdk_window_invalidate_region() for details). Normally GDK calls
4164 * gdk_window_process_all_updates() on your behalf, so there's no
4165 * need to call this function unless you want to force expose events
4166 * to be delivered immediately and synchronously (vs. the usual
4167 * case, where GDK delivers them in an idle handler). Occasionally
4168 * this is useful to produce nicer scrolling behavior, for example.
4172 gdk_window_process_updates (GdkWindow *window,
4173 gboolean update_children)
4175 GdkWindow *impl_window;
4177 g_return_if_fail (GDK_IS_WINDOW (window));
4179 if (GDK_WINDOW_DESTROYED (window))
4182 /* Make sure the window lives during the expose callouts */
4183 g_object_ref (window);
4185 impl_window = gdk_window_get_impl_window (window);
4186 if ((impl_window->update_area ||
4187 impl_window->outstanding_moves) &&
4188 !impl_window->update_freeze_count &&
4189 !gdk_window_is_toplevel_frozen (window) &&
4191 /* Don't recurse into process_updates_internal, we'll
4192 * do the update later when idle instead. */
4193 impl_window->implicit_paint == NULL)
4195 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4196 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4199 if (update_children)
4201 /* process updates in reverse stacking order so composition or
4202 * painting over achieves the desired effect for offscreen windows
4204 GList *node, *children;
4206 children = g_list_copy (window->children);
4207 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4209 for (node = g_list_last (children); node; node = node->prev)
4211 gdk_window_process_updates (node->data, TRUE);
4212 g_object_unref (node->data);
4215 g_list_free (children);
4218 g_object_unref (window);
4222 gdk_window_invalidate_rect_full (GdkWindow *window,
4223 const GdkRectangle *rect,
4224 gboolean invalidate_children,
4227 GdkRectangle window_rect;
4228 cairo_region_t *region;
4230 g_return_if_fail (GDK_IS_WINDOW (window));
4232 if (GDK_WINDOW_DESTROYED (window))
4235 if (window->input_only || !window->viewable)
4242 window_rect.width = window->width;
4243 window_rect.height = window->height;
4244 rect = &window_rect;
4247 region = cairo_region_create_rectangle (rect);
4248 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4249 cairo_region_destroy (region);
4253 * gdk_window_invalidate_rect:
4254 * @window: a #GdkWindow
4255 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4257 * @invalidate_children: whether to also invalidate child windows
4259 * A convenience wrapper around gdk_window_invalidate_region() which
4260 * invalidates a rectangular region. See
4261 * gdk_window_invalidate_region() for details.
4264 gdk_window_invalidate_rect (GdkWindow *window,
4265 const GdkRectangle *rect,
4266 gboolean invalidate_children)
4268 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4272 draw_ugly_color (GdkWindow *window,
4273 const cairo_region_t *region)
4277 cr = gdk_cairo_create (window);
4278 /* Draw ugly color all over the newly-invalid region */
4279 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4280 gdk_cairo_region (cr, region);
4287 impl_window_add_update_area (GdkWindow *impl_window,
4288 cairo_region_t *region)
4290 if (impl_window->update_area)
4291 cairo_region_union (impl_window->update_area, region);
4294 gdk_window_add_update_window (impl_window);
4295 impl_window->update_area = cairo_region_copy (region);
4296 gdk_window_schedule_update (impl_window);
4300 /* clear_bg controls if the region will be cleared to
4301 * the background pattern if the exposure mask is not
4302 * set for the window, whereas this might not otherwise be
4303 * done (unless necessary to emulate background settings).
4304 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4305 * need to clear the background, such as when exposing the area beneath a
4306 * hidden or moved window, but not when an app requests repaint or when the
4307 * windowing system exposes a newly visible area (because then the windowing
4308 * system has already cleared the area).
4311 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4312 const cairo_region_t *region,
4314 GdkWindowChildFunc child_func,
4317 GdkWindow *impl_window;
4318 cairo_region_t *visible_region;
4321 g_return_if_fail (GDK_IS_WINDOW (window));
4323 if (GDK_WINDOW_DESTROYED (window))
4326 if (window->input_only ||
4327 !window->viewable ||
4328 cairo_region_is_empty (region) ||
4329 window->window_type == GDK_WINDOW_ROOT)
4332 visible_region = gdk_window_get_visible_region (window);
4333 cairo_region_intersect (visible_region, region);
4335 tmp_list = window->children;
4338 GdkWindow *child = tmp_list->data;
4340 if (!child->input_only)
4342 cairo_region_t *child_region;
4343 GdkRectangle child_rect;
4345 child_rect.x = child->x;
4346 child_rect.y = child->y;
4347 child_rect.width = child->width;
4348 child_rect.height = child->height;
4349 child_region = cairo_region_create_rectangle (&child_rect);
4351 /* remove child area from the invalid area of the parent */
4352 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4353 !child->composited &&
4354 !gdk_window_is_offscreen (child))
4355 cairo_region_subtract (visible_region, child_region);
4357 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4359 cairo_region_t *tmp = cairo_region_copy (region);
4361 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4362 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4363 cairo_region_intersect (child_region, tmp);
4365 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4366 child_region, clear_bg, child_func, user_data);
4368 cairo_region_destroy (tmp);
4371 cairo_region_destroy (child_region);
4374 tmp_list = tmp_list->next;
4377 impl_window = gdk_window_get_impl_window (window);
4379 if (!cairo_region_is_empty (visible_region) ||
4380 /* Even if we're not exposing anything, make sure we process
4381 idles for windows with outstanding moves */
4382 (impl_window->outstanding_moves != NULL &&
4383 impl_window->update_area == NULL))
4386 draw_ugly_color (window, region);
4388 /* Convert to impl coords */
4389 cairo_region_translate (visible_region, window->abs_x, window->abs_y);
4391 /* Only invalidate area if app requested expose events or if
4392 we need to clear the area (by request or to emulate background
4393 clearing for non-native windows or native windows with no support
4394 for window backgrounds */
4395 if (window->event_mask & GDK_EXPOSURE_MASK ||
4396 clear_bg == CLEAR_BG_ALL ||
4397 clear_bg == CLEAR_BG_WINCLEARED)
4398 impl_window_add_update_area (impl_window, visible_region);
4401 cairo_region_destroy (visible_region);
4405 * gdk_window_invalidate_maybe_recurse:
4406 * @window: a #GdkWindow
4407 * @region: a #cairo_region_t
4408 * @child_func: (scope call) (allow-none): function to use to decide if to
4409 * recurse to a child, %NULL means never recurse.
4410 * @user_data: data passed to @child_func
4412 * Adds @region to the update area for @window. The update area is the
4413 * region that needs to be redrawn, or "dirty region." The call
4414 * gdk_window_process_updates() sends one or more expose events to the
4415 * window, which together cover the entire update area. An
4416 * application would normally redraw the contents of @window in
4417 * response to those expose events.
4419 * GDK will call gdk_window_process_all_updates() on your behalf
4420 * whenever your program returns to the main loop and becomes idle, so
4421 * normally there's no need to do that manually, you just need to
4422 * invalidate regions that you know should be redrawn.
4424 * The @child_func parameter controls whether the region of
4425 * each child window that intersects @region will also be invalidated.
4426 * Only children for which @child_func returns TRUE will have the area
4430 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4431 const cairo_region_t *region,
4432 GdkWindowChildFunc child_func,
4435 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4436 child_func, user_data);
4440 true_predicate (GdkWindow *window,
4447 gdk_window_invalidate_region_full (GdkWindow *window,
4448 const cairo_region_t *region,
4449 gboolean invalidate_children,
4452 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4453 invalidate_children ?
4454 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4459 * gdk_window_invalidate_region:
4460 * @window: a #GdkWindow
4461 * @region: a #cairo_region_t
4462 * @invalidate_children: %TRUE to also invalidate child windows
4464 * Adds @region to the update area for @window. The update area is the
4465 * region that needs to be redrawn, or "dirty region." The call
4466 * gdk_window_process_updates() sends one or more expose events to the
4467 * window, which together cover the entire update area. An
4468 * application would normally redraw the contents of @window in
4469 * response to those expose events.
4471 * GDK will call gdk_window_process_all_updates() on your behalf
4472 * whenever your program returns to the main loop and becomes idle, so
4473 * normally there's no need to do that manually, you just need to
4474 * invalidate regions that you know should be redrawn.
4476 * The @invalidate_children parameter controls whether the region of
4477 * each child window that intersects @region will also be invalidated.
4478 * If %FALSE, then the update area for child windows will remain
4479 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4480 * fine grained control over which children are invalidated.
4483 gdk_window_invalidate_region (GdkWindow *window,
4484 const cairo_region_t *region,
4485 gboolean invalidate_children)
4487 gdk_window_invalidate_maybe_recurse (window, region,
4488 invalidate_children ?
4489 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4494 * _gdk_window_invalidate_for_expose:
4495 * @window: a #GdkWindow
4496 * @region: a #cairo_region_t
4498 * Adds @region to the update area for @window. The update area is the
4499 * region that needs to be redrawn, or "dirty region." The call
4500 * gdk_window_process_updates() sends one or more expose events to the
4501 * window, which together cover the entire update area. An
4502 * application would normally redraw the contents of @window in
4503 * response to those expose events.
4505 * GDK will call gdk_window_process_all_updates() on your behalf
4506 * whenever your program returns to the main loop and becomes idle, so
4507 * normally there's no need to do that manually, you just need to
4508 * invalidate regions that you know should be redrawn.
4510 * This version of invalidation is used when you recieve expose events
4511 * from the native window system. It exposes the native window, plus
4512 * any non-native child windows (but not native child windows, as those would
4513 * have gotten their own expose events).
4516 _gdk_window_invalidate_for_expose (GdkWindow *window,
4517 cairo_region_t *region)
4519 GdkWindowRegionMove *move;
4520 cairo_region_t *move_region;
4523 /* Any invalidations comming from the windowing system will
4524 be in areas that may be moved by outstanding moves,
4525 so we need to modify the expose region correspondingly,
4526 otherwise we would expose in the wrong place, as the
4527 outstanding moves will be copied before we draw the
4529 for (l = window->outstanding_moves; l != NULL; l = l->next)
4533 /* covert to move source region */
4534 move_region = cairo_region_copy (move->dest_region);
4535 cairo_region_translate (move_region, -move->dx, -move->dy);
4537 /* Move area of region that intersects with move source
4538 by dx, dy of the move*/
4539 cairo_region_intersect (move_region, region);
4540 cairo_region_subtract (region, move_region);
4541 cairo_region_translate (move_region, move->dx, move->dy);
4542 cairo_region_union (region, move_region);
4544 cairo_region_destroy (move_region);
4547 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4548 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4554 * gdk_window_get_update_area:
4555 * @window: a #GdkWindow
4557 * Transfers ownership of the update area from @window to the caller
4558 * of the function. That is, after calling this function, @window will
4559 * no longer have an invalid/dirty region; the update area is removed
4560 * from @window and handed to you. If a window has no update area,
4561 * gdk_window_get_update_area() returns %NULL. You are responsible for
4562 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4564 * Return value: the update area for @window
4567 gdk_window_get_update_area (GdkWindow *window)
4569 GdkWindow *impl_window;
4570 cairo_region_t *tmp_region;
4572 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4574 impl_window = gdk_window_get_impl_window (window);
4576 if (impl_window->update_area)
4578 tmp_region = cairo_region_copy (window->clip_region_with_children);
4579 /* Convert to impl coords */
4580 cairo_region_translate (tmp_region, window->abs_x, window->abs_y);
4581 cairo_region_intersect (tmp_region, impl_window->update_area);
4583 if (cairo_region_is_empty (tmp_region))
4585 cairo_region_destroy (tmp_region);
4590 cairo_region_subtract (impl_window->update_area, tmp_region);
4592 if (cairo_region_is_empty (impl_window->update_area) &&
4593 impl_window->outstanding_moves == NULL)
4595 cairo_region_destroy (impl_window->update_area);
4596 impl_window->update_area = NULL;
4598 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4601 /* Convert from impl coords */
4602 cairo_region_translate (tmp_region, -window->abs_x, -window->abs_y);
4612 * _gdk_window_clear_update_area:
4613 * @window: a #GdkWindow.
4615 * Internal function to clear the update area for a window. This
4616 * is called when the window is hidden or destroyed.
4619 _gdk_window_clear_update_area (GdkWindow *window)
4621 g_return_if_fail (GDK_IS_WINDOW (window));
4623 if (window->update_area)
4625 gdk_window_remove_update_window (window);
4627 cairo_region_destroy (window->update_area);
4628 window->update_area = NULL;
4633 * gdk_window_freeze_updates:
4634 * @window: a #GdkWindow
4636 * Temporarily freezes a window such that it won't receive expose
4637 * events. The window will begin receiving expose events again when
4638 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4639 * has been called more than once, gdk_window_thaw_updates() must be called
4640 * an equal number of times to begin processing exposes.
4643 gdk_window_freeze_updates (GdkWindow *window)
4645 GdkWindow *impl_window;
4647 g_return_if_fail (GDK_IS_WINDOW (window));
4649 impl_window = gdk_window_get_impl_window (window);
4650 impl_window->update_freeze_count++;
4654 * gdk_window_thaw_updates:
4655 * @window: a #GdkWindow
4657 * Thaws a window frozen with gdk_window_freeze_updates().
4660 gdk_window_thaw_updates (GdkWindow *window)
4662 GdkWindow *impl_window;
4664 g_return_if_fail (GDK_IS_WINDOW (window));
4666 impl_window = gdk_window_get_impl_window (window);
4668 g_return_if_fail (impl_window->update_freeze_count > 0);
4670 if (--impl_window->update_freeze_count == 0)
4671 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4675 * gdk_window_freeze_toplevel_updates_libgtk_only:
4676 * @window: a #GdkWindow
4678 * Temporarily freezes a window and all its descendants such that it won't
4679 * receive expose events. The window will begin receiving expose events
4680 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4681 * gdk_window_freeze_toplevel_updates_libgtk_only()
4682 * has been called more than once,
4683 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4684 * an equal number of times to begin processing exposes.
4686 * This function is not part of the GDK public API and is only
4690 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4692 g_return_if_fail (GDK_IS_WINDOW (window));
4693 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4695 window->update_and_descendants_freeze_count++;
4699 * gdk_window_thaw_toplevel_updates_libgtk_only:
4700 * @window: a #GdkWindow
4702 * Thaws a window frozen with
4703 * gdk_window_freeze_toplevel_updates_libgtk_only().
4705 * This function is not part of the GDK public API and is only
4709 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4711 g_return_if_fail (GDK_IS_WINDOW (window));
4712 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4713 g_return_if_fail (window->update_and_descendants_freeze_count > 0);
4715 window->update_and_descendants_freeze_count--;
4717 gdk_window_schedule_update (window);
4721 * gdk_window_set_debug_updates:
4722 * @setting: %TRUE to turn on update debugging
4724 * With update debugging enabled, calls to
4725 * gdk_window_invalidate_region() clear the invalidated region of the
4726 * screen to a noticeable color, and GDK pauses for a short time
4727 * before sending exposes to windows during
4728 * gdk_window_process_updates(). The net effect is that you can see
4729 * the invalid region for each window and watch redraws as they
4730 * occur. This allows you to diagnose inefficiencies in your application.
4732 * In essence, because the GDK rendering model prevents all flicker,
4733 * if you are redrawing the same region 400 times you may never
4734 * notice, aside from noticing a speed problem. Enabling update
4735 * debugging causes GTK to flicker slowly and noticeably, so you can
4736 * see exactly what's being redrawn when, in what order.
4738 * The --gtk-debug=updates command line option passed to GTK+ programs
4739 * enables this debug option at application startup time. That's
4740 * usually more useful than calling gdk_window_set_debug_updates()
4741 * yourself, though you might want to use this function to enable
4742 * updates sometime after application startup time.
4746 gdk_window_set_debug_updates (gboolean setting)
4748 debug_updates = setting;
4752 * gdk_window_constrain_size:
4753 * @geometry: a #GdkGeometry structure
4754 * @flags: a mask indicating what portions of @geometry are set
4755 * @width: desired width of window
4756 * @height: desired height of the window
4757 * @new_width: (out): location to store resulting width
4758 * @new_height: (out): location to store resulting height
4760 * Constrains a desired width and height according to a
4761 * set of geometry hints (such as minimum and maximum size).
4764 gdk_window_constrain_size (GdkGeometry *geometry,
4771 /* This routine is partially borrowed from fvwm.
4773 * Copyright 1993, Robert Nation
4774 * You may use this code for any purpose, as long as the original
4775 * copyright remains in the source code and all documentation
4777 * which in turn borrows parts of the algorithm from uwm
4780 gint min_height = 0;
4781 gint base_width = 0;
4782 gint base_height = 0;
4785 gint max_width = G_MAXINT;
4786 gint max_height = G_MAXINT;
4788 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4790 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4792 base_width = geometry->base_width;
4793 base_height = geometry->base_height;
4794 min_width = geometry->min_width;
4795 min_height = geometry->min_height;
4797 else if (flags & GDK_HINT_BASE_SIZE)
4799 base_width = geometry->base_width;
4800 base_height = geometry->base_height;
4801 min_width = geometry->base_width;
4802 min_height = geometry->base_height;
4804 else if (flags & GDK_HINT_MIN_SIZE)
4806 base_width = geometry->min_width;
4807 base_height = geometry->min_height;
4808 min_width = geometry->min_width;
4809 min_height = geometry->min_height;
4812 if (flags & GDK_HINT_MAX_SIZE)
4814 max_width = geometry->max_width ;
4815 max_height = geometry->max_height;
4818 if (flags & GDK_HINT_RESIZE_INC)
4820 xinc = MAX (xinc, geometry->width_inc);
4821 yinc = MAX (yinc, geometry->height_inc);
4824 /* clamp width and height to min and max values
4826 width = CLAMP (width, min_width, max_width);
4827 height = CLAMP (height, min_height, max_height);
4829 /* shrink to base + N * inc
4831 width = base_width + FLOOR (width - base_width, xinc);
4832 height = base_height + FLOOR (height - base_height, yinc);
4834 /* constrain aspect ratio, according to:
4837 * min_aspect <= -------- <= max_aspect
4841 if (flags & GDK_HINT_ASPECT &&
4842 geometry->min_aspect > 0 &&
4843 geometry->max_aspect > 0)
4847 if (geometry->min_aspect * height > width)
4849 delta = FLOOR (height - width / geometry->min_aspect, yinc);
4850 if (height - delta >= min_height)
4854 delta = FLOOR (height * geometry->min_aspect - width, xinc);
4855 if (width + delta <= max_width)
4860 if (geometry->max_aspect * height < width)
4862 delta = FLOOR (width - height * geometry->max_aspect, xinc);
4863 if (width - delta >= min_width)
4867 delta = FLOOR (width / geometry->max_aspect - height, yinc);
4868 if (height + delta <= max_height)
4877 *new_height = height;
4881 * gdk_window_get_pointer:
4882 * @window: a #GdkWindow
4883 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
4884 * return the X coordinate
4885 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
4886 * return the Y coordinate
4887 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
4890 * Obtains the current pointer position and modifier state.
4891 * The position is given in coordinates relative to the upper left
4892 * corner of @window.
4894 * Return value: (transfer none): the window containing the pointer (as with
4895 * gdk_window_at_pointer()), or %NULL if the window containing the
4896 * pointer isn't known to GDK
4898 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
4901 gdk_window_get_pointer (GdkWindow *window,
4904 GdkModifierType *mask)
4906 GdkDisplay *display;
4908 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4910 display = gdk_window_get_display (window);
4912 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
4916 * gdk_window_get_device_position:
4917 * @window: a #GdkWindow.
4918 * @device: pointer #GdkDevice to query to.
4919 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
4920 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
4921 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
4923 * Obtains the current device position and modifier state.
4924 * The position is given in coordinates relative to the upper left
4925 * corner of @window.
4927 * Return value: (transfer none): The window underneath @device (as with
4928 * gdk_device_get_window_at_position()), or %NULL if the window is not known to GDK.
4933 gdk_window_get_device_position (GdkWindow *window,
4937 GdkModifierType *mask)
4940 GdkModifierType tmp_mask;
4941 gboolean normal_child;
4943 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4944 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
4945 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
4947 normal_child = GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_device_state (window,
4951 /* We got the coords on the impl, convert to the window */
4952 tmp_x -= window->abs_x;
4953 tmp_y -= window->abs_y;
4962 _gdk_display_enable_motion_hints (gdk_window_get_display (window), device);
4965 return _gdk_window_find_child_at (window, tmp_x, tmp_y);
4970 * gdk_get_default_root_window:
4972 * Obtains the root window (parent all other windows are inside)
4973 * for the default display and screen.
4975 * Return value: (transfer none): the default root window
4978 gdk_get_default_root_window (void)
4980 return gdk_screen_get_root_window (gdk_screen_get_default ());
4984 get_all_native_children (GdkWindow *window,
4990 for (l = window->children; l != NULL; l = l->next)
4994 if (gdk_window_has_impl (child))
4995 *native = g_list_prepend (*native, child);
4997 get_all_native_children (child, native);
5003 gdk_window_raise_internal (GdkWindow *window)
5005 GdkWindow *parent = window->parent;
5007 GList *native_children;
5009 GdkWindowImplClass *impl_class;
5013 parent->children = g_list_remove (parent->children, window);
5014 parent->children = g_list_prepend (parent->children, window);
5017 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5018 /* Just do native raise for toplevels */
5019 if (gdk_window_is_toplevel (window) ||
5020 /* The restack_under codepath should work correctly even if the parent
5021 is native, but it relies on the order of ->children to be correct,
5022 and some apps like SWT reorder the x windows without gdks knowledge,
5023 so we use raise directly in order to make these behave as before
5024 when using native windows */
5025 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5027 impl_class->raise (window);
5029 else if (gdk_window_has_impl (window))
5031 above = find_native_sibling_above (parent, window);
5034 listhead.data = window;
5035 listhead.next = NULL;
5036 listhead.prev = NULL;
5037 impl_class->restack_under ((GdkWindow *)above,
5041 impl_class->raise (window);
5045 native_children = NULL;
5046 get_all_native_children (window, &native_children);
5047 if (native_children != NULL)
5049 above = find_native_sibling_above (parent, window);
5052 impl_class->restack_under (above, native_children);
5055 /* Right order, since native_children is bottom-topmost first */
5056 for (l = native_children; l != NULL; l = l->next)
5057 impl_class->raise (l->data);
5060 g_list_free (native_children);
5066 /* Returns TRUE If the native window was mapped or unmapped */
5068 set_viewable (GdkWindow *w,
5072 GdkWindowImplClass *impl_class;
5075 if (w->viewable == val)
5081 recompute_visible_regions (w, FALSE, FALSE);
5083 for (l = w->children; l != NULL; l = l->next)
5087 if (GDK_WINDOW_IS_MAPPED (child) &&
5088 child->window_type != GDK_WINDOW_FOREIGN)
5089 set_viewable (child, val);
5092 if (gdk_window_has_impl (w) &&
5093 w->window_type != GDK_WINDOW_FOREIGN &&
5094 !gdk_window_is_toplevel (w))
5096 /* For most native windows we show/hide them not when they are
5097 * mapped/unmapped, because that may not produce the correct results.
5098 * For instance, if a native window have a non-native parent which is
5099 * hidden, but its native parent is viewable then showing the window
5100 * would make it viewable to X but its not viewable wrt the non-native
5101 * hierarchy. In order to handle this we track the gdk side viewability
5102 * and only map really viewable windows.
5104 * There are two exceptions though:
5106 * For foreign windows we don't want ever change the mapped state
5107 * except when explicitly done via gdk_window_show/hide, as this may
5108 * cause problems for client owning the foreign window when its window
5109 * is suddenly mapped or unmapped.
5111 * For toplevel windows embedded in a foreign window (e.g. a plug)
5112 * we sometimes synthesize a map of a window, but the native
5113 * window is really shown by the embedder, so we don't want to
5114 * do the show ourselves. We can't really tell this case from the normal
5115 * toplevel show as such toplevels are seen by gdk as parents of the
5116 * root window, so we make an exception for all toplevels.
5119 impl_class = GDK_WINDOW_IMPL_GET_CLASS (w->impl);
5121 impl_class->show ((GdkWindow *)w, FALSE);
5123 impl_class->hide ((GdkWindow *)w);
5131 /* Returns TRUE If the native window was mapped or unmapped */
5133 _gdk_window_update_viewable (GdkWindow *window)
5137 if (window->window_type == GDK_WINDOW_FOREIGN ||
5138 window->window_type == GDK_WINDOW_ROOT)
5140 else if (gdk_window_is_toplevel (window) ||
5141 window->parent->viewable)
5142 viewable = GDK_WINDOW_IS_MAPPED (window);
5146 return set_viewable (window, viewable);
5150 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5152 GdkWindowImplClass *impl_class;
5153 gboolean was_mapped, was_viewable;
5156 g_return_if_fail (GDK_IS_WINDOW (window));
5158 if (window->destroyed)
5161 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5162 was_viewable = window->viewable;
5165 /* Keep children in (reverse) stacking order */
5166 gdk_window_raise_internal (window);
5168 if (gdk_window_has_impl (window))
5171 gdk_synthesize_window_state (window,
5172 GDK_WINDOW_STATE_WITHDRAWN,
5173 GDK_WINDOW_STATE_FOCUSED);
5180 did_show = _gdk_window_update_viewable (window);
5182 /* If it was already viewable the backend show op won't be called, call it
5183 again to ensure things happen right if the mapped tracking was not right
5184 for e.g. a foreign window.
5185 Dunno if this is strictly needed but its what happened pre-csw.
5186 Also show if not done by gdk_window_update_viewable. */
5187 if (gdk_window_has_impl (window) && (was_viewable || !did_show))
5189 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5190 impl_class->show (window, !did_show ? was_mapped : TRUE);
5193 if (!was_mapped && !gdk_window_has_impl (window))
5195 if (window->event_mask & GDK_STRUCTURE_MASK)
5196 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5198 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5199 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5202 if (!was_mapped || raise)
5204 recompute_visible_regions (window, TRUE, FALSE);
5206 /* If any decendants became visible we need to send visibility notify */
5207 gdk_window_update_visibility_recursively (window, NULL);
5209 if (gdk_window_is_viewable (window))
5211 _gdk_synthesize_crossing_events_for_geometry_change (window);
5212 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5218 * gdk_window_show_unraised:
5219 * @window: a #GdkWindow
5221 * Shows a #GdkWindow onscreen, but does not modify its stacking
5222 * order. In contrast, gdk_window_show() will raise the window
5223 * to the top of the window stack.
5225 * On the X11 platform, in Xlib terms, this function calls
5226 * XMapWindow() (it also updates some internal GDK state, which means
5227 * that you can't really use XMapWindow() directly on a GDK window).
5230 gdk_window_show_unraised (GdkWindow *window)
5232 gdk_window_show_internal (window, FALSE);
5237 * @window: a #GdkWindow
5239 * Raises @window to the top of the Z-order (stacking order), so that
5240 * other windows with the same parent window appear below @window.
5241 * This is true whether or not the windows are visible.
5243 * If @window is a toplevel, the window manager may choose to deny the
5244 * request to move the window in the Z-order, gdk_window_raise() only
5245 * requests the restack, does not guarantee it.
5248 gdk_window_raise (GdkWindow *window)
5250 cairo_region_t *old_region, *new_region;
5252 g_return_if_fail (GDK_IS_WINDOW (window));
5254 if (window->destroyed)
5257 gdk_window_flush_if_exposing (window);
5260 if (gdk_window_is_viewable (window) &&
5261 !window->input_only)
5262 old_region = cairo_region_copy (window->clip_region);
5264 /* Keep children in (reverse) stacking order */
5265 gdk_window_raise_internal (window);
5267 recompute_visible_regions (window, TRUE, FALSE);
5271 new_region = cairo_region_copy (window->clip_region);
5273 cairo_region_subtract (new_region, old_region);
5274 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5276 cairo_region_destroy (old_region);
5277 cairo_region_destroy (new_region);
5282 gdk_window_lower_internal (GdkWindow *window)
5284 GdkWindow *parent = window->parent;
5285 GdkWindowImplClass *impl_class;
5287 GList *native_children;
5292 parent->children = g_list_remove (parent->children, window);
5293 parent->children = g_list_append (parent->children, window);
5296 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5297 /* Just do native lower for toplevels */
5298 if (gdk_window_is_toplevel (window) ||
5299 /* The restack_under codepath should work correctly even if the parent
5300 is native, but it relies on the order of ->children to be correct,
5301 and some apps like SWT reorder the x windows without gdks knowledge,
5302 so we use lower directly in order to make these behave as before
5303 when using native windows */
5304 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5306 impl_class->lower (window);
5308 else if (gdk_window_has_impl (window))
5310 above = find_native_sibling_above (parent, window);
5313 listhead.data = window;
5314 listhead.next = NULL;
5315 listhead.prev = NULL;
5316 impl_class->restack_under ((GdkWindow *)above, &listhead);
5319 impl_class->raise (window);
5323 native_children = NULL;
5324 get_all_native_children (window, &native_children);
5325 if (native_children != NULL)
5327 above = find_native_sibling_above (parent, window);
5330 impl_class->restack_under ((GdkWindow *)above,
5334 /* Right order, since native_children is bottom-topmost first */
5335 for (l = native_children; l != NULL; l = l->next)
5336 impl_class->raise (l->data);
5339 g_list_free (native_children);
5346 gdk_window_invalidate_in_parent (GdkWindow *private)
5348 GdkRectangle r, child;
5350 if (gdk_window_is_toplevel (private))
5353 /* get the visible rectangle of the parent */
5355 r.width = private->parent->width;
5356 r.height = private->parent->height;
5358 child.x = private->x;
5359 child.y = private->y;
5360 child.width = private->width;
5361 child.height = private->height;
5362 gdk_rectangle_intersect (&r, &child, &r);
5364 gdk_window_invalidate_rect_full (private->parent, &r, TRUE, CLEAR_BG_ALL);
5370 * @window: a #GdkWindow
5372 * Lowers @window to the bottom of the Z-order (stacking order), so that
5373 * other windows with the same parent window appear above @window.
5374 * This is true whether or not the other windows are visible.
5376 * If @window is a toplevel, the window manager may choose to deny the
5377 * request to move the window in the Z-order, gdk_window_lower() only
5378 * requests the restack, does not guarantee it.
5380 * Note that gdk_window_show() raises the window again, so don't call this
5381 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5384 gdk_window_lower (GdkWindow *window)
5386 g_return_if_fail (GDK_IS_WINDOW (window));
5388 if (window->destroyed)
5391 gdk_window_flush_if_exposing (window);
5393 /* Keep children in (reverse) stacking order */
5394 gdk_window_lower_internal (window);
5396 recompute_visible_regions (window, TRUE, FALSE);
5398 _gdk_synthesize_crossing_events_for_geometry_change (window);
5399 gdk_window_invalidate_in_parent (window);
5403 * gdk_window_restack:
5404 * @window: a #GdkWindow
5405 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5408 * Changes the position of @window in the Z-order (stacking order), so that
5409 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5412 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5413 * lowers the window.
5415 * If @window is a toplevel, the window manager may choose to deny the
5416 * request to move the window in the Z-order, gdk_window_restack() only
5417 * requests the restack, does not guarantee it.
5422 gdk_window_restack (GdkWindow *window,
5426 GdkWindowImplClass *impl_class;
5428 GdkWindow *above_native;
5429 GList *sibling_link;
5430 GList *native_children;
5433 g_return_if_fail (GDK_IS_WINDOW (window));
5434 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5436 if (window->destroyed)
5439 if (sibling == NULL)
5442 gdk_window_raise (window);
5444 gdk_window_lower (window);
5448 gdk_window_flush_if_exposing (window);
5450 if (gdk_window_is_toplevel (window))
5452 g_return_if_fail (gdk_window_is_toplevel (sibling));
5453 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5454 impl_class->restack_toplevel (window, sibling, above);
5458 parent = window->parent;
5461 sibling_link = g_list_find (parent->children, sibling);
5462 g_return_if_fail (sibling_link != NULL);
5463 if (sibling_link == NULL)
5466 parent->children = g_list_remove (parent->children, window);
5468 parent->children = g_list_insert_before (parent->children,
5472 parent->children = g_list_insert_before (parent->children,
5476 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5477 if (gdk_window_has_impl (window))
5479 above_native = find_native_sibling_above (parent, window);
5482 listhead.data = window;
5483 listhead.next = NULL;
5484 listhead.prev = NULL;
5485 impl_class->restack_under (above_native, &listhead);
5488 impl_class->raise (window);
5492 native_children = NULL;
5493 get_all_native_children (window, &native_children);
5494 if (native_children != NULL)
5496 above_native = find_native_sibling_above (parent, window);
5498 impl_class->restack_under (above_native,
5502 /* Right order, since native_children is bottom-topmost first */
5503 for (l = native_children; l != NULL; l = l->next)
5504 impl_class->raise (l->data);
5507 g_list_free (native_children);
5512 recompute_visible_regions (window, TRUE, FALSE);
5514 _gdk_synthesize_crossing_events_for_geometry_change (window);
5515 gdk_window_invalidate_in_parent (window);
5521 * @window: a #GdkWindow
5523 * Like gdk_window_show_unraised(), but also raises the window to the
5524 * top of the window stack (moves the window to the front of the
5527 * This function maps a window so it's visible onscreen. Its opposite
5528 * is gdk_window_hide().
5530 * When implementing a #GtkWidget, you should call this function on the widget's
5531 * #GdkWindow as part of the "map" method.
5534 gdk_window_show (GdkWindow *window)
5536 gdk_window_show_internal (window, TRUE);
5541 * @window: a #GdkWindow
5543 * For toplevel windows, withdraws them, so they will no longer be
5544 * known to the window manager; for all windows, unmaps them, so
5545 * they won't be displayed. Normally done automatically as
5546 * part of gtk_widget_hide().
5549 gdk_window_hide (GdkWindow *window)
5551 GdkWindowImplClass *impl_class;
5552 gboolean was_mapped, did_hide;
5554 g_return_if_fail (GDK_IS_WINDOW (window));
5556 if (window->destroyed)
5559 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5561 if (gdk_window_has_impl (window))
5564 if (GDK_WINDOW_IS_MAPPED (window))
5565 gdk_synthesize_window_state (window,
5567 GDK_WINDOW_STATE_WITHDRAWN);
5569 else if (was_mapped)
5571 GdkDisplay *display;
5572 GdkDeviceManager *device_manager;
5575 /* May need to break grabs on children */
5576 display = gdk_window_get_display (window);
5577 device_manager = gdk_display_get_device_manager (display);
5579 /* Get all devices */
5580 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5581 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5582 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5584 for (d = devices; d; d = d->next)
5586 GdkDevice *device = d->data;
5588 if (_gdk_display_end_device_grab (display,
5590 _gdk_display_get_next_serial (display),
5593 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5596 window->state = GDK_WINDOW_STATE_WITHDRAWN;
5597 g_list_free (devices);
5600 did_hide = _gdk_window_update_viewable (window);
5602 /* Hide foreign window as those are not handled by update_viewable. */
5603 if (gdk_window_has_impl (window) && (!did_hide))
5605 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5606 impl_class->hide (window);
5609 recompute_visible_regions (window, TRUE, FALSE);
5611 /* all decendants became non-visible, we need to send visibility notify */
5612 gdk_window_update_visibility_recursively (window, NULL);
5614 if (was_mapped && !gdk_window_has_impl (window))
5616 if (window->event_mask & GDK_STRUCTURE_MASK)
5617 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5619 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5620 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5622 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5625 /* Invalidate the rect */
5627 gdk_window_invalidate_in_parent (window);
5631 * gdk_window_withdraw:
5632 * @window: a toplevel #GdkWindow
5634 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5635 * This function is not really useful as gdk_window_hide() automatically
5636 * withdraws toplevel windows before hiding them.
5639 gdk_window_withdraw (GdkWindow *window)
5641 GdkWindowImplClass *impl_class;
5642 gboolean was_mapped;
5644 g_return_if_fail (GDK_IS_WINDOW (window));
5646 if (window->destroyed)
5649 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5651 if (gdk_window_has_impl (window))
5653 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5654 impl_class->withdraw (window);
5658 if (window->event_mask & GDK_STRUCTURE_MASK)
5659 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5661 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5662 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5664 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5667 recompute_visible_regions (window, TRUE, FALSE);
5672 * gdk_window_set_events:
5673 * @window: a #GdkWindow
5674 * @event_mask: event mask for @window
5676 * The event mask for a window determines which events will be reported
5677 * for that window from all master input devices. For example, an event mask
5678 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5679 * press events. The event mask is the bitwise OR of values from the
5680 * #GdkEventMask enumeration.
5683 gdk_window_set_events (GdkWindow *window,
5684 GdkEventMask event_mask)
5686 GdkWindowImplClass *impl_class;
5687 GdkDisplay *display;
5689 g_return_if_fail (GDK_IS_WINDOW (window));
5691 if (window->destroyed)
5694 /* If motion hint is disabled, enable motion events again */
5695 display = gdk_window_get_display (window);
5696 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5697 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5699 GList *devices = window->devices_inside;
5703 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5704 devices = devices->next;
5708 window->event_mask = event_mask;
5710 if (gdk_window_has_impl (window))
5712 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5713 impl_class->set_events (window,
5714 get_native_event_mask (window));
5720 * gdk_window_get_events:
5721 * @window: a #GdkWindow
5723 * Gets the event mask for @window for all master input devices. See
5724 * gdk_window_set_events().
5726 * Return value: event mask for @window
5729 gdk_window_get_events (GdkWindow *window)
5731 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5733 if (window->destroyed)
5736 return window->event_mask;
5740 * gdk_window_set_device_events:
5741 * @window: a #GdkWindow
5742 * @device: #GdkDevice to enable events for.
5743 * @event_mask: event mask for @window
5745 * Sets the event mask for a given device (Normally a floating device, not
5746 * attached to any visible pointer) to @window. For example, an event mask
5747 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5748 * press events. The event mask is the bitwise OR of values from the
5749 * #GdkEventMask enumeration.
5754 gdk_window_set_device_events (GdkWindow *window,
5756 GdkEventMask event_mask)
5758 GdkEventMask device_mask;
5759 GdkDisplay *display;
5762 g_return_if_fail (GDK_IS_WINDOW (window));
5763 g_return_if_fail (GDK_IS_DEVICE (device));
5765 if (GDK_WINDOW_DESTROYED (window))
5768 /* If motion hint is disabled, enable motion events again */
5769 display = gdk_window_get_display (window);
5770 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5771 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5772 _gdk_display_enable_motion_hints (display, device);
5774 if (G_UNLIKELY (!window->device_events))
5775 window->device_events = g_hash_table_new (NULL, NULL);
5777 if (event_mask == 0)
5779 /* FIXME: unsetting events on a master device
5780 * would restore window->event_mask
5782 g_hash_table_remove (window->device_events, device);
5785 g_hash_table_insert (window->device_events, device,
5786 GINT_TO_POINTER (event_mask));
5788 native = gdk_window_get_toplevel (window);
5790 while (gdk_window_is_offscreen (native))
5792 native = gdk_offscreen_window_get_embedder (native);
5794 if (native == NULL ||
5795 (!_gdk_window_has_impl (native) &&
5796 !gdk_window_is_viewable (native)))
5799 native = gdk_window_get_toplevel (native);
5802 device_mask = get_native_device_event_mask (window, device);
5803 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
5807 * gdk_window_get_device_events:
5808 * @window: a #GdkWindow.
5809 * @device: a #GdkDevice.
5811 * Returns the event mask for @window corresponding to an specific device.
5813 * Returns: device event mask for @window
5818 gdk_window_get_device_events (GdkWindow *window,
5823 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5824 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
5826 if (GDK_WINDOW_DESTROYED (window))
5829 if (!window->device_events)
5832 mask = GPOINTER_TO_INT (g_hash_table_lookup (window->device_events, device));
5834 /* FIXME: device could be controlled by window->event_mask */
5840 gdk_window_move_resize_toplevel (GdkWindow *window,
5847 cairo_region_t *old_region, *new_region;
5848 GdkWindowImplClass *impl_class;
5855 is_resize = (width != -1) || (height != -1);
5857 if (gdk_window_is_viewable (window) &&
5858 !window->input_only)
5861 old_region = cairo_region_copy (window->clip_region);
5864 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5865 impl_class->move_resize (window, with_move, x, y, width, height);
5867 /* Avoid recomputing for pure toplevel moves, for performance reasons */
5869 recompute_visible_regions (window, TRUE, FALSE);
5873 new_region = cairo_region_copy (window->clip_region);
5875 /* This is the newly exposed area (due to any resize),
5876 * X will expose it, but lets do that without the roundtrip
5878 cairo_region_subtract (new_region, old_region);
5879 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
5881 cairo_region_destroy (old_region);
5882 cairo_region_destroy (new_region);
5885 _gdk_synthesize_crossing_events_for_geometry_change (window);
5890 move_native_children (GdkWindow *private)
5894 GdkWindowImplClass *impl_class;
5896 for (l = private->children; l; l = l->next)
5900 if (child->impl != private->impl)
5902 impl_class = GDK_WINDOW_IMPL_GET_CLASS (child->impl);
5903 impl_class->move_resize (child, TRUE,
5905 child->width, child->height);
5908 move_native_children (child);
5913 collect_native_child_region_helper (GdkWindow *window,
5914 GdkWindowImpl *impl,
5915 cairo_region_t **region,
5920 cairo_region_t *tmp;
5923 for (l = window->children; l != NULL; l = l->next)
5927 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
5930 if (child->impl != impl)
5932 tmp = cairo_region_copy (child->clip_region);
5933 cairo_region_translate (tmp,
5934 x_offset + child->x,
5935 y_offset + child->y);
5936 if (*region == NULL)
5940 cairo_region_union (*region, tmp);
5941 cairo_region_destroy (tmp);
5945 collect_native_child_region_helper (child, impl, region,
5946 x_offset + child->x,
5947 y_offset + child->y);
5953 static cairo_region_t *
5954 collect_native_child_region (GdkWindow *window,
5955 gboolean include_this)
5957 cairo_region_t *region;
5959 if (include_this && gdk_window_has_impl (window) && window->viewable)
5960 return cairo_region_copy (window->clip_region);
5964 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
5971 gdk_window_move_resize_internal (GdkWindow *window,
5978 cairo_region_t *old_region, *new_region, *copy_area;
5979 cairo_region_t *old_native_child_region, *new_native_child_region;
5980 GdkWindow *impl_window;
5981 GdkWindowImplClass *impl_class;
5983 int old_x, old_y, old_abs_x, old_abs_y;
5986 g_return_if_fail (GDK_IS_WINDOW (window));
5988 if (window->destroyed)
5991 if (gdk_window_is_toplevel (window))
5993 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
5997 /* Bail early if no change */
5998 if (window->width == width &&
5999 window->height == height &&
6005 gdk_window_flush_if_exposing (window);
6007 /* Handle child windows */
6012 impl_window = gdk_window_get_impl_window (window);
6017 old_native_child_region = NULL;
6018 if (gdk_window_is_viewable (window) &&
6019 !window->input_only)
6023 old_region = cairo_region_copy (window->clip_region);
6024 /* Adjust region to parent window coords */
6025 cairo_region_translate (old_region, window->x, window->y);
6027 old_native_child_region = collect_native_child_region (window, TRUE);
6028 if (old_native_child_region)
6030 /* Adjust region to parent window coords */
6031 cairo_region_translate (old_native_child_region, window->x, window->y);
6033 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6034 * source or destination for a delayed GdkWindowRegionMove. So, we need
6035 * to flush those here for the parent window and all overlapped subwindows
6036 * of it. And we need to do this before setting the new clips as those will be
6039 gdk_window_flush_recursive (window->parent);
6043 /* Set the new position and size */
6049 if (!(width < 0 && height < 0))
6053 window->width = width;
6056 window->height = height;
6059 dx = window->x - old_x;
6060 dy = window->y - old_y;
6062 old_abs_x = window->abs_x;
6063 old_abs_y = window->abs_y;
6065 recompute_visible_regions (window, TRUE, FALSE);
6067 new_native_child_region = NULL;
6068 if (old_native_child_region)
6070 new_native_child_region = collect_native_child_region (window, TRUE);
6071 /* Adjust region to parent window coords */
6072 cairo_region_translate (new_native_child_region, window->x, window->y);
6075 if (gdk_window_has_impl (window))
6077 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6079 /* Do the actual move after recomputing things, as this will have set the shape to
6080 the now correct one, thus avoiding copying regions that should not be copied. */
6081 impl_class->move_resize (window, TRUE,
6082 window->x, window->y,
6083 window->width, window->height);
6085 else if (old_abs_x != window->abs_x ||
6086 old_abs_y != window->abs_y)
6087 move_native_children (window);
6091 new_region = cairo_region_copy (window->clip_region);
6092 /* Adjust region to parent window coords */
6093 cairo_region_translate (new_region, window->x, window->y);
6096 * Part of the data at the new location can be copied from the
6097 * old location, this area is the intersection of the old region
6098 * moved as the copy will move it and then intersected with
6102 * Everything in the old and new regions that is not copied must be
6103 * invalidated (including children) as this is newly exposed
6105 copy_area = cairo_region_copy (new_region);
6107 cairo_region_union (new_region, old_region);
6109 if (old_native_child_region)
6111 /* Don't copy from inside native children, as this is copied by
6112 * the native window move.
6114 cairo_region_subtract (old_region, old_native_child_region);
6116 cairo_region_translate (old_region, dx, dy);
6118 cairo_region_intersect (copy_area, old_region);
6120 if (new_native_child_region)
6122 /* Don't copy any bits that would cause a read from the moved
6123 native windows, as we can't read that data */
6124 cairo_region_translate (new_native_child_region, dx, dy);
6125 cairo_region_subtract (copy_area, new_native_child_region);
6126 cairo_region_translate (new_native_child_region, -dx, -dy);
6129 cairo_region_subtract (new_region, copy_area);
6131 /* Convert old region to impl coords */
6132 cairo_region_translate (old_region, -dx + window->abs_x - window->x, -dy + window->abs_y - window->y);
6134 /* convert from parent coords to impl */
6135 cairo_region_translate (copy_area, window->abs_x - window->x, window->abs_y - window->y);
6137 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6139 /* Invalidate affected part in the parent window
6140 * (no higher window should be affected)
6141 * We also invalidate any children in that area, which could include
6142 * this window if it still overlaps that area.
6144 if (old_native_child_region)
6146 /* No need to expose the region that the native window move copies */
6147 cairo_region_translate (old_native_child_region, dx, dy);
6148 cairo_region_intersect (old_native_child_region, new_native_child_region);
6149 cairo_region_subtract (new_region, old_native_child_region);
6151 gdk_window_invalidate_region_full (window->parent, new_region, TRUE, CLEAR_BG_ALL);
6153 cairo_region_destroy (old_region);
6154 cairo_region_destroy (new_region);
6157 if (old_native_child_region)
6159 cairo_region_destroy (old_native_child_region);
6160 cairo_region_destroy (new_native_child_region);
6163 _gdk_synthesize_crossing_events_for_geometry_change (window);
6170 * @window: a #GdkWindow
6171 * @x: X coordinate relative to window's parent
6172 * @y: Y coordinate relative to window's parent
6174 * Repositions a window relative to its parent window.
6175 * For toplevel windows, window managers may ignore or modify the move;
6176 * you should probably use gtk_window_move() on a #GtkWindow widget
6177 * anyway, instead of using GDK functions. For child windows,
6178 * the move will reliably succeed.
6180 * If you're also planning to resize the window, use gdk_window_move_resize()
6181 * to both move and resize simultaneously, for a nicer visual effect.
6184 gdk_window_move (GdkWindow *window,
6188 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6192 * gdk_window_resize:
6193 * @window: a #GdkWindow
6194 * @width: new width of the window
6195 * @height: new height of the window
6197 * Resizes @window; for toplevel windows, asks the window manager to resize
6198 * the window. The window manager may not allow the resize. When using GTK+,
6199 * use gtk_window_resize() instead of this low-level GDK function.
6201 * Windows may not be resized below 1x1.
6203 * If you're also planning to move the window, use gdk_window_move_resize()
6204 * to both move and resize simultaneously, for a nicer visual effect.
6207 gdk_window_resize (GdkWindow *window,
6211 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6216 * gdk_window_move_resize:
6217 * @window: a #GdkWindow
6218 * @x: new X position relative to window's parent
6219 * @y: new Y position relative to window's parent
6221 * @height: new height
6223 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6224 * except that both operations are performed at once, avoiding strange
6225 * visual effects. (i.e. the user may be able to see the window first
6226 * move, then resize, if you don't use gdk_window_move_resize().)
6229 gdk_window_move_resize (GdkWindow *window,
6235 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6240 * gdk_window_scroll:
6241 * @window: a #GdkWindow
6242 * @dx: Amount to scroll in the X direction
6243 * @dy: Amount to scroll in the Y direction
6245 * Scroll the contents of @window, both pixels and children, by the
6246 * given amount. @window itself does not move. Portions of the window
6247 * that the scroll operation brings in from offscreen areas are
6248 * invalidated. The invalidated region may be bigger than what would
6249 * strictly be necessary.
6251 * For X11, a minimum area will be invalidated if the window has no
6252 * subwindows, or if the edges of the window's parent do not extend
6253 * beyond the edges of the window. In other cases, a multi-step process
6254 * is used to scroll the window which may produce temporary visual
6255 * artifacts and unnecessary invalidations.
6258 gdk_window_scroll (GdkWindow *window,
6262 GdkWindow *impl_window;
6263 cairo_region_t *copy_area, *noncopy_area;
6264 cairo_region_t *old_native_child_region, *new_native_child_region;
6267 g_return_if_fail (GDK_IS_WINDOW (window));
6269 if (dx == 0 && dy == 0)
6272 if (window->destroyed)
6275 gdk_window_flush_if_exposing (window);
6277 old_native_child_region = collect_native_child_region (window, FALSE);
6278 if (old_native_child_region)
6280 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6281 * source or destination for a delayed GdkWindowRegionMove. So, we need
6282 * to flush those here for the window and all overlapped subwindows
6283 * of it. And we need to do this before setting the new clips as those will be
6286 gdk_window_flush_recursive (window);
6290 /* First move all child windows, without causing invalidation */
6292 tmp_list = window->children;
6295 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6297 /* Just update the positions, the bits will move with the copy */
6301 tmp_list = tmp_list->next;
6304 recompute_visible_regions (window, FALSE, TRUE);
6306 new_native_child_region = NULL;
6307 if (old_native_child_region)
6308 new_native_child_region = collect_native_child_region (window, FALSE);
6310 move_native_children (window);
6312 /* Then copy the actual bits of the window w/ child windows */
6314 impl_window = gdk_window_get_impl_window (window);
6316 /* Calculate the area that can be gotten by copying the old area */
6317 copy_area = cairo_region_copy (window->clip_region);
6318 if (old_native_child_region)
6320 /* Don't copy from inside native children, as this is copied by
6321 * the native window move.
6323 cairo_region_subtract (copy_area, old_native_child_region);
6325 /* Don't copy any bits that would cause a read from the moved
6326 native windows, as we can't read that data */
6327 cairo_region_subtract (copy_area, new_native_child_region);
6329 cairo_region_translate (copy_area, dx, dy);
6330 cairo_region_intersect (copy_area, window->clip_region);
6332 /* And the rest need to be invalidated */
6333 noncopy_area = cairo_region_copy (window->clip_region);
6334 cairo_region_subtract (noncopy_area, copy_area);
6336 /* convert from window coords to impl */
6337 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6339 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6341 /* Invalidate not copied regions */
6342 if (old_native_child_region)
6344 /* No need to expose the region that the native window move copies */
6345 cairo_region_translate (old_native_child_region, dx, dy);
6346 cairo_region_intersect (old_native_child_region, new_native_child_region);
6347 cairo_region_subtract (noncopy_area, old_native_child_region);
6349 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6351 cairo_region_destroy (noncopy_area);
6353 if (old_native_child_region)
6355 cairo_region_destroy (old_native_child_region);
6356 cairo_region_destroy (new_native_child_region);
6359 _gdk_synthesize_crossing_events_for_geometry_change (window);
6363 * gdk_window_move_region:
6364 * @window: a #GdkWindow
6365 * @region: The #cairo_region_t to move
6366 * @dx: Amount to move in the X direction
6367 * @dy: Amount to move in the Y direction
6369 * Move the part of @window indicated by @region by @dy pixels in the Y
6370 * direction and @dx pixels in the X direction. The portions of @region
6371 * that not covered by the new position of @region are invalidated.
6373 * Child windows are not moved.
6378 gdk_window_move_region (GdkWindow *window,
6379 const cairo_region_t *region,
6383 GdkWindow *impl_window;
6384 cairo_region_t *nocopy_area;
6385 cairo_region_t *copy_area;
6387 g_return_if_fail (GDK_IS_WINDOW (window));
6388 g_return_if_fail (region != NULL);
6390 if (dx == 0 && dy == 0)
6393 if (window->destroyed)
6396 impl_window = gdk_window_get_impl_window (window);
6398 /* compute source regions */
6399 copy_area = cairo_region_copy (region);
6400 cairo_region_intersect (copy_area, window->clip_region_with_children);
6402 /* compute destination regions */
6403 cairo_region_translate (copy_area, dx, dy);
6404 cairo_region_intersect (copy_area, window->clip_region_with_children);
6406 /* Invalidate parts of the region (source and dest) not covered
6408 nocopy_area = cairo_region_copy (region);
6409 cairo_region_translate (nocopy_area, dx, dy);
6410 cairo_region_union (nocopy_area, region);
6411 cairo_region_subtract (nocopy_area, copy_area);
6413 /* convert from window coords to impl */
6414 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6415 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6417 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6418 cairo_region_destroy (nocopy_area);
6422 * gdk_window_set_background:
6423 * @window: a #GdkWindow
6424 * @color: a #GdkColor
6426 * Sets the background color of @window. (However, when using GTK+,
6427 * set the background of a widget with gtk_widget_modify_bg() - if
6428 * you're an application - or gtk_style_set_background() - if you're
6429 * implementing a custom widget.)
6431 * See also gdk_window_set_background_pattern().
6434 gdk_window_set_background (GdkWindow *window,
6435 const GdkColor *color)
6437 cairo_pattern_t *pattern;
6439 g_return_if_fail (GDK_IS_WINDOW (window));
6441 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6442 color->green / 65535.,
6443 color->blue / 65535.);
6445 gdk_window_set_background_pattern (window, pattern);
6447 cairo_pattern_destroy (pattern);
6451 * gdk_window_set_background_rgba:
6452 * @window: a #GdkWindow
6453 * @rgba: a #GdkRGBA color
6455 * Sets the background color of @window.
6457 * See also gdk_window_set_background_pattern().
6460 gdk_window_set_background_rgba (GdkWindow *window,
6463 cairo_pattern_t *pattern;
6465 g_return_if_fail (GDK_IS_WINDOW (window));
6466 g_return_if_fail (rgba != NULL);
6468 pattern = cairo_pattern_create_rgba (rgba->red, rgba->green,
6469 rgba->blue, rgba->alpha);
6471 gdk_window_set_background_pattern (window, pattern);
6473 cairo_pattern_destroy (pattern);
6477 * gdk_window_set_background_pattern:
6478 * @window: a #GdkWindow
6479 * @pattern: (allow-none): a pattern to use, or %NULL
6481 * Sets the background of @window.
6483 * A background of %NULL means that the window will inherit its
6484 * background form its parent window.
6486 * The windowing system will normally fill a window with its background
6487 * when the window is obscured then exposed.
6490 gdk_window_set_background_pattern (GdkWindow *window,
6491 cairo_pattern_t *pattern)
6493 g_return_if_fail (GDK_IS_WINDOW (window));
6495 if (window->input_only)
6499 cairo_pattern_reference (pattern);
6500 if (window->background)
6501 cairo_pattern_destroy (window->background);
6502 window->background = pattern;
6504 if (gdk_window_has_impl (window))
6506 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6507 impl_class->set_background (window, pattern);
6510 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
6514 * gdk_window_get_background_pattern:
6517 * Gets the pattern used to clear the background on @window. If @window
6518 * does not have its own background and reuses the parent's, %NULL is
6519 * returned and you'll have to query it yourself.
6521 * Returns: (transfer none): The pattern to use for the background or
6522 * %NULL to use the parent's background.
6527 gdk_window_get_background_pattern (GdkWindow *window)
6529 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6531 return window->background;
6535 gdk_window_set_cursor_internal (GdkWindow *window,
6539 if (GDK_WINDOW_DESTROYED (window))
6542 if (window->window_type == GDK_WINDOW_ROOT ||
6543 window->window_type == GDK_WINDOW_FOREIGN)
6544 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_device_cursor (window, device, cursor);
6547 GdkPointerWindowInfo *pointer_info;
6548 GdkDisplay *display;
6550 display = gdk_window_get_display (window);
6551 pointer_info = _gdk_display_get_pointer_info (display, device);
6553 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6554 update_cursor (display, device);
6559 * gdk_window_get_cursor:
6560 * @window: a #GdkWindow
6562 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6563 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6564 * there is no custom cursor set on the specified window, and it is
6565 * using the cursor for its parent window.
6567 * Return value: (transfer none): a #GdkCursor, or %NULL. The returned
6568 * object is owned by the #GdkWindow and should not be unreferenced
6569 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6575 gdk_window_get_cursor (GdkWindow *window)
6577 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6579 return window->cursor;
6583 * gdk_window_set_cursor:
6584 * @window: a #GdkWindow
6585 * @cursor: (allow-none): a cursor
6587 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6588 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6589 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6590 * to gdk_window_set_cursor() means that @window will use the cursor of its
6591 * parent window. Most windows should use this default.
6594 gdk_window_set_cursor (GdkWindow *window,
6597 GdkDisplay *display;
6599 g_return_if_fail (GDK_IS_WINDOW (window));
6601 display = gdk_window_get_display (window);
6605 g_object_unref (window->cursor);
6606 window->cursor = NULL;
6609 if (!GDK_WINDOW_DESTROYED (window))
6611 GdkDeviceManager *device_manager;
6615 window->cursor = g_object_ref (cursor);
6617 device_manager = gdk_display_get_device_manager (display);
6618 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6620 for (d = devices; d; d = d->next)
6626 if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
6629 gdk_window_set_cursor_internal (window, device, window->cursor);
6632 g_list_free (devices);
6633 g_object_notify (G_OBJECT (window), "cursor");
6638 * gdk_window_get_device_cursor:
6639 * @window: a #GdkWindow.
6640 * @device: a master, pointer #GdkDevice.
6642 * Retrieves a #GdkCursor pointer for the @device currently set on the
6643 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6644 * there is no custom cursor set on the specified window, and it is
6645 * using the cursor for its parent window.
6647 * Returns: (transfer none): a #GdkCursor, or %NULL. The returned
6648 * object is owned by the #GdkWindow and should not be unreferenced
6649 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6655 gdk_window_get_device_cursor (GdkWindow *window,
6658 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6659 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6660 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
6661 g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER, NULL);
6663 return g_hash_table_lookup (window->device_cursor, device);
6667 * gdk_window_set_device_cursor:
6668 * @window: a #Gdkwindow
6669 * @device: a master, pointer #GdkDevice
6670 * @cursor: a #GdkCursor
6672 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6673 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6674 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6675 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6676 * @window will use the cursor of its parent window. Most windows should
6682 gdk_window_set_device_cursor (GdkWindow *window,
6686 g_return_if_fail (GDK_IS_WINDOW (window));
6687 g_return_if_fail (GDK_IS_DEVICE (device));
6688 g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
6689 g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
6692 g_hash_table_remove (window->device_cursor, device);
6694 g_hash_table_replace (window->device_cursor, device, g_object_ref (cursor));
6696 gdk_window_set_cursor_internal (window, device, cursor);
6700 * gdk_window_get_geometry:
6701 * @window: a #GdkWindow
6702 * @x: (out) (allow-none): return location for X coordinate of window (relative to its parent)
6703 * @y: (out) (allow-none): return location for Y coordinate of window (relative to its parent)
6704 * @width: (out) (allow-none): return location for width of window
6705 * @height: (out) (allow-none): return location for height of window
6707 * Any of the return location arguments to this function may be %NULL,
6708 * if you aren't interested in getting the value of that field.
6710 * The X and Y coordinates returned are relative to the parent window
6711 * of @window, which for toplevels usually means relative to the
6712 * window decorations (titlebar, etc.) rather than relative to the
6713 * root window (screen-size background window).
6715 * On the X11 platform, the geometry is obtained from the X server,
6716 * so reflects the latest position of @window; this may be out-of-sync
6717 * with the position of @window delivered in the most-recently-processed
6718 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6719 * position from the most recent configure event.
6722 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6723 * to call gdk_window_get_position(), gdk_window_get_width() and
6724 * gdk_window_get_height() instead, because it avoids the roundtrip to
6725 * the X server and because these functions support the full 32-bit
6726 * coordinate space, whereas gdk_window_get_geometry() is restricted to
6727 * the 16-bit coordinates of X11.
6731 gdk_window_get_geometry (GdkWindow *window,
6738 GdkWindowImplClass *impl_class;
6742 GDK_NOTE (MULTIHEAD,
6743 g_message ("gdk_window_get_geometry(): Window needs "
6744 "to be non-NULL to be multi head safe"));
6745 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
6748 g_return_if_fail (GDK_IS_WINDOW (window));
6750 if (!GDK_WINDOW_DESTROYED (window))
6752 if (gdk_window_has_impl (window))
6754 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6755 impl_class->get_geometry (window, x, y,
6757 /* This reports the position wrt to the native parent, we need to convert
6758 it to be relative to the client side parent */
6759 parent = window->parent;
6760 if (parent && !gdk_window_has_impl (parent))
6763 *x -= parent->abs_x;
6765 *y -= parent->abs_y;
6775 *width = window->width;
6777 *height = window->height;
6783 * gdk_window_get_width:
6784 * @window: a #GdkWindow
6786 * Returns the width of the given @window.
6788 * On the X11 platform the returned size is the size reported in the
6789 * most-recently-processed configure event, rather than the current
6790 * size on the X server.
6792 * Returns: The width of @window
6797 gdk_window_get_width (GdkWindow *window)
6799 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6801 return window->width;
6805 * gdk_window_get_height:
6806 * @window: a #GdkWindow
6808 * Returns the height of the given @window.
6810 * On the X11 platform the returned size is the size reported in the
6811 * most-recently-processed configure event, rather than the current
6812 * size on the X server.
6814 * Returns: The height of @window
6819 gdk_window_get_height (GdkWindow *window)
6821 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6823 return window->height;
6827 * gdk_window_get_origin:
6828 * @window: a #GdkWindow
6829 * @x: (out) (allow-none): return location for X coordinate
6830 * @y: (out) (allow-none): return location for Y coordinate
6832 * Obtains the position of a window in root window coordinates.
6833 * (Compare with gdk_window_get_position() and
6834 * gdk_window_get_geometry() which return the position of a window
6835 * relative to its parent window.)
6837 * Return value: not meaningful, ignore
6840 gdk_window_get_origin (GdkWindow *window,
6844 GdkWindowImplClass *impl_class;
6846 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6848 if (GDK_WINDOW_DESTROYED (window))
6857 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6858 impl_class->get_root_coords (window,
6867 * gdk_window_get_root_coords:
6868 * @window: a #GdkWindow
6869 * @x: X coordinate in window
6870 * @y: Y coordinate in window
6871 * @root_x: (out): return location for X coordinate
6872 * @root_y: (out): return location for Y coordinate
6874 * Obtains the position of a window position in root
6875 * window coordinates. This is similar to
6876 * gdk_window_get_origin() but allows you go pass
6877 * in any position in the window, not just the origin.
6882 gdk_window_get_root_coords (GdkWindow *window,
6888 GdkWindowImplClass *impl_class;
6890 g_return_if_fail (GDK_IS_WINDOW (window));
6892 if (GDK_WINDOW_DESTROYED (window))
6899 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6900 impl_class->get_root_coords (window,
6907 * gdk_window_coords_to_parent:
6908 * @window: a child window
6909 * @x: X coordinate in child's coordinate system
6910 * @y: Y coordinate in child's coordinate system
6911 * @parent_x: (out) (allow-none): return location for X coordinate
6912 * in parent's coordinate system, or %NULL
6913 * @parent_y: (out) (allow-none): return location for Y coordinate
6914 * in parent's coordinate system, or %NULL
6916 * Transforms window coordinates from a child window to its parent
6917 * window, where the parent window is the normal parent as returned by
6918 * gdk_window_get_parent() for normal windows, and the window's
6919 * embedder as returned by gdk_offscreen_window_get_embedder() for
6920 * offscreen windows.
6922 * For normal windows, calling this function is equivalent to adding
6923 * the return values of gdk_window_get_position() to the child coordinates.
6924 * For offscreen windows however (which can be arbitrarily transformed),
6925 * this function calls the GdkWindow::to-embedder: signal to translate
6928 * You should always use this function when writing generic code that
6929 * walks up a window hierarchy.
6931 * See also: gdk_window_coords_from_parent()
6936 gdk_window_coords_to_parent (GdkWindow *window,
6942 g_return_if_fail (GDK_IS_WINDOW (window));
6944 if (gdk_window_is_offscreen (window))
6948 to_embedder (window, x, y, &px, &py);
6959 *parent_x = x + window->x;
6962 *parent_y = y + window->y;
6967 * gdk_window_coords_from_parent:
6968 * @window: a child window
6969 * @parent_x: X coordinate in parent's coordinate system
6970 * @parent_y: Y coordinate in parent's coordinate system
6971 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
6972 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
6974 * Transforms window coordinates from a parent window to a child
6975 * window, where the parent window is the normal parent as returned by
6976 * gdk_window_get_parent() for normal windows, and the window's
6977 * embedder as returned by gdk_offscreen_window_get_embedder() for
6978 * offscreen windows.
6980 * For normal windows, calling this function is equivalent to subtracting
6981 * the return values of gdk_window_get_position() from the parent coordinates.
6982 * For offscreen windows however (which can be arbitrarily transformed),
6983 * this function calls the GdkWindow::from-embedder: signal to translate
6986 * You should always use this function when writing generic code that
6987 * walks down a window hierarchy.
6989 * See also: gdk_window_coords_to_parent()
6994 gdk_window_coords_from_parent (GdkWindow *window,
7000 g_return_if_fail (GDK_IS_WINDOW (window));
7002 if (gdk_window_is_offscreen (window))
7006 from_embedder (window, parent_x, parent_y, &cx, &cy);
7017 *x = parent_x - window->x;
7020 *y = parent_y - window->y;
7025 * gdk_window_shape_combine_region:
7026 * @window: a #GdkWindow
7027 * @shape_region: (allow-none): region of window to be non-transparent
7028 * @offset_x: X position of @shape_region in @window coordinates
7029 * @offset_y: Y position of @shape_region in @window coordinates
7031 * Makes pixels in @window outside @shape_region be transparent,
7032 * so that the window may be nonrectangular.
7034 * If @shape_region is %NULL, the shape will be unset, so the whole
7035 * window will be opaque again. @offset_x and @offset_y are ignored
7036 * if @shape_region is %NULL.
7038 * On the X11 platform, this uses an X server extension which is
7039 * widely available on most common platforms, but not available on
7040 * very old X servers, and occasionally the implementation will be
7041 * buggy. On servers without the shape extension, this function
7044 * This function works on both toplevel and child windows.
7047 gdk_window_shape_combine_region (GdkWindow *window,
7048 const cairo_region_t *shape_region,
7052 cairo_region_t *old_region, *new_region, *diff;
7054 g_return_if_fail (GDK_IS_WINDOW (window));
7056 if (GDK_WINDOW_DESTROYED (window))
7059 if (!window->shape && shape_region == NULL)
7062 window->shaped = (shape_region != NULL);
7065 cairo_region_destroy (window->shape);
7068 if (GDK_WINDOW_IS_MAPPED (window))
7069 old_region = cairo_region_copy (window->clip_region);
7073 window->shape = cairo_region_copy (shape_region);
7074 cairo_region_translate (window->shape, offset_x, offset_y);
7077 window->shape = NULL;
7079 recompute_visible_regions (window, TRUE, FALSE);
7081 if (gdk_window_has_impl (window) &&
7082 !should_apply_clip_as_shape (window))
7083 apply_shape (window, window->shape);
7087 new_region = cairo_region_copy (window->clip_region);
7089 /* New area in the window, needs invalidation */
7090 diff = cairo_region_copy (new_region);
7091 cairo_region_subtract (diff, old_region);
7093 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7095 cairo_region_destroy (diff);
7097 if (!gdk_window_is_toplevel (window))
7099 /* New area in the non-root parent window, needs invalidation */
7100 diff = cairo_region_copy (old_region);
7101 cairo_region_subtract (diff, new_region);
7103 /* Adjust region to parent window coords */
7104 cairo_region_translate (diff, window->x, window->y);
7106 gdk_window_invalidate_region_full (window->parent, diff, TRUE, CLEAR_BG_ALL);
7108 cairo_region_destroy (diff);
7111 cairo_region_destroy (new_region);
7112 cairo_region_destroy (old_region);
7117 do_child_shapes (GdkWindow *window,
7121 cairo_region_t *region;
7125 r.width = window->width;
7126 r.height = window->height;
7128 region = cairo_region_create_rectangle (&r);
7129 remove_child_area (window, NULL, FALSE, region);
7131 if (merge && window->shape)
7132 cairo_region_subtract (region, window->shape);
7134 gdk_window_shape_combine_region (window, region, 0, 0);
7138 * gdk_window_set_child_shapes:
7139 * @window: a #GdkWindow
7141 * Sets the shape mask of @window to the union of shape masks
7142 * for all children of @window, ignoring the shape mask of @window
7143 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7144 * the shape mask of @window in the masks to be merged.
7147 gdk_window_set_child_shapes (GdkWindow *window)
7149 g_return_if_fail (GDK_IS_WINDOW (window));
7151 do_child_shapes (window, FALSE);
7155 * gdk_window_merge_child_shapes:
7156 * @window: a #GdkWindow
7158 * Merges the shape masks for any child windows into the
7159 * shape mask for @window. i.e. the union of all masks
7160 * for @window and its children will become the new mask
7161 * for @window. See gdk_window_shape_combine_region().
7163 * This function is distinct from gdk_window_set_child_shapes()
7164 * because it includes @window's shape mask in the set of shapes to
7168 gdk_window_merge_child_shapes (GdkWindow *window)
7170 g_return_if_fail (GDK_IS_WINDOW (window));
7172 do_child_shapes (window, TRUE);
7176 * gdk_window_input_shape_combine_region:
7177 * @window: a #GdkWindow
7178 * @shape_region: region of window to be non-transparent
7179 * @offset_x: X position of @shape_region in @window coordinates
7180 * @offset_y: Y position of @shape_region in @window coordinates
7182 * Like gdk_window_shape_combine_region(), but the shape applies
7183 * only to event handling. Mouse events which happen while
7184 * the pointer position corresponds to an unset bit in the
7185 * mask will be passed on the window below @window.
7187 * An input shape is typically used with RGBA windows.
7188 * The alpha channel of the window defines which pixels are
7189 * invisible and allows for nicely antialiased borders,
7190 * and the input shape controls where the window is
7193 * On the X11 platform, this requires version 1.1 of the
7196 * On the Win32 platform, this functionality is not present and the
7197 * function does nothing.
7202 gdk_window_input_shape_combine_region (GdkWindow *window,
7203 const cairo_region_t *shape_region,
7207 GdkWindowImplClass *impl_class;
7209 g_return_if_fail (GDK_IS_WINDOW (window));
7211 if (GDK_WINDOW_DESTROYED (window))
7214 if (window->input_shape)
7215 cairo_region_destroy (window->input_shape);
7219 window->input_shape = cairo_region_copy (shape_region);
7220 cairo_region_translate (window->input_shape, offset_x, offset_y);
7223 window->input_shape = NULL;
7225 if (gdk_window_has_impl (window))
7227 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7228 impl_class->input_shape_combine_region (window, window->input_shape, 0, 0);
7231 /* Pointer may have e.g. moved outside window due to the input mask change */
7232 _gdk_synthesize_crossing_events_for_geometry_change (window);
7236 do_child_input_shapes (GdkWindow *window,
7240 cairo_region_t *region;
7244 r.width = window->width;
7245 r.height = window->height;
7247 region = cairo_region_create_rectangle (&r);
7248 remove_child_area (window, NULL, TRUE, region);
7250 if (merge && window->shape)
7251 cairo_region_subtract (region, window->shape);
7252 if (merge && window->input_shape)
7253 cairo_region_subtract (region, window->input_shape);
7255 gdk_window_input_shape_combine_region (window, region, 0, 0);
7260 * gdk_window_set_child_input_shapes:
7261 * @window: a #GdkWindow
7263 * Sets the input shape mask of @window to the union of input shape masks
7264 * for all children of @window, ignoring the input shape mask of @window
7265 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7266 * the input shape mask of @window in the masks to be merged.
7271 gdk_window_set_child_input_shapes (GdkWindow *window)
7273 g_return_if_fail (GDK_IS_WINDOW (window));
7275 do_child_input_shapes (window, FALSE);
7279 * gdk_window_merge_child_input_shapes:
7280 * @window: a #GdkWindow
7282 * Merges the input shape masks for any child windows into the
7283 * input shape mask for @window. i.e. the union of all input masks
7284 * for @window and its children will become the new input mask
7285 * for @window. See gdk_window_input_shape_combine_region().
7287 * This function is distinct from gdk_window_set_child_input_shapes()
7288 * because it includes @window's input shape mask in the set of
7289 * shapes to be merged.
7294 gdk_window_merge_child_input_shapes (GdkWindow *window)
7296 g_return_if_fail (GDK_IS_WINDOW (window));
7298 do_child_input_shapes (window, TRUE);
7303 * gdk_window_set_static_gravities:
7304 * @window: a #GdkWindow
7305 * @use_static: %TRUE to turn on static gravity
7307 * Set the bit gravity of the given window to static, and flag it so
7308 * all children get static subwindow gravity. This is used if you are
7309 * implementing scary features that involve deep knowledge of the
7310 * windowing system. Don't worry about it unless you have to.
7312 * Return value: %TRUE if the server supports static gravity
7315 gdk_window_set_static_gravities (GdkWindow *window,
7316 gboolean use_static)
7318 GdkWindowImplClass *impl_class;
7320 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7322 if (gdk_window_has_impl (window))
7324 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7325 return impl_class->set_static_gravities (window, use_static);
7332 * gdk_window_get_composited:
7333 * @window: a #GdkWindow
7335 * Determines whether @window is composited.
7337 * See gdk_window_set_composited().
7339 * Returns: %TRUE if the window is composited.
7344 gdk_window_get_composited (GdkWindow *window)
7346 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7348 return window->composited;
7352 * gdk_window_set_composited:
7353 * @window: a #GdkWindow
7354 * @composited: %TRUE to set the window as composited
7356 * Sets a #GdkWindow as composited, or unsets it. Composited
7357 * windows do not automatically have their contents drawn to
7358 * the screen. Drawing is redirected to an offscreen buffer
7359 * and an expose event is emitted on the parent of the composited
7360 * window. It is the responsibility of the parent's expose handler
7361 * to manually merge the off-screen content onto the screen in
7362 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7365 * It only makes sense for child windows to be composited; see
7366 * gdk_window_set_opacity() if you need translucent toplevel
7369 * An additional effect of this call is that the area of this
7370 * window is no longer clipped from regions marked for
7371 * invalidation on its parent. Draws done on the parent
7372 * window are also no longer clipped by the child.
7374 * This call is only supported on some systems (currently,
7375 * only X11 with new enough Xcomposite and Xdamage extensions).
7376 * You must call gdk_display_supports_composite() to check if
7377 * setting a window as composited is supported before
7378 * attempting to do so.
7383 gdk_window_set_composited (GdkWindow *window,
7384 gboolean composited)
7386 GdkDisplay *display;
7387 GdkWindowImplClass *impl_class;
7389 g_return_if_fail (GDK_IS_WINDOW (window));
7391 composited = composited != FALSE;
7393 if (window->composited == composited)
7397 gdk_window_ensure_native (window);
7399 display = gdk_window_get_display (window);
7401 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7403 if (composited && (!gdk_display_supports_composite (display) || !impl_class->set_composited))
7405 g_warning ("gdk_window_set_composited called but "
7406 "compositing is not supported");
7410 impl_class->set_composited (window, composited);
7412 recompute_visible_regions (window, TRUE, FALSE);
7414 if (GDK_WINDOW_IS_MAPPED (window))
7415 gdk_window_invalidate_in_parent (window);
7417 window->composited = composited;
7421 * gdk_window_get_modal_hint:
7422 * @window: A toplevel #GdkWindow.
7424 * Determines whether or not the window manager is hinted that @window
7425 * has modal behaviour.
7427 * Return value: whether or not the window has the modal hint set.
7432 gdk_window_get_modal_hint (GdkWindow *window)
7434 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7436 return window->modal_hint;
7440 * gdk_window_get_accept_focus:
7441 * @window: a toplevel #GdkWindow.
7443 * Determines whether or not the desktop environment shuld be hinted that
7444 * the window does not want to receive input focus.
7446 * Return value: whether or not the window should receive input focus.
7451 gdk_window_get_accept_focus (GdkWindow *window)
7453 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7455 return window->accept_focus;
7459 * gdk_window_get_focus_on_map:
7460 * @window: a toplevel #GdkWindow.
7462 * Determines whether or not the desktop environment should be hinted that the
7463 * window does not want to receive input focus when it is mapped.
7465 * Return value: whether or not the window wants to receive input focus when
7471 gdk_window_get_focus_on_map (GdkWindow *window)
7473 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7475 return window->focus_on_map;
7479 * gdk_window_is_input_only:
7480 * @window: a toplevel #GdkWindow
7482 * Determines whether or not the window is an input only window.
7484 * Return value: %TRUE if @window is input only
7489 gdk_window_is_input_only (GdkWindow *window)
7491 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7493 return window->input_only;
7497 * gdk_window_is_shaped:
7498 * @window: a toplevel #GdkWindow
7500 * Determines whether or not the window is shaped.
7502 * Return value: %TRUE if @window is shaped
7507 gdk_window_is_shaped (GdkWindow *window)
7509 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7511 return window->shaped;
7515 window_get_size_rectangle (GdkWindow *window,
7518 rect->x = rect->y = 0;
7519 rect->width = window->width;
7520 rect->height = window->height;
7523 /* Calculates the real clipping region for a window, in window coordinates,
7524 * taking into account other windows, gc clip region and gc clip mask.
7527 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7528 GdkWindow *base_window,
7529 gboolean do_children,
7530 gint *base_x_offset,
7531 gint *base_y_offset)
7533 GdkRectangle visible_rect;
7534 cairo_region_t *real_clip_region;
7535 gint x_offset, y_offset;
7536 GdkWindow *parentwin, *lastwin;
7543 if (!window->viewable || window->input_only)
7544 return cairo_region_create ();
7546 window_get_size_rectangle (window, &visible_rect);
7548 /* real_clip_region is in window coordinates */
7549 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7551 x_offset = y_offset = 0;
7555 parentwin = lastwin;
7557 parentwin = lastwin->parent;
7559 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7560 for (; parentwin != NULL &&
7561 (parentwin == window || lastwin != base_window);
7562 lastwin = parentwin, parentwin = lastwin->parent)
7565 GdkRectangle real_clip_rect;
7567 if (parentwin != window)
7569 x_offset += lastwin->x;
7570 y_offset += lastwin->y;
7573 /* children is ordered in reverse stack order */
7574 for (cur = parentwin->children;
7575 cur && cur->data != lastwin;
7578 GdkWindow *child = cur->data;
7580 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
7583 /* Ignore offscreen children, as they don't draw in their parent and
7584 * don't take part in the clipping */
7585 if (gdk_window_is_offscreen (child))
7588 window_get_size_rectangle (child, &visible_rect);
7590 /* Convert rect to "window" coords */
7591 visible_rect.x += child->x - x_offset;
7592 visible_rect.y += child->y - y_offset;
7594 /* This shortcut is really necessary for performance when there are a lot of windows */
7595 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7596 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7597 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7598 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7599 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7602 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7605 /* Clip to the parent */
7606 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7607 /* Convert rect to "window" coords */
7608 visible_rect.x += - x_offset;
7609 visible_rect.y += - y_offset;
7611 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7615 *base_x_offset = x_offset;
7617 *base_y_offset = y_offset;
7619 return real_clip_region;
7623 _gdk_window_add_damage (GdkWindow *toplevel,
7624 cairo_region_t *damaged_region)
7626 GdkDisplay *display;
7627 GdkEvent event = { 0, };
7628 event.expose.type = GDK_DAMAGE;
7629 event.expose.window = toplevel;
7630 event.expose.send_event = FALSE;
7631 event.expose.region = damaged_region;
7632 cairo_region_get_extents (event.expose.region, &event.expose.area);
7633 display = gdk_window_get_display (event.expose.window);
7634 _gdk_event_queue_append (display, gdk_event_copy (&event));
7637 /* Gets the toplevel for a window as used for events,
7638 i.e. including offscreen parents */
7640 get_event_parent (GdkWindow *window)
7642 if (gdk_window_is_offscreen (window))
7643 return gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7645 return window->parent;
7648 /* Gets the toplevel for a window as used for events,
7649 i.e. including offscreen parents going up to the native
7652 get_event_toplevel (GdkWindow *window)
7656 while ((parent = get_event_parent (window)) != NULL &&
7657 (parent->window_type != GDK_WINDOW_ROOT))
7664 _gdk_window_event_parent_of (GdkWindow *parent,
7675 w = get_event_parent (w);
7682 update_cursor (GdkDisplay *display,
7685 GdkWindow *cursor_window, *parent, *toplevel;
7686 GdkWindow *pointer_window;
7687 GdkWindowImplClass *impl_class;
7688 GdkPointerWindowInfo *pointer_info;
7689 GdkDeviceGrabInfo *grab;
7692 pointer_info = _gdk_display_get_pointer_info (display, device);
7693 pointer_window = pointer_info->window_under_pointer;
7695 /* We ignore the serials here and just pick the last grab
7696 we've sent, as that would shortly be used anyway. */
7697 grab = _gdk_display_get_last_device_grab (display, device);
7700 /* the pointer is not in a descendant of the grab window */
7701 !_gdk_window_event_parent_of (grab->window, pointer_window))
7703 /* use the cursor from the grab window */
7704 cursor_window = grab->window;
7708 /* otherwise use the cursor from the pointer window */
7709 cursor_window = pointer_window;
7712 /* Find the first window with the cursor actually set, as
7713 the cursor is inherited from the parent */
7714 while (cursor_window->cursor == NULL &&
7715 (parent = get_event_parent (cursor_window)) != NULL &&
7716 parent->window_type != GDK_WINDOW_ROOT)
7717 cursor_window = parent;
7719 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
7722 cursor = cursor_window->cursor;
7724 /* Set all cursors on toplevel, otherwise its tricky to keep track of
7725 * which native window has what cursor set. */
7726 toplevel = get_event_toplevel (pointer_window);
7727 impl_class = GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl);
7728 impl_class->set_device_cursor (toplevel, device, cursor);
7732 point_in_window (GdkWindow *window,
7737 x >= 0 && x < window->width &&
7738 y >= 0 && y < window->height &&
7739 (window->shape == NULL ||
7740 cairo_region_contains_point (window->shape,
7742 (window->input_shape == NULL ||
7743 cairo_region_contains_point (window->input_shape,
7748 convert_native_coords_to_toplevel (GdkWindow *window,
7751 gdouble *toplevel_x,
7752 gdouble *toplevel_y)
7759 while (!gdk_window_is_toplevel (window))
7763 window = window->parent;
7773 convert_toplevel_coords_to_window (GdkWindow *window,
7781 GList *children, *l;
7787 while ((parent = get_event_parent (window)) != NULL &&
7788 (parent->window_type != GDK_WINDOW_ROOT))
7790 children = g_list_prepend (children, window);
7794 for (l = children; l != NULL; l = l->next)
7795 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
7797 g_list_free (children);
7804 pick_embedded_child (GdkWindow *window,
7811 g_signal_emit (window,
7812 signals[PICK_EMBEDDED_CHILD], 0,
7819 _gdk_window_find_child_at (GdkWindow *window,
7824 double child_x, child_y;
7827 if (point_in_window (window, x, y))
7829 /* Children is ordered in reverse stack order, i.e. first is topmost */
7830 for (l = window->children; l != NULL; l = l->next)
7834 if (!GDK_WINDOW_IS_MAPPED (sub))
7837 gdk_window_coords_from_parent ((GdkWindow *)sub,
7839 &child_x, &child_y);
7840 if (point_in_window (sub, child_x, child_y))
7841 return (GdkWindow *)sub;
7844 if (window->num_offscreen_children > 0)
7846 sub = pick_embedded_child (window,
7849 return (GdkWindow *)sub;
7857 _gdk_window_find_descendant_at (GdkWindow *window,
7864 gdouble child_x, child_y;
7868 if (point_in_window (window, x, y))
7873 /* Children is ordered in reverse stack order, i.e. first is topmost */
7874 for (l = window->children; l != NULL; l = l->next)
7878 if (!GDK_WINDOW_IS_MAPPED (sub))
7881 gdk_window_coords_from_parent ((GdkWindow *)sub,
7883 &child_x, &child_y);
7884 if (point_in_window (sub, child_x, child_y))
7894 window->num_offscreen_children > 0)
7896 sub = pick_embedded_child (window,
7902 from_embedder (sub, x, y, &x, &y);
7910 /* Not in window at all */
7924 * @window: a toplevel #GdkWindow
7926 * Emits a short beep associated to @window in the appropriate
7927 * display, if supported. Otherwise, emits a short beep on
7928 * the display just as gdk_display_beep().
7933 gdk_window_beep (GdkWindow *window)
7935 GdkDisplay *display;
7936 GdkWindow *toplevel;
7938 g_return_if_fail (GDK_IS_WINDOW (window));
7940 if (GDK_WINDOW_DESTROYED (window))
7943 toplevel = get_event_toplevel (window);
7944 display = gdk_window_get_display (window);
7948 if (GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl)->beep (toplevel))
7952 /* If windows fail to beep, we beep the display. */
7953 gdk_display_beep (display);
7957 * gdk_window_set_support_multidevice:
7958 * @window: a #GdkWindow.
7959 * @support_multidevice: %TRUE to enable multidevice support in @window.
7961 * This function will enable multidevice features in @window.
7963 * Multidevice aware windows will need to handle properly multiple,
7964 * per device enter/leave events, device grabs and grab ownerships.
7969 gdk_window_set_support_multidevice (GdkWindow *window,
7970 gboolean support_multidevice)
7972 g_return_if_fail (GDK_IS_WINDOW (window));
7974 if (GDK_WINDOW_DESTROYED (window))
7977 if (window->support_multidevice == support_multidevice)
7980 window->support_multidevice = support_multidevice;
7982 /* FIXME: What to do if called when some pointers are inside the window ? */
7986 * gdk_window_get_support_multidevice:
7987 * @window: a #GdkWindow.
7989 * Returns %TRUE if the window is aware of the existence of multiple
7992 * Returns: %TRUE if the window handles multidevice features.
7997 gdk_window_get_support_multidevice (GdkWindow *window)
7999 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8001 if (GDK_WINDOW_DESTROYED (window))
8004 return window->support_multidevice;
8007 static const guint type_masks[] = {
8008 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8009 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8010 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8011 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8012 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8013 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8014 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8015 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8016 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8017 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8018 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8019 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8020 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8021 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8022 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8023 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8024 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8025 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8026 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8027 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8028 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8029 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8030 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8031 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8032 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8033 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8034 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8035 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8036 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8037 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8038 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8039 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8040 0, /* GDK_WINDOW_STATE = 32 */
8041 0, /* GDK_SETTING = 33 */
8042 0, /* GDK_OWNER_CHANGE = 34 */
8043 0, /* GDK_GRAB_BROKEN = 35 */
8044 0, /* GDK_DAMAGE = 36 */
8046 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8048 /* send motion events if the right buttons are down */
8050 update_evmask_for_button_motion (guint evmask,
8051 GdkModifierType mask)
8053 if (evmask & GDK_BUTTON_MOTION_MASK &&
8054 mask & (GDK_BUTTON1_MASK |
8059 evmask |= GDK_POINTER_MOTION_MASK;
8061 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8062 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8063 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8064 evmask |= GDK_POINTER_MOTION_MASK;
8070 is_button_type (GdkEventType type)
8072 return type == GDK_BUTTON_PRESS ||
8073 type == GDK_2BUTTON_PRESS ||
8074 type == GDK_3BUTTON_PRESS ||
8075 type == GDK_BUTTON_RELEASE ||
8080 is_motion_type (GdkEventType type)
8082 return type == GDK_MOTION_NOTIFY ||
8083 type == GDK_ENTER_NOTIFY ||
8084 type == GDK_LEAVE_NOTIFY;
8088 find_common_ancestor (GdkWindow *win1,
8092 GList *path1 = NULL, *path2 = NULL;
8093 GList *list1, *list2;
8096 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8098 path1 = g_list_prepend (path1, tmp);
8099 tmp = get_event_parent (tmp);
8103 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8105 path2 = g_list_prepend (path2, tmp);
8106 tmp = get_event_parent (tmp);
8112 while (list1 && list2 && (list1->data == list2->data))
8115 list1 = g_list_next (list1);
8116 list2 = g_list_next (list2);
8118 g_list_free (path1);
8119 g_list_free (path2);
8125 _gdk_make_event (GdkWindow *window,
8127 GdkEvent *event_in_queue,
8128 gboolean before_event)
8130 GdkEvent *event = gdk_event_new (type);
8132 GdkModifierType the_state;
8134 the_time = gdk_event_get_time (event_in_queue);
8135 gdk_event_get_state (event_in_queue, &the_state);
8137 event->any.window = g_object_ref (window);
8138 event->any.send_event = FALSE;
8139 if (event_in_queue && event_in_queue->any.send_event)
8140 event->any.send_event = TRUE;
8144 case GDK_MOTION_NOTIFY:
8145 event->motion.time = the_time;
8146 event->motion.axes = NULL;
8147 event->motion.state = the_state;
8150 case GDK_BUTTON_PRESS:
8151 case GDK_2BUTTON_PRESS:
8152 case GDK_3BUTTON_PRESS:
8153 case GDK_BUTTON_RELEASE:
8154 event->button.time = the_time;
8155 event->button.axes = NULL;
8156 event->button.state = the_state;
8160 event->scroll.time = the_time;
8161 event->scroll.state = the_state;
8165 case GDK_KEY_RELEASE:
8166 event->key.time = the_time;
8167 event->key.state = the_state;
8170 case GDK_ENTER_NOTIFY:
8171 case GDK_LEAVE_NOTIFY:
8172 event->crossing.time = the_time;
8173 event->crossing.state = the_state;
8176 case GDK_PROPERTY_NOTIFY:
8177 event->property.time = the_time;
8178 event->property.state = the_state;
8181 case GDK_SELECTION_CLEAR:
8182 case GDK_SELECTION_REQUEST:
8183 case GDK_SELECTION_NOTIFY:
8184 event->selection.time = the_time;
8187 case GDK_PROXIMITY_IN:
8188 case GDK_PROXIMITY_OUT:
8189 event->proximity.time = the_time;
8192 case GDK_DRAG_ENTER:
8193 case GDK_DRAG_LEAVE:
8194 case GDK_DRAG_MOTION:
8195 case GDK_DRAG_STATUS:
8196 case GDK_DROP_START:
8197 case GDK_DROP_FINISHED:
8198 event->dnd.time = the_time;
8201 case GDK_FOCUS_CHANGE:
8205 case GDK_CLIENT_EVENT:
8206 case GDK_VISIBILITY_NOTIFY:
8217 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8219 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8222 _gdk_event_queue_append (gdk_window_get_display (window), event);
8228 send_crossing_event (GdkDisplay *display,
8229 GdkWindow *toplevel,
8232 GdkCrossingMode mode,
8233 GdkNotifyType notify_type,
8234 GdkWindow *subwindow,
8236 GdkDevice *source_device,
8239 GdkModifierType mask,
8241 GdkEvent *event_in_queue,
8245 guint32 window_event_mask, type_event_mask;
8246 GdkDeviceGrabInfo *grab;
8247 gboolean block_event = FALSE;
8249 grab = _gdk_display_has_device_grab (display, device, serial);
8252 !grab->owner_events)
8254 /* !owner_event => only report events wrt grab window, ignore rest */
8255 if ((GdkWindow *)window != grab->window)
8257 window_event_mask = grab->event_mask;
8260 window_event_mask = window->event_mask;
8262 if (type == GDK_LEAVE_NOTIFY)
8264 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8265 window->devices_inside = g_list_remove (window->devices_inside, device);
8267 if (!window->support_multidevice && window->devices_inside)
8269 /* Block leave events unless it's the last pointer */
8275 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8277 if (!window->support_multidevice && window->devices_inside)
8279 /* Only emit enter events for the first device */
8283 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8284 gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
8285 !g_list_find (window->devices_inside, device))
8286 window->devices_inside = g_list_prepend (window->devices_inside, device);
8292 if (window_event_mask & type_event_mask)
8294 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8295 gdk_event_set_device (event, device);
8298 gdk_event_set_source_device (event, source_device);
8300 event->crossing.time = time_;
8301 event->crossing.subwindow = subwindow;
8303 g_object_ref (subwindow);
8304 convert_toplevel_coords_to_window ((GdkWindow *)window,
8305 toplevel_x, toplevel_y,
8306 &event->crossing.x, &event->crossing.y);
8307 event->crossing.x_root = toplevel_x + toplevel->x;
8308 event->crossing.y_root = toplevel_y + toplevel->y;
8309 event->crossing.mode = mode;
8310 event->crossing.detail = notify_type;
8311 event->crossing.focus = FALSE;
8312 event->crossing.state = mask;
8317 /* The coordinates are in the toplevel window that src/dest are in.
8318 * src and dest are always (if != NULL) in the same toplevel, as
8319 * we get a leave-notify and set the window_under_pointer to null
8320 * before crossing to another toplevel.
8323 _gdk_synthesize_crossing_events (GdkDisplay *display,
8327 GdkDevice *source_device,
8328 GdkCrossingMode mode,
8331 GdkModifierType mask,
8333 GdkEvent *event_in_queue,
8335 gboolean non_linear)
8338 GdkWindow *win, *last, *next;
8342 GdkWindow *toplevel;
8343 GdkNotifyType notify_type;
8345 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8350 return; /* No crossings generated between src and dest */
8352 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8354 if (a && gdk_window_get_device_events (src, device) == 0)
8357 if (b && gdk_window_get_device_events (dest, device) == 0)
8364 c = find_common_ancestor (a, b);
8366 non_linear |= (c != a) && (c != b);
8368 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8370 toplevel = gdk_window_get_toplevel (a);
8372 /* Traverse up from a to (excluding) c sending leave events */
8374 notify_type = GDK_NOTIFY_NONLINEAR;
8376 notify_type = GDK_NOTIFY_INFERIOR;
8378 notify_type = GDK_NOTIFY_ANCESTOR;
8379 send_crossing_event (display, toplevel,
8380 a, GDK_LEAVE_NOTIFY,
8383 NULL, device, source_device,
8384 toplevel_x, toplevel_y,
8392 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8394 notify_type = GDK_NOTIFY_VIRTUAL;
8397 win = get_event_parent (a);
8398 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8400 send_crossing_event (display, toplevel,
8401 win, GDK_LEAVE_NOTIFY,
8405 device, source_device,
8406 toplevel_x, toplevel_y,
8412 win = get_event_parent (win);
8417 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8419 toplevel = gdk_window_get_toplevel ((GdkWindow *)b);
8421 /* Traverse down from c to b */
8425 win = get_event_parent (b);
8426 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8428 path = g_list_prepend (path, win);
8429 win = get_event_parent (win);
8433 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8435 notify_type = GDK_NOTIFY_VIRTUAL;
8441 list = g_list_next (list);
8447 send_crossing_event (display, toplevel,
8448 win, GDK_ENTER_NOTIFY,
8452 device, source_device,
8453 toplevel_x, toplevel_y,
8463 notify_type = GDK_NOTIFY_NONLINEAR;
8465 notify_type = GDK_NOTIFY_ANCESTOR;
8467 notify_type = GDK_NOTIFY_INFERIOR;
8469 send_crossing_event (display, toplevel,
8470 b, GDK_ENTER_NOTIFY,
8474 device, source_device,
8475 toplevel_x, toplevel_y,
8482 /* Returns the window inside the event window with the pointer in it
8483 * at the specified coordinates, or NULL if its not in any child of
8484 * the toplevel. It also takes into account !owner_events grabs.
8487 get_pointer_window (GdkDisplay *display,
8488 GdkWindow *event_window,
8494 GdkWindow *pointer_window;
8495 GdkDeviceGrabInfo *grab;
8496 GdkPointerWindowInfo *pointer_info;
8498 pointer_info = _gdk_display_get_pointer_info (display, device);
8500 if (event_window == pointer_info->toplevel_under_pointer)
8502 _gdk_window_find_descendant_at (event_window,
8503 toplevel_x, toplevel_y,
8506 pointer_window = NULL;
8508 grab = _gdk_display_has_device_grab (display, device, serial);
8510 !grab->owner_events &&
8511 pointer_window != grab->window)
8512 pointer_window = NULL;
8514 return pointer_window;
8518 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8522 GdkPointerWindowInfo *device_info;
8524 device_info = _gdk_display_get_pointer_info (display, device);
8526 if (device_info->window_under_pointer)
8527 g_object_unref (device_info->window_under_pointer);
8528 device_info->window_under_pointer = window;
8532 g_object_ref (window);
8533 update_cursor (display, device);
8536 _gdk_display_enable_motion_hints (display, device);
8541 * @window: the #GdkWindow which will own the grab (the grab window).
8542 * @owner_events: if %FALSE then all pointer events are reported with respect to
8543 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8544 * events for this application are reported as normal, but pointer events outside
8545 * this application are reported with respect to @window and only if selected by
8546 * @event_mask. In either mode, unreported events are discarded.
8547 * @event_mask: specifies the event mask, which is used in accordance with
8548 * @owner_events. Note that only pointer events (i.e. button and motion events)
8550 * @confine_to: (allow-none): If non-%NULL, the pointer will be confined to this
8551 * window during the grab. If the pointer is outside @confine_to, it will
8552 * automatically be moved to the closest edge of @confine_to and enter
8553 * and leave events will be generated as necessary.
8554 * @cursor: (allow-none): the cursor to display while the grab is active. If this is %NULL then
8555 * the normal cursors are used for @window and its descendants, and the cursor
8556 * for @window is used for all other windows.
8557 * @time_: the timestamp of the event which led to this pointer grab. This usually
8558 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8559 * the time isn't known.
8561 * Grabs the pointer (usually a mouse) so that all events are passed to this
8562 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8563 * the grab window becomes unviewable.
8564 * This overrides any previous pointer grab by this client.
8566 * Pointer grabs are used for operations which need complete control over mouse
8567 * events, even if the mouse leaves the application.
8568 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8569 * the #GtkHPaned and #GtkVPaned widgets.
8571 * Note that if the event mask of an X window has selected both button press and
8572 * button release events, then a button press event will cause an automatic
8573 * pointer grab until the button is released.
8574 * X does this automatically since most applications expect to receive button
8575 * press and release events in pairs.
8576 * It is equivalent to a pointer grab on the window with @owner_events set to
8579 * If you set up anything at the time you take the grab that needs to be cleaned
8580 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8581 * are emitted when the grab ends unvoluntarily.
8583 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8585 * Deprecated: 3.0: Use gdk_device_grab() instead.
8588 gdk_pointer_grab (GdkWindow * window,
8589 gboolean owner_events,
8590 GdkEventMask event_mask,
8591 GdkWindow * confine_to,
8596 GdkDisplay *display;
8597 GdkDeviceManager *device_manager;
8599 GdkGrabStatus res = 0;
8601 GList *devices, *dev;
8603 g_return_val_if_fail (window != NULL, 0);
8604 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8605 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8607 /* We need a native window for confine to to work, ensure we have one */
8610 if (!gdk_window_ensure_native (confine_to))
8612 g_warning ("Can't confine to grabbed window, not native");
8617 /* Non-viewable client side window => fail */
8618 if (!_gdk_window_has_impl (window) &&
8619 !gdk_window_is_viewable (window))
8620 return GDK_GRAB_NOT_VIEWABLE;
8622 native = gdk_window_get_toplevel (window);
8623 while (gdk_window_is_offscreen (native))
8625 native = gdk_offscreen_window_get_embedder (native);
8627 if (native == NULL ||
8628 (!_gdk_window_has_impl (native) &&
8629 !gdk_window_is_viewable (native)))
8630 return GDK_GRAB_NOT_VIEWABLE;
8632 native = gdk_window_get_toplevel (native);
8635 display = gdk_window_get_display (window);
8637 serial = _gdk_display_get_next_serial (display);
8638 device_manager = gdk_display_get_device_manager (display);
8639 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8641 /* FIXME: Should this be generic to all backends? */
8642 /* FIXME: What happens with extended devices? */
8643 for (dev = devices; dev; dev = dev->next)
8647 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
8650 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
8653 get_native_grab_event_mask (event_mask),
8658 if (res == GDK_GRAB_SUCCESS)
8659 _gdk_display_add_device_grab (display,
8671 /* FIXME: handle errors when grabbing */
8673 g_list_free (devices);
8679 * gdk_keyboard_grab:
8680 * @window: the #GdkWindow which will own the grab (the grab window).
8681 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8682 * @window. If %TRUE then keyboard events for this application are
8683 * reported as normal, but keyboard events outside this application
8684 * are reported with respect to @window. Both key press and key
8685 * release events are always reported, independant of the event mask
8686 * set by the application.
8687 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8690 * Grabs the keyboard so that all events are passed to this
8691 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8692 * This overrides any previous keyboard grab by this client.
8694 * If you set up anything at the time you take the grab that needs to be cleaned
8695 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8696 * are emitted when the grab ends unvoluntarily.
8698 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8700 * Deprecated: 3.0: Use gdk_device_grab() instead.
8703 gdk_keyboard_grab (GdkWindow *window,
8704 gboolean owner_events,
8708 GdkDisplay *display;
8709 GdkDeviceManager *device_manager;
8711 GdkGrabStatus res = 0;
8713 GList *devices, *dev;
8715 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8717 /* Non-viewable client side window => fail */
8718 if (!_gdk_window_has_impl (window) &&
8719 !gdk_window_is_viewable (window))
8720 return GDK_GRAB_NOT_VIEWABLE;
8722 native = gdk_window_get_toplevel (window);
8724 while (gdk_window_is_offscreen (native))
8726 native = gdk_offscreen_window_get_embedder (native);
8728 if (native == NULL ||
8729 (!_gdk_window_has_impl (native) &&
8730 !gdk_window_is_viewable (native)))
8731 return GDK_GRAB_NOT_VIEWABLE;
8733 native = gdk_window_get_toplevel (native);
8736 display = gdk_window_get_display (window);
8737 serial = _gdk_display_get_next_serial (display);
8738 device_manager = gdk_display_get_device_manager (display);
8739 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8741 /* FIXME: Should this be generic to all backends? */
8742 /* FIXME: What happens with extended devices? */
8743 for (dev = devices; dev; dev = dev->next)
8747 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
8750 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
8753 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
8758 if (res == GDK_GRAB_SUCCESS)
8759 _gdk_display_add_device_grab (display,
8770 /* FIXME: handle errors when grabbing */
8772 g_list_free (devices);
8778 * gdk_window_geometry_changed:
8779 * @window: an embedded offscreen #GdkWindow
8781 * This function informs GDK that the geometry of an embedded
8782 * offscreen window has changed. This is necessary for GDK to keep
8783 * track of which offscreen window the pointer is in.
8788 gdk_window_geometry_changed (GdkWindow *window)
8790 _gdk_synthesize_crossing_events_for_geometry_change (window);
8794 source_events_device_added (GdkDeviceManager *device_manager,
8799 GdkEventMask event_mask;
8800 GdkInputSource source;
8802 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_FLOATING)
8806 source = gdk_device_get_source (device);
8808 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
8809 GINT_TO_POINTER (source)));
8811 gdk_window_set_device_events (window, device, event_mask);
8815 source_events_device_changed (GdkDeviceManager *device_manager,
8820 GdkInputSource source;
8821 GdkEventMask event_mask;
8825 type = gdk_device_get_device_type (device);
8826 source = gdk_device_get_source (device);
8828 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
8829 GINT_TO_POINTER (source)));
8834 if (type == GDK_DEVICE_TYPE_FLOATING)
8836 /* The device was just floated, enable its event mask */
8837 gdk_window_set_device_events (window, device, event_mask);
8839 else if (type == GDK_DEVICE_TYPE_SLAVE)
8840 gdk_window_set_device_events (window, device, 0);
8844 * gdk_window_set_source_events:
8845 * @window: a #GdkWindow
8846 * @source: a #GdkInputSource to define the source class.
8847 * @event_mask: event mask for @window
8849 * Sets the event mask for any floating device (i.e. not attached to any
8850 * visible pointer) that has the source defined as @source. This event
8851 * mask will be applied both to currently existing, newly added devices
8852 * after this call, and devices being attached/detached.
8857 gdk_window_set_source_events (GdkWindow *window,
8858 GdkInputSource source,
8859 GdkEventMask event_mask)
8861 GdkDeviceManager *device_manager;
8862 GdkDisplay *display;
8866 g_return_if_fail (GDK_IS_WINDOW (window));
8868 display = gdk_window_get_display (window);
8869 device_manager = gdk_display_get_device_manager (display);
8871 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
8873 /* Set event mask for existing devices */
8874 for (d = devices; d; d = d->next)
8876 GdkDevice *device = d->data;
8878 if (source == gdk_device_get_source (device))
8879 gdk_window_set_device_events (window, device, event_mask);
8882 g_list_free (devices);
8884 /* Update accounting */
8885 if (G_UNLIKELY (!window->source_event_masks))
8886 window->source_event_masks = g_hash_table_new (NULL, NULL);
8889 g_hash_table_insert (window->source_event_masks,
8890 GUINT_TO_POINTER (source),
8891 GUINT_TO_POINTER (event_mask));
8893 g_hash_table_remove (window->source_event_masks,
8894 GUINT_TO_POINTER (source));
8896 size = g_hash_table_size (window->source_event_masks);
8898 /* Update handler if needed */
8899 if (!window->device_added_handler_id && size > 0)
8901 window->device_added_handler_id =
8902 g_signal_connect (device_manager, "device-added",
8903 G_CALLBACK (source_events_device_added), window);
8904 window->device_changed_handler_id =
8905 g_signal_connect (device_manager, "device-changed",
8906 G_CALLBACK (source_events_device_changed), window);
8908 else if (window->device_added_handler_id && size == 0)
8909 g_signal_handler_disconnect (device_manager, window->device_added_handler_id);
8913 * gdk_window_get_source_events:
8914 * @window: a #GdkWindow
8915 * @source: a #GdkInputSource to define the source class.
8917 * Returns the event mask for @window corresponding to the device class specified
8920 * Returns: source event mask for @window
8923 gdk_window_get_source_events (GdkWindow *window,
8924 GdkInputSource source)
8926 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8928 return GPOINTER_TO_UINT (g_hash_table_lookup (window->source_event_masks,
8929 GUINT_TO_POINTER (source)));
8933 do_synthesize_crossing_event (gpointer data)
8935 GdkDisplay *display;
8936 GdkWindow *changed_toplevel;
8937 GHashTableIter iter;
8938 gpointer key, value;
8941 changed_toplevel = data;
8943 changed_toplevel->synthesize_crossing_event_queued = FALSE;
8945 if (GDK_WINDOW_DESTROYED (changed_toplevel))
8948 display = gdk_window_get_display (changed_toplevel);
8949 serial = _gdk_display_get_next_serial (display);
8950 g_hash_table_iter_init (&iter, display->pointers_info);
8952 while (g_hash_table_iter_next (&iter, &key, &value))
8954 GdkWindow *new_window_under_pointer;
8955 GdkPointerWindowInfo *pointer_info = value;
8956 GdkDevice *device = key;
8958 if (changed_toplevel == pointer_info->toplevel_under_pointer)
8960 new_window_under_pointer =
8961 get_pointer_window (display, changed_toplevel,
8963 pointer_info->toplevel_x,
8964 pointer_info->toplevel_y,
8966 if (new_window_under_pointer != pointer_info->window_under_pointer)
8968 _gdk_synthesize_crossing_events (display,
8969 pointer_info->window_under_pointer,
8970 new_window_under_pointer,
8972 GDK_CROSSING_NORMAL,
8973 pointer_info->toplevel_x,
8974 pointer_info->toplevel_y,
8975 pointer_info->state,
8980 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
8989 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
8991 GdkWindow *toplevel;
8993 toplevel = get_event_toplevel (changed_window);
8995 if (!toplevel->synthesize_crossing_event_queued)
8997 toplevel->synthesize_crossing_event_queued = TRUE;
8999 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9000 do_synthesize_crossing_event,
9001 g_object_ref (toplevel),
9006 /* Don't use for crossing events */
9008 get_event_window (GdkDisplay *display,
9010 GdkWindow *pointer_window,
9012 GdkModifierType mask,
9017 GdkWindow *grab_window;
9018 GdkDeviceGrabInfo *grab;
9020 grab = _gdk_display_has_device_grab (display, device, serial);
9022 if (grab != NULL && !grab->owner_events)
9024 evmask = grab->event_mask;
9025 evmask = update_evmask_for_button_motion (evmask, mask);
9027 grab_window = grab->window;
9029 if (evmask & type_masks[type])
9032 *evmask_out = evmask;
9039 while (pointer_window != NULL)
9041 evmask = pointer_window->event_mask;
9042 evmask = update_evmask_for_button_motion (evmask, mask);
9044 if (evmask & type_masks[type])
9047 *evmask_out = evmask;
9048 return pointer_window;
9051 pointer_window = get_event_parent (pointer_window);
9057 evmask = grab->event_mask;
9058 evmask = update_evmask_for_button_motion (evmask, mask);
9060 if (evmask & type_masks[type])
9063 *evmask_out = evmask;
9064 return grab->window;
9074 proxy_pointer_event (GdkDisplay *display,
9075 GdkEvent *source_event,
9078 GdkWindow *toplevel_window, *event_window;
9079 GdkWindow *pointer_window;
9080 GdkPointerWindowInfo *pointer_info;
9081 GdkDevice *device, *source_device;
9084 gdouble toplevel_x, toplevel_y;
9086 gboolean non_linear;
9088 event_window = source_event->any.window;
9089 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9090 gdk_event_get_state (source_event, &state);
9091 time_ = gdk_event_get_time (source_event);
9092 device = gdk_event_get_device (source_event);
9093 source_device = gdk_event_get_source_device (source_event);
9094 pointer_info = _gdk_display_get_pointer_info (display, device);
9095 toplevel_window = convert_native_coords_to_toplevel (event_window,
9096 toplevel_x, toplevel_y,
9097 &toplevel_x, &toplevel_y);
9100 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9101 source_event->type == GDK_ENTER_NOTIFY) &&
9102 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9103 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9106 /* If we get crossing events with subwindow unexpectedly being NULL
9107 that means there is a native subwindow that gdk doesn't know about.
9108 We track these and forward them, with the correct virtual window
9110 This is important to get right, as metacity uses gdk for the frame
9111 windows, but gdk doesn't know about the client windows reparented
9113 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9114 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9115 (source_event->type == GDK_ENTER_NOTIFY &&
9116 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9117 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9118 source_event->crossing.subwindow == NULL)
9120 /* Left for an unknown (to gdk) subwindow */
9122 /* Send leave events from window under pointer to event window
9123 that will get the subwindow == NULL window */
9124 _gdk_synthesize_crossing_events (display,
9125 pointer_info->window_under_pointer,
9127 device, source_device,
9128 source_event->crossing.mode,
9129 toplevel_x, toplevel_y,
9135 /* Send subwindow == NULL event */
9136 send_crossing_event (display,
9140 source_event->crossing.mode,
9141 source_event->crossing.detail,
9143 device, source_device,
9144 toplevel_x, toplevel_y,
9149 _gdk_display_set_window_under_pointer (display, device, NULL);
9153 pointer_window = get_pointer_window (display, toplevel_window, device,
9154 toplevel_x, toplevel_y, serial);
9156 if (((source_event->type == GDK_ENTER_NOTIFY &&
9157 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9158 (source_event->type == GDK_LEAVE_NOTIFY &&
9159 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9160 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9161 source_event->crossing.subwindow == NULL)
9163 /* Entered from an unknown (to gdk) subwindow */
9165 /* Send subwindow == NULL event */
9166 send_crossing_event (display,
9170 source_event->crossing.mode,
9171 source_event->crossing.detail,
9173 device, source_device,
9174 toplevel_x, toplevel_y,
9179 /* Send enter events from event window to pointer_window */
9180 _gdk_synthesize_crossing_events (display,
9183 device, source_device,
9184 source_event->crossing.mode,
9185 toplevel_x, toplevel_y,
9188 serial, non_linear);
9189 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9193 if (pointer_info->window_under_pointer != pointer_window)
9195 /* Either a toplevel crossing notify that ended up inside a child window,
9196 or a motion notify that got into another child window */
9198 /* Different than last time, send crossing events */
9199 _gdk_synthesize_crossing_events (display,
9200 pointer_info->window_under_pointer,
9202 device, source_device,
9203 GDK_CROSSING_NORMAL,
9204 toplevel_x, toplevel_y,
9207 serial, non_linear);
9208 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9210 else if (source_event->type == GDK_MOTION_NOTIFY)
9212 GdkWindow *event_win;
9216 event_win = get_event_window (display,
9225 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9226 gdk_window_get_device_events (event_win, device) == 0)
9232 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9234 gulong *device_serial;
9236 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9238 if (!device_serial ||
9239 (*device_serial != 0 &&
9240 serial < *device_serial))
9241 event_win = NULL; /* Ignore event */
9245 *device_serial = G_MAXULONG;
9249 if (event_win && !display->ignore_core_events)
9251 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9252 event->motion.time = time_;
9253 convert_toplevel_coords_to_window (event_win,
9254 toplevel_x, toplevel_y,
9255 &event->motion.x, &event->motion.y);
9256 event->motion.x_root = source_event->motion.x_root;
9257 event->motion.y_root = source_event->motion.y_root;
9258 event->motion.state = state;
9259 event->motion.is_hint = is_hint;
9260 event->motion.device = source_event->motion.device;
9261 event->motion.axes = g_memdup (source_event->motion.axes,
9262 sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
9263 gdk_event_set_source_device (event, source_device);
9267 /* unlink all move events from queue.
9268 We handle our own, including our emulated masks. */
9272 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9273 GDK_BUTTON2_MASK | \
9274 GDK_BUTTON3_MASK | \
9275 GDK_BUTTON4_MASK | \
9279 proxy_button_event (GdkEvent *source_event,
9282 GdkWindow *toplevel_window, *event_window;
9283 GdkWindow *event_win;
9284 GdkWindow *pointer_window;
9290 gdouble toplevel_x, toplevel_y;
9291 GdkDisplay *display;
9293 GdkDevice *device, *source_device;
9295 type = source_event->any.type;
9296 event_window = source_event->any.window;
9297 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9298 gdk_event_get_state (source_event, &state);
9299 time_ = gdk_event_get_time (source_event);
9300 device = gdk_event_get_device (source_event);
9301 source_device = gdk_event_get_source_device (source_event);
9302 display = gdk_window_get_display (source_event->any.window);
9303 toplevel_window = convert_native_coords_to_toplevel (event_window,
9304 toplevel_x, toplevel_y,
9305 &toplevel_x, &toplevel_y);
9307 if (type == GDK_BUTTON_PRESS &&
9308 !source_event->any.send_event &&
9309 _gdk_display_has_device_grab (display, device, serial) == NULL)
9312 _gdk_window_find_descendant_at (toplevel_window,
9313 toplevel_x, toplevel_y,
9316 /* Find the event window, that gets the grab */
9319 (parent = get_event_parent (w)) != NULL &&
9320 parent->window_type != GDK_WINDOW_ROOT)
9322 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9326 pointer_window = (GdkWindow *)w;
9328 _gdk_display_add_device_grab (display,
9334 gdk_window_get_events (pointer_window),
9338 _gdk_display_device_grab_update (display, device, source_device, serial);
9341 pointer_window = get_pointer_window (display, toplevel_window, device,
9342 toplevel_x, toplevel_y,
9345 event_win = get_event_window (display,
9351 if (event_win == NULL || display->ignore_core_events)
9354 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9355 gdk_window_get_device_events (event_win, device) == 0)
9358 event = _gdk_make_event (event_win, type, source_event, FALSE);
9362 case GDK_BUTTON_PRESS:
9363 case GDK_BUTTON_RELEASE:
9364 event->button.button = source_event->button.button;
9365 convert_toplevel_coords_to_window (event_win,
9366 toplevel_x, toplevel_y,
9367 &event->button.x, &event->button.y);
9368 event->button.x_root = source_event->button.x_root;
9369 event->button.y_root = source_event->button.y_root;
9370 event->button.state = state;
9371 event->button.device = source_event->button.device;
9372 event->button.axes = g_memdup (source_event->button.axes,
9373 sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
9375 gdk_event_set_source_device (event, source_device);
9377 if (type == GDK_BUTTON_PRESS)
9378 _gdk_event_button_generate (display, event);
9382 event->scroll.direction = source_event->scroll.direction;
9383 convert_toplevel_coords_to_window (event_win,
9384 toplevel_x, toplevel_y,
9385 &event->scroll.x, &event->scroll.y);
9386 event->scroll.x_root = source_event->scroll.x_root;
9387 event->scroll.y_root = source_event->scroll.y_root;
9388 event->scroll.state = state;
9389 event->scroll.device = source_event->scroll.device;
9390 gdk_event_set_source_device (event, source_device);
9397 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9400 #ifdef DEBUG_WINDOW_PRINTING
9402 gdk_window_print (GdkWindow *window,
9406 const char *window_types[] = {
9416 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9417 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9418 window->x, window->y,
9419 window->width, window->height
9422 if (gdk_window_has_impl (window))
9424 #ifdef GDK_WINDOWING_X11
9425 g_print (" impl(0x%lx)", gdk_x11_window_get_xid (window));
9429 if (window->window_type != GDK_WINDOW_CHILD)
9430 g_print (" %s", window_types[window->window_type]);
9432 if (window->input_only)
9433 g_print (" input-only");
9436 g_print (" shaped");
9438 if (!gdk_window_is_visible ((GdkWindow *)window))
9439 g_print (" hidden");
9441 g_print (" abs[%d,%d]",
9442 window->abs_x, window->abs_y);
9444 cairo_region_get_extents (window->clip_region, &r);
9445 if (cairo_region_is_empty (window->clip_region))
9446 g_print (" clipbox[empty]");
9448 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9455 gdk_window_print_tree (GdkWindow *window,
9457 gboolean include_input_only)
9461 if (window->input_only && !include_input_only)
9464 gdk_window_print (window, indent);
9466 for (l = window->children; l != NULL; l = l->next)
9467 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9470 #endif /* DEBUG_WINDOW_PRINTING */
9473 _gdk_windowing_got_event (GdkDisplay *display,
9478 GdkWindow *event_window;
9480 gboolean unlink_event;
9481 guint old_state, old_button;
9482 GdkDeviceGrabInfo *button_release_grab;
9483 GdkPointerWindowInfo *pointer_info;
9484 GdkDevice *device, *source_device;
9485 gboolean is_toplevel;
9487 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9488 display->last_event_time = gdk_event_get_time (event);
9490 device = gdk_event_get_device (event);
9491 source_device = gdk_event_get_source_device (event);
9497 g_object_get (device, "input-mode", &mode, NULL);
9498 _gdk_display_device_grab_update (display, device, source_device, serial);
9500 if (mode == GDK_MODE_DISABLED ||
9501 !_gdk_display_check_grab_ownership (display, device, serial))
9503 /* Device events are blocked by another
9504 * device grab, or the device is disabled
9506 unlink_event = TRUE;
9511 event_window = event->any.window;
9515 pointer_info = _gdk_display_get_pointer_info (display, device);
9517 #ifdef DEBUG_WINDOW_PRINTING
9518 if (event->type == GDK_KEY_PRESS &&
9519 (event->key.keyval == 0xa7 ||
9520 event->key.keyval == 0xbd))
9522 gdk_window_print_tree (event_window, 0,
9523 event->key.keyval == 0xbd);
9527 if (event->type == GDK_VISIBILITY_NOTIFY)
9529 event_window->native_visibility = event->visibility.state;
9530 gdk_window_update_visibility_recursively (event_window,
9535 if (!(is_button_type (event->type) ||
9536 is_motion_type (event->type)) ||
9537 event_window->window_type == GDK_WINDOW_ROOT)
9540 is_toplevel = gdk_window_is_toplevel (event_window);
9542 if ((event->type == GDK_ENTER_NOTIFY ||
9543 event->type == GDK_LEAVE_NOTIFY) &&
9544 (event->crossing.mode == GDK_CROSSING_GRAB ||
9545 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9546 (_gdk_display_has_device_grab (display, device, serial) ||
9547 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9549 /* We synthesize all crossing events due to grabs ourselves,
9550 * so we ignore the native ones caused by our native pointer_grab
9551 * calls. Otherwise we would proxy these crossing event and cause
9552 * multiple copies of crossing events for grabs.
9554 * We do want to handle grabs from other clients though, as for
9555 * instance alt-tab in metacity causes grabs like these and
9556 * we want to handle those. Thus the has_pointer_grab check.
9558 * Implicit grabs on child windows create some grabbing events
9559 * that are sent before the button press. This means we can't
9560 * detect these with the has_pointer_grab check (as the implicit
9561 * grab is only noticed when we get button press event), so we
9562 * detect these events by checking for INFERIOR enter or leave
9563 * events. These should never be a problem to filter out.
9566 /* We ended up in this window after some (perhaps other clients)
9567 grab, so update the toplevel_under_window state */
9569 event->type == GDK_ENTER_NOTIFY &&
9570 event->crossing.mode == GDK_CROSSING_UNGRAB)
9572 if (pointer_info->toplevel_under_pointer)
9573 g_object_unref (pointer_info->toplevel_under_pointer);
9574 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9577 unlink_event = TRUE;
9581 /* Track toplevel_under_pointer */
9584 if (event->type == GDK_ENTER_NOTIFY &&
9585 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9587 if (pointer_info->toplevel_under_pointer)
9588 g_object_unref (pointer_info->toplevel_under_pointer);
9589 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9591 else if (event->type == GDK_LEAVE_NOTIFY &&
9592 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9593 pointer_info->toplevel_under_pointer == event_window)
9595 if (pointer_info->toplevel_under_pointer)
9596 g_object_unref (pointer_info->toplevel_under_pointer);
9597 pointer_info->toplevel_under_pointer = NULL;
9601 /* Store last pointer window and position/state */
9602 old_state = pointer_info->state;
9603 old_button = pointer_info->button;
9605 gdk_event_get_coords (event, &x, &y);
9606 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9607 pointer_info->toplevel_x = x;
9608 pointer_info->toplevel_y = y;
9609 gdk_event_get_state (event, &pointer_info->state);
9610 if (event->type == GDK_BUTTON_PRESS ||
9611 event->type == GDK_BUTTON_RELEASE)
9612 pointer_info->button = event->button.button;
9615 (pointer_info->state != old_state ||
9616 pointer_info->button != old_button))
9617 _gdk_display_enable_motion_hints (display, device);
9619 unlink_event = FALSE;
9620 if (is_motion_type (event->type))
9621 unlink_event = proxy_pointer_event (display,
9624 else if (is_button_type (event->type))
9625 unlink_event = proxy_button_event (event,
9628 if (event->type == GDK_BUTTON_RELEASE &&
9629 !event->any.send_event)
9631 button_release_grab =
9632 _gdk_display_has_device_grab (display, device, serial);
9633 if (button_release_grab &&
9634 button_release_grab->implicit &&
9635 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9637 button_release_grab->serial_end = serial;
9638 button_release_grab->implicit_ungrab = FALSE;
9639 _gdk_display_device_grab_update (display, device, source_device, serial);
9646 _gdk_event_queue_remove_link (display, event_link);
9647 g_list_free_1 (event_link);
9648 gdk_event_free (event);
9653 * gdk_window_create_similar_surface:
9654 * @window: window to make new surface similar to
9655 * @content: the content for the new surface
9656 * @width: width of the new surface
9657 * @height: height of the new surface
9659 * Create a new surface that is as compatible as possible with the
9660 * given @window. For example the new surface will have the same
9661 * fallback resolution and font options as @window. Generally, the new
9662 * surface will also use the same backend as @window, unless that is
9663 * not possible for some reason. The type of the returned surface may
9664 * be examined with cairo_surface_get_type().
9666 * Initially the surface contents are all 0 (transparent if contents
9667 * have transparency, black otherwise.)
9669 * Returns: a pointer to the newly allocated surface. The caller
9670 * owns the surface and should call cairo_surface_destroy() when done
9673 * This function always returns a valid pointer, but it will return a
9674 * pointer to a "nil" surface if @other is already in an error state
9675 * or any other error occurs.
9680 gdk_window_create_similar_surface (GdkWindow * window,
9681 cairo_content_t content,
9685 cairo_surface_t *window_surface, *surface;
9687 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9689 window_surface = _gdk_window_ref_cairo_surface (window);
9691 switch (_gdk_rendering_mode)
9693 case GDK_RENDERING_MODE_RECORDING:
9695 cairo_rectangle_t rect = { 0, 0, width, height };
9696 surface = cairo_recording_surface_create (content, &rect);
9699 case GDK_RENDERING_MODE_IMAGE:
9700 surface = cairo_image_surface_create (content == CAIRO_CONTENT_COLOR ? CAIRO_FORMAT_RGB24 :
9701 content == CAIRO_CONTENT_ALPHA ? CAIRO_FORMAT_A8 : CAIRO_FORMAT_ARGB32,
9704 case GDK_RENDERING_MODE_SIMILAR:
9706 surface = cairo_surface_create_similar (window_surface,
9712 cairo_surface_destroy (window_surface);
9719 * @window: a #GdkWindow
9720 * @timestamp: timestamp of the event triggering the window focus
9722 * Sets keyboard focus to @window. In most cases, gtk_window_present()
9723 * should be used on a #GtkWindow, rather than calling this function.
9727 gdk_window_focus (GdkWindow *window,
9730 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->focus (window, timestamp);
9734 * gdk_window_set_type_hint:
9735 * @window: A toplevel #GdkWindow
9736 * @hint: A hint of the function this window will have
9738 * The application can use this call to provide a hint to the window
9739 * manager about the functionality of a window. The window manager
9740 * can use this information when determining the decoration and behaviour
9743 * The hint must be set before the window is mapped.
9746 gdk_window_set_type_hint (GdkWindow *window,
9747 GdkWindowTypeHint hint)
9749 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_type_hint (window, hint);
9753 * gdk_window_get_type_hint:
9754 * @window: A toplevel #GdkWindow
9756 * This function returns the type hint set for a window.
9758 * Return value: The type hint set for @window
9763 gdk_window_get_type_hint (GdkWindow *window)
9765 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_type_hint (window);
9769 * gdk_window_set_modal_hint:
9770 * @window: A toplevel #GdkWindow
9771 * @modal: %TRUE if the window is modal, %FALSE otherwise.
9773 * The application can use this hint to tell the window manager
9774 * that a certain window has modal behaviour. The window manager
9775 * can use this information to handle modal windows in a special
9778 * You should only use this on windows for which you have
9779 * previously called gdk_window_set_transient_for()
9782 gdk_window_set_modal_hint (GdkWindow *window,
9785 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_modal_hint (window, modal);
9789 * gdk_window_set_skip_taskbar_hint:
9790 * @window: a toplevel #GdkWindow
9791 * @skips_taskbar: %TRUE to skip the taskbar
9793 * Toggles whether a window should appear in a task list or window
9794 * list. If a window's semantic type as specified with
9795 * gdk_window_set_type_hint() already fully describes the window, this
9796 * function should <emphasis>not</emphasis> be called in addition,
9797 * instead you should allow the window to be treated according to
9798 * standard policy for its semantic type.
9803 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
9804 gboolean skips_taskbar)
9806 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_taskbar_hint (window, skips_taskbar);
9810 * gdk_window_set_skip_pager_hint:
9811 * @window: a toplevel #GdkWindow
9812 * @skips_pager: %TRUE to skip the pager
9814 * Toggles whether a window should appear in a pager (workspace
9815 * switcher, or other desktop utility program that displays a small
9816 * thumbnail representation of the windows on the desktop). If a
9817 * window's semantic type as specified with gdk_window_set_type_hint()
9818 * already fully describes the window, this function should
9819 * <emphasis>not</emphasis> be called in addition, instead you should
9820 * allow the window to be treated according to standard policy for
9821 * its semantic type.
9826 gdk_window_set_skip_pager_hint (GdkWindow *window,
9827 gboolean skips_pager)
9829 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_pager_hint (window, skips_pager);
9833 * gdk_window_set_urgency_hint:
9834 * @window: a toplevel #GdkWindow
9835 * @urgent: %TRUE if the window is urgent
9837 * Toggles whether a window needs the user's
9843 gdk_window_set_urgency_hint (GdkWindow *window,
9846 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_urgency_hint (window, urgent);
9850 * gdk_window_set_geometry_hints:
9851 * @window: a toplevel #GdkWindow
9852 * @geometry: geometry hints
9853 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
9855 * Sets the geometry hints for @window. Hints flagged in @geom_mask
9856 * are set, hints not flagged in @geom_mask are unset.
9857 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
9859 * This function provides hints to the windowing system about
9860 * acceptable sizes for a toplevel window. The purpose of
9861 * this is to constrain user resizing, but the windowing system
9862 * will typically (but is not required to) also constrain the
9863 * current size of the window to the provided values and
9864 * constrain programatic resizing via gdk_window_resize() or
9865 * gdk_window_move_resize().
9867 * Note that on X11, this effect has no effect on windows
9868 * of type %GDK_WINDOW_TEMP or windows where override redirect
9869 * has been turned on via gdk_window_set_override_redirect()
9870 * since these windows are not resizable by the user.
9872 * Since you can't count on the windowing system doing the
9873 * constraints for programmatic resizes, you should generally
9874 * call gdk_window_constrain_size() yourself to determine
9875 * appropriate sizes.
9879 gdk_window_set_geometry_hints (GdkWindow *window,
9880 const GdkGeometry *geometry,
9881 GdkWindowHints geom_mask)
9883 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_geometry_hints (window, geometry, geom_mask);
9887 * gdk_window_set_title:
9888 * @window: a toplevel #GdkWindow
9889 * @title: title of @window
9891 * Sets the title of a toplevel window, to be displayed in the titlebar.
9892 * If you haven't explicitly set the icon name for the window
9893 * (using gdk_window_set_icon_name()), the icon name will be set to
9894 * @title as well. @title must be in UTF-8 encoding (as with all
9895 * user-readable strings in GDK/GTK+). @title may not be %NULL.
9898 gdk_window_set_title (GdkWindow *window,
9901 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_title (window, title);
9905 * gdk_window_set_role:
9906 * @window: a toplevel #GdkWindow
9907 * @role: a string indicating its role
9909 * When using GTK+, typically you should use gtk_window_set_role() instead
9910 * of this low-level function.
9912 * The window manager and session manager use a window's role to
9913 * distinguish it from other kinds of window in the same application.
9914 * When an application is restarted after being saved in a previous
9915 * session, all windows with the same title and role are treated as
9916 * interchangeable. So if you have two windows with the same title
9917 * that should be distinguished for session management purposes, you
9918 * should set the role on those windows. It doesn't matter what string
9919 * you use for the role, as long as you have a different role for each
9920 * non-interchangeable kind of window.
9924 gdk_window_set_role (GdkWindow *window,
9927 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_role (window, role);
9931 * gdk_window_set_startup_id:
9932 * @window: a toplevel #GdkWindow
9933 * @startup_id: a string with startup-notification identifier
9935 * When using GTK+, typically you should use gtk_window_set_startup_id()
9936 * instead of this low-level function.
9942 gdk_window_set_startup_id (GdkWindow *window,
9943 const gchar *startup_id)
9945 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_startup_id (window, startup_id);
9949 * gdk_window_set_transient_for:
9950 * @window: a toplevel #GdkWindow
9951 * @parent: another toplevel #GdkWindow
9953 * Indicates to the window manager that @window is a transient dialog
9954 * associated with the application window @parent. This allows the
9955 * window manager to do things like center @window on @parent and
9956 * keep @window above @parent.
9958 * See gtk_window_set_transient_for() if you're using #GtkWindow or
9962 gdk_window_set_transient_for (GdkWindow *window,
9965 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_transient_for (window, parent);
9969 * gdk_window_get_root_origin:
9970 * @window: a toplevel #GdkWindow
9971 * @x: (out): return location for X position of window frame
9972 * @y: (out): return location for Y position of window frame
9974 * Obtains the top-left corner of the window manager frame in root
9975 * window coordinates.
9979 gdk_window_get_root_origin (GdkWindow *window,
9983 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_root_origin (window, x, y);
9987 * gdk_window_get_frame_extents:
9988 * @window: a toplevel #GdkWindow
9989 * @rect: rectangle to fill with bounding box of the window frame
9991 * Obtains the bounding box of the window, including window manager
9992 * titlebar/borders if any. The frame position is given in root window
9993 * coordinates. To get the position of the window itself (rather than
9994 * the frame) in root window coordinates, use gdk_window_get_origin().
9998 gdk_window_get_frame_extents (GdkWindow *window,
10001 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_frame_extents (window, rect);
10005 * gdk_window_set_override_redirect:
10006 * @window: a toplevel #GdkWindow
10007 * @override_redirect: %TRUE if window should be override redirect
10009 * An override redirect window is not under the control of the window manager.
10010 * This means it won't have a titlebar, won't be minimizable, etc. - it will
10011 * be entirely under the control of the application. The window manager
10012 * can't see the override redirect window at all.
10014 * Override redirect should only be used for short-lived temporary
10015 * windows, such as popup menus. #GtkMenu uses an override redirect
10016 * window in its implementation, for example.
10020 gdk_window_set_override_redirect (GdkWindow *window,
10021 gboolean override_redirect)
10023 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_override_redirect (window, override_redirect);
10027 * gdk_window_set_accept_focus:
10028 * @window: a toplevel #GdkWindow
10029 * @accept_focus: %TRUE if the window should receive input focus
10031 * Setting @accept_focus to %FALSE hints the desktop environment that the
10032 * window doesn't want to receive input focus.
10034 * On X, it is the responsibility of the window manager to interpret this
10035 * hint. ICCCM-compliant window manager usually respect it.
10040 gdk_window_set_accept_focus (GdkWindow *window,
10041 gboolean accept_focus)
10043 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_accept_focus (window, accept_focus);
10047 * gdk_window_set_focus_on_map:
10048 * @window: a toplevel #GdkWindow
10049 * @focus_on_map: %TRUE if the window should receive input focus when mapped
10051 * Setting @focus_on_map to %FALSE hints the desktop environment that the
10052 * window doesn't want to receive input focus when it is mapped.
10053 * focus_on_map should be turned off for windows that aren't triggered
10054 * interactively (such as popups from network activity).
10056 * On X, it is the responsibility of the window manager to interpret
10057 * this hint. Window managers following the freedesktop.org window
10058 * manager extension specification should respect it.
10063 gdk_window_set_focus_on_map (GdkWindow *window,
10064 gboolean focus_on_map)
10066 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_focus_on_map (window, focus_on_map);
10070 * gdk_window_set_icon_list:
10071 * @window: The #GdkWindow toplevel window to set the icon of.
10072 * @pixbufs: (transfer none) (element-type GdkPixbuf):
10073 * A list of pixbufs, of different sizes.
10075 * Sets a list of icons for the window. One of these will be used
10076 * to represent the window when it has been iconified. The icon is
10077 * usually shown in an icon box or some sort of task bar. Which icon
10078 * size is shown depends on the window manager. The window manager
10079 * can scale the icon but setting several size icons can give better
10080 * image quality since the window manager may only need to scale the
10081 * icon by a small amount or not at all.
10085 gdk_window_set_icon_list (GdkWindow *window,
10088 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_list (window, pixbufs);
10092 * gdk_window_set_icon_name:
10093 * @window: a toplevel #GdkWindow
10094 * @name: (allow-none): name of window while iconified (minimized)
10096 * Windows may have a name used while minimized, distinct from the
10097 * name they display in their titlebar. Most of the time this is a bad
10098 * idea from a user interface standpoint. But you can set such a name
10099 * with this function, if you like.
10101 * After calling this with a non-%NULL @name, calls to gdk_window_set_title()
10102 * will not update the icon title.
10104 * Using %NULL for @name unsets the icon title; further calls to
10105 * gdk_window_set_title() will again update the icon title as well.
10108 gdk_window_set_icon_name (GdkWindow *window,
10111 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_name (window, name);
10115 * gdk_window_iconify:
10116 * @window: a toplevel #GdkWindow
10118 * Asks to iconify (minimize) @window. The window manager may choose
10119 * to ignore the request, but normally will honor it. Using
10120 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
10122 * This function only makes sense when @window is a toplevel window.
10126 gdk_window_iconify (GdkWindow *window)
10128 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->iconify (window);
10132 * gdk_window_deiconify:
10133 * @window: a toplevel #GdkWindow
10135 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
10136 * choose to ignore the request to deiconify. When using GTK+,
10137 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
10138 * you probably want to use gtk_window_present(), which raises the window, focuses it,
10139 * unminimizes it, and puts it on the current desktop.
10143 gdk_window_deiconify (GdkWindow *window)
10145 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->deiconify (window);
10149 * gdk_window_stick:
10150 * @window: a toplevel #GdkWindow
10152 * "Pins" a window such that it's on all workspaces and does not scroll
10153 * with viewports, for window managers that have scrollable viewports.
10154 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
10156 * On the X11 platform, this function depends on window manager
10157 * support, so may have no effect with many window managers. However,
10158 * GDK will do the best it can to convince the window manager to stick
10159 * the window. For window managers that don't support this operation,
10160 * there's nothing you can do to force it to happen.
10164 gdk_window_stick (GdkWindow *window)
10166 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->stick (window);
10170 * gdk_window_unstick:
10171 * @window: a toplevel #GdkWindow
10173 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
10174 * and gtk_window_unstick().
10178 gdk_window_unstick (GdkWindow *window)
10180 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unstick (window);
10184 * gdk_window_maximize:
10185 * @window: a toplevel #GdkWindow
10187 * Maximizes the window. If the window was already maximized, then
10188 * this function does nothing.
10190 * On X11, asks the window manager to maximize @window, if the window
10191 * manager supports this operation. Not all window managers support
10192 * this, and some deliberately ignore it or don't have a concept of
10193 * "maximized"; so you can't rely on the maximization actually
10194 * happening. But it will happen with most standard window managers,
10195 * and GDK makes a best effort to get it to happen.
10197 * On Windows, reliably maximizes the window.
10201 gdk_window_maximize (GdkWindow *window)
10203 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->maximize (window);
10207 * gdk_window_unmaximize:
10208 * @window: a toplevel #GdkWindow
10210 * Unmaximizes the window. If the window wasn't maximized, then this
10211 * function does nothing.
10213 * On X11, asks the window manager to unmaximize @window, if the
10214 * window manager supports this operation. Not all window managers
10215 * support this, and some deliberately ignore it or don't have a
10216 * concept of "maximized"; so you can't rely on the unmaximization
10217 * actually happening. But it will happen with most standard window
10218 * managers, and GDK makes a best effort to get it to happen.
10220 * On Windows, reliably unmaximizes the window.
10224 gdk_window_unmaximize (GdkWindow *window)
10226 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unmaximize (window);
10230 * gdk_window_fullscreen:
10231 * @window: a toplevel #GdkWindow
10233 * Moves the window into fullscreen mode. This means the
10234 * window covers the entire screen and is above any panels
10237 * If the window was already fullscreen, then this function does nothing.
10239 * On X11, asks the window manager to put @window in a fullscreen
10240 * state, if the window manager supports this operation. Not all
10241 * window managers support this, and some deliberately ignore it or
10242 * don't have a concept of "fullscreen"; so you can't rely on the
10243 * fullscreenification actually happening. But it will happen with
10244 * most standard window managers, and GDK makes a best effort to get
10250 gdk_window_fullscreen (GdkWindow *window)
10252 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->fullscreen (window);
10256 * gdk_window_unfullscreen:
10257 * @window: a toplevel #GdkWindow
10259 * Moves the window out of fullscreen mode. If the window was not
10260 * fullscreen, does nothing.
10262 * On X11, asks the window manager to move @window out of the fullscreen
10263 * state, if the window manager supports this operation. Not all
10264 * window managers support this, and some deliberately ignore it or
10265 * don't have a concept of "fullscreen"; so you can't rely on the
10266 * unfullscreenification actually happening. But it will happen with
10267 * most standard window managers, and GDK makes a best effort to get
10273 gdk_window_unfullscreen (GdkWindow *window)
10275 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unfullscreen (window);
10279 * gdk_window_set_keep_above:
10280 * @window: a toplevel #GdkWindow
10281 * @setting: whether to keep @window above other windows
10283 * Set if @window must be kept above other windows. If the
10284 * window was already above, then this function does nothing.
10286 * On X11, asks the window manager to keep @window above, if the window
10287 * manager supports this operation. Not all window managers support
10288 * this, and some deliberately ignore it or don't have a concept of
10289 * "keep above"; so you can't rely on the window being kept above.
10290 * But it will happen with most standard window managers,
10291 * and GDK makes a best effort to get it to happen.
10296 gdk_window_set_keep_above (GdkWindow *window,
10299 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_above (window, setting);
10303 * gdk_window_set_keep_below:
10304 * @window: a toplevel #GdkWindow
10305 * @setting: whether to keep @window below other windows
10307 * Set if @window must be kept below other windows. If the
10308 * window was already below, then this function does nothing.
10310 * On X11, asks the window manager to keep @window below, if the window
10311 * manager supports this operation. Not all window managers support
10312 * this, and some deliberately ignore it or don't have a concept of
10313 * "keep below"; so you can't rely on the window being kept below.
10314 * But it will happen with most standard window managers,
10315 * and GDK makes a best effort to get it to happen.
10320 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
10322 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_below (window, setting);
10326 * gdk_window_get_group:
10327 * @window: a toplevel #GdkWindow
10329 * Returns the group leader window for @window. See gdk_window_set_group().
10331 * Return value: (transfer none): the group leader window for @window
10336 gdk_window_get_group (GdkWindow *window)
10338 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_group (window);
10342 * gdk_window_set_group:
10343 * @window: a toplevel #GdkWindow
10344 * @leader: (allow-none): group leader window, or %NULL to restore the default group leader window
10346 * Sets the group leader window for @window. By default,
10347 * GDK sets the group leader for all toplevel windows
10348 * to a global window implicitly created by GDK. With this function
10349 * you can override this default.
10351 * The group leader window allows the window manager to distinguish
10352 * all windows that belong to a single application. It may for example
10353 * allow users to minimize/unminimize all windows belonging to an
10354 * application at once. You should only set a non-default group window
10355 * if your application pretends to be multiple applications.
10358 gdk_window_set_group (GdkWindow *window,
10361 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_group (window, leader);
10365 * gdk_window_set_decorations:
10366 * @window: a toplevel #GdkWindow
10367 * @decorations: decoration hint mask
10369 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
10370 * This function sets the traditional Motif window manager hints that tell the
10371 * window manager which decorations you would like your window to have.
10372 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
10373 * using the GDK function directly.
10375 * The @decorations argument is the logical OR of the fields in
10376 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
10377 * mask, the other bits indicate which decorations should be turned off.
10378 * If #GDK_DECOR_ALL is not included, then the other bits indicate
10379 * which decorations should be turned on.
10381 * Most window managers honor a decorations hint of 0 to disable all decorations,
10382 * but very few honor all possible combinations of bits.
10386 gdk_window_set_decorations (GdkWindow *window,
10387 GdkWMDecoration decorations)
10389 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_decorations (window, decorations);
10393 * gdk_window_get_decorations:
10394 * @window: The toplevel #GdkWindow to get the decorations from
10395 * @decorations: (out): The window decorations will be written here
10397 * Returns the decorations set on the GdkWindow with
10398 * gdk_window_set_decorations().
10400 * Returns: %TRUE if the window has decorations set, %FALSE otherwise.
10403 gdk_window_get_decorations(GdkWindow *window,
10404 GdkWMDecoration *decorations)
10406 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_decorations (window, decorations);
10410 * gdk_window_set_functions:
10411 * @window: a toplevel #GdkWindow
10412 * @functions: bitmask of operations to allow on @window
10414 * Sets hints about the window management functions to make available
10415 * via buttons on the window frame.
10417 * On the X backend, this function sets the traditional Motif window
10418 * manager hint for this purpose. However, few window managers do
10419 * anything reliable or interesting with this hint. Many ignore it
10422 * The @functions argument is the logical OR of values from the
10423 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
10424 * then the other bits indicate which functions to disable; if
10425 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
10430 gdk_window_set_functions (GdkWindow *window,
10431 GdkWMFunction functions)
10433 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_functions (window, functions);
10437 * gdk_window_begin_resize_drag_for_device:
10438 * @window: a toplevel #GdkWindow
10439 * @edge: the edge or corner from which the drag is started
10440 * @device: the device used for the operation
10441 * @button: the button being used to drag
10442 * @root_x: root window X coordinate of mouse click that began the drag
10443 * @root_y: root window Y coordinate of mouse click that began the drag
10444 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
10446 * Begins a window resize operation (for a toplevel window).
10447 * You might use this function to implement a "window resize grip," for
10448 * example; in fact #GtkStatusbar uses it. The function works best
10449 * with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a
10450 * fallback implementation for other window managers.
10455 gdk_window_begin_resize_drag_for_device (GdkWindow *window,
10456 GdkWindowEdge edge,
10463 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_resize_drag (window, edge, device, button, root_x, root_y, timestamp);
10467 * gdk_window_begin_resize_drag:
10468 * @window: a toplevel #GdkWindow
10469 * @edge: the edge or corner from which the drag is started
10470 * @button: the button being used to drag
10471 * @root_x: root window X coordinate of mouse click that began the drag
10472 * @root_y: root window Y coordinate of mouse click that began the drag
10473 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
10475 * Begins a window resize operation (for a toplevel window).
10477 * This function assumes that the drag is controlled by the
10478 * client pointer device, use gdk_window_begin_resize_drag_for_device()
10479 * to begin a drag with a different device.
10482 gdk_window_begin_resize_drag (GdkWindow *window,
10483 GdkWindowEdge edge,
10489 GdkDeviceManager *device_manager;
10492 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
10493 device = gdk_device_manager_get_client_pointer (device_manager);
10494 gdk_window_begin_resize_drag_for_device (window, edge,
10495 device, button, root_x, root_y, timestamp);
10499 * gdk_window_begin_move_drag_for_device:
10500 * @window: a toplevel #GdkWindow
10501 * @device: the device used for the operation
10502 * @button: the button being used to drag
10503 * @root_x: root window X coordinate of mouse click that began the drag
10504 * @root_y: root window Y coordinate of mouse click that began the drag
10505 * @timestamp: timestamp of mouse click that began the drag
10507 * Begins a window move operation (for a toplevel window).
10508 * You might use this function to implement a "window move grip," for
10509 * example. The function works best with window managers that support
10510 * the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
10511 * Window Manager Hints</ulink>, but has a fallback implementation for
10512 * other window managers.
10517 gdk_window_begin_move_drag_for_device (GdkWindow *window,
10524 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_move_drag (window,
10525 device, button, root_x, root_y, timestamp);
10529 * gdk_window_begin_move_drag:
10530 * @window: a toplevel #GdkWindow
10531 * @button: the button being used to drag
10532 * @root_x: root window X coordinate of mouse click that began the drag
10533 * @root_y: root window Y coordinate of mouse click that began the drag
10534 * @timestamp: timestamp of mouse click that began the drag
10536 * Begins a window move operation (for a toplevel window).
10538 * This function assumes that the drag is controlled by the
10539 * client pointer device, use gdk_window_begin_move_drag_for_device()
10540 * to begin a drag with a different device.
10543 gdk_window_begin_move_drag (GdkWindow *window,
10549 GdkDeviceManager *device_manager;
10552 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
10553 device = gdk_device_manager_get_client_pointer (device_manager);
10554 gdk_window_begin_move_drag_for_device (window, device, button, root_x, root_y, timestamp);
10558 * gdk_window_enable_synchronized_configure:
10559 * @window: a toplevel #GdkWindow
10561 * Indicates that the application will cooperate with the window
10562 * system in synchronizing the window repaint with the window
10563 * manager during resizing operations. After an application calls
10564 * this function, it must call gdk_window_configure_finished() every
10565 * time it has finished all processing associated with a set of
10566 * Configure events. Toplevel GTK+ windows automatically use this
10569 * On X, calling this function makes @window participate in the
10570 * _NET_WM_SYNC_REQUEST window manager protocol.
10575 gdk_window_enable_synchronized_configure (GdkWindow *window)
10577 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->enable_synchronized_configure (window);
10581 * gdk_window_configure_finished:
10582 * @window: a toplevel #GdkWindow
10584 * Signal to the window system that the application has finished
10585 * handling Configure events it has received. Window Managers can
10586 * use this to better synchronize the frame repaint with the
10587 * application. GTK+ applications will automatically call this
10588 * function when appropriate.
10590 * This function can only be called if gdk_window_enable_synchronized_configure()
10591 * was called previously.
10596 gdk_window_configure_finished (GdkWindow *window)
10598 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->configure_finished (window);
10602 * gdk_window_set_opacity:
10603 * @window: a top-level #GdkWindow
10604 * @opacity: opacity
10606 * Request the windowing system to make @window partially transparent,
10607 * with opacity 0 being fully transparent and 1 fully opaque. (Values
10608 * of the opacity parameter are clamped to the [0,1] range.)
10610 * On X11, this works only on X screens with a compositing manager
10613 * For setting up per-pixel alpha, see gdk_screen_get_rgba_visual().
10614 * For making non-toplevel windows translucent, see
10615 * gdk_window_set_composited().
10620 gdk_window_set_opacity (GdkWindow *window,
10623 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_opacity (window, opacity);
10626 /* This function is called when the XWindow is really gone.
10629 gdk_window_destroy_notify (GdkWindow *window)
10631 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->destroy_notify (window);
10635 * gdk_window_register_dnd:
10636 * @window: a #GdkWindow.
10638 * Registers a window as a potential drop destination.
10641 gdk_window_register_dnd (GdkWindow *window)
10643 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->register_dnd (window);
10647 * gdk_window_get_drag_protocol:
10648 * @window: the destination window
10649 * @target: (out) (allow-none) (transfer full): location of the window
10650 * where the drop should happen. This may be @window or a proxy window,
10651 * or %NULL if @window does not support Drag and Drop.
10653 * Finds out the DND protocol supported by a window.
10655 * Returns: the supported DND protocol.
10660 gdk_window_get_drag_protocol (GdkWindow *window,
10661 GdkWindow **target)
10663 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_DRAG_PROTO_NONE);
10665 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_drag_protocol (window, target);
10670 * @window: the source window for this drag.
10671 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
10672 * as list of #GdkAtoms
10674 * Starts a drag and creates a new drag context for it.
10675 * This function assumes that the drag is controlled by the
10676 * client pointer device, use gdk_drag_begin_for_device() to
10677 * begin a drag with a different device.
10679 * This function is called by the drag source.
10681 * Return value: (transfer full): a newly created #GdkDragContext
10684 gdk_drag_begin (GdkWindow *window,
10687 GdkDeviceManager *device_manager;
10690 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
10691 device = gdk_device_manager_get_client_pointer (device_manager);
10693 return gdk_drag_begin_for_device (window, device, targets);
10697 * gdk_drag_begin_for_device:
10698 * @window: the source window for this drag
10699 * @device: the device that controls this drag
10700 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
10701 * as list of #GdkAtoms
10703 * Starts a drag and creates a new drag context for it.
10705 * This function is called by the drag source.
10707 * Return value: (transfer full): a newly created #GdkDragContext
10710 gdk_drag_begin_for_device (GdkWindow *window,
10714 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, targets);
10718 * gdk_test_render_sync:
10719 * @window: a mapped #GdkWindow
10721 * Retrieves a pixel from @window to force the windowing
10722 * system to carry out any pending rendering commands.
10724 * This function is intended to be used to synchronize with rendering
10725 * pipelines, to benchmark windowing system rendering operations.
10730 gdk_test_render_sync (GdkWindow *window)
10732 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->sync_rendering (window);
10736 * gdk_test_simulate_key:
10737 * @window: a #GdkWindow to simulate a key event for
10738 * @x: x coordinate within @window for the key event
10739 * @y: y coordinate within @window for the key event
10740 * @keyval: A GDK keyboard value
10741 * @modifiers: Keyboard modifiers the event is setup with
10742 * @key_pressrelease: either %GDK_KEY_PRESS or %GDK_KEY_RELEASE
10744 * This function is intended to be used in GTK+ test programs.
10745 * If (@x,@y) are > (-1,-1), it will warp the mouse pointer to
10746 * the given (@x,@y) coordinates within @window and simulate a
10747 * key press or release event.
10749 * When the mouse pointer is warped to the target location, use
10750 * of this function outside of test programs that run in their
10751 * own virtual windowing system (e.g. Xvfb) is not recommended.
10752 * If (@x,@y) are passed as (-1,-1), the mouse pointer will not
10753 * be warped and @window origin will be used as mouse pointer
10754 * location for the event.
10756 * Also, gdk_test_simulate_key() is a fairly low level function,
10757 * for most testing purposes, gtk_test_widget_send_key() is the
10758 * right function to call which will generate a key press event
10759 * followed by its accompanying key release event.
10761 * Returns: whether all actions necessary for a key event simulation
10762 * were carried out successfully
10767 gdk_test_simulate_key (GdkWindow *window,
10771 GdkModifierType modifiers,
10772 GdkEventType key_pressrelease)
10774 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10775 ->simulate_key (window, x, y, keyval, modifiers, key_pressrelease);
10779 * gdk_test_simulate_button:
10780 * @window: a #GdkWindow to simulate a button event for
10781 * @x: x coordinate within @window for the button event
10782 * @y: y coordinate within @window for the button event
10783 * @button: Number of the pointer button for the event, usually 1, 2 or 3
10784 * @modifiers: Keyboard modifiers the event is setup with
10785 * @button_pressrelease: either %GDK_BUTTON_PRESS or %GDK_BUTTON_RELEASE
10787 * This function is intended to be used in GTK+ test programs.
10788 * It will warp the mouse pointer to the given (@x,@y) coordinates
10789 * within @window and simulate a button press or release event.
10790 * Because the mouse pointer needs to be warped to the target
10791 * location, use of this function outside of test programs that
10792 * run in their own virtual windowing system (e.g. Xvfb) is not
10795 * Also, gdk_test_simulate_button() is a fairly low level function,
10796 * for most testing purposes, gtk_test_widget_click() is the right
10797 * function to call which will generate a button press event followed
10798 * by its accompanying button release event.
10800 * Returns: whether all actions necessary for a button event simulation
10801 * were carried out successfully
10806 gdk_test_simulate_button (GdkWindow *window,
10809 guint button, /*1..3*/
10810 GdkModifierType modifiers,
10811 GdkEventType button_pressrelease)
10813 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10814 ->simulate_button (window, x, y, button, modifiers, button_pressrelease);
10818 * gdk_property_get:
10819 * @window: a #GdkWindow
10820 * @property: the property to retrieve
10821 * @type: the desired property type, or %GDK_NONE, if any type of data
10822 * is acceptable. If this does not match the actual
10823 * type, then @actual_format and @actual_length will
10824 * be filled in, a warning will be printed to stderr
10825 * and no data will be returned.
10826 * @offset: the offset into the property at which to begin
10827 * retrieving data, in 4 byte units.
10828 * @length: the length of the data to retrieve in bytes. Data is
10829 * considered to be retrieved in 4 byte chunks, so @length
10830 * will be rounded up to the next highest 4 byte boundary
10831 * (so be careful not to pass a value that might overflow
10832 * when rounded up).
10833 * @pdelete: if %TRUE, delete the property after retrieving the
10835 * @actual_property_type: (out) (transfer none): location to store the
10836 * actual type of the property.
10837 * @actual_format: (out): location to store the actual return format of the
10838 * data; either 8, 16 or 32 bits.
10839 * @actual_length: location to store the length of the retrieved data, in
10840 * bytes. Data returned in the 32 bit format is stored
10841 * in a long variable, so the actual number of 32 bit
10842 * elements should be be calculated via
10843 * @actual_length / sizeof(glong) to ensure portability to
10845 * @data: (out) (array length=actual_length) (transfer full): location
10846 * to store a pointer to the data. The retrieved data should be
10847 * freed with g_free() when you are finished using it.
10849 * Retrieves a portion of the contents of a property. If the
10850 * property does not exist, then the function returns %FALSE,
10851 * and %GDK_NONE will be stored in @actual_property_type.
10855 * The XGetWindowProperty() function that gdk_property_get()
10856 * uses has a very confusing and complicated set of semantics.
10857 * Unfortunately, gdk_property_get() makes the situation
10858 * worse instead of better (the semantics should be considered
10859 * undefined), and also prints warnings to stderr in cases where it
10860 * should return a useful error to the program. You are advised to use
10861 * XGetWindowProperty() directly until a replacement function for
10862 * gdk_property_get()
10867 * Returns: %TRUE if data was successfully received and stored
10868 * in @data, otherwise %FALSE.
10871 gdk_property_get (GdkWindow *window,
10877 GdkAtom *actual_property_type,
10878 gint *actual_format_type,
10879 gint *actual_length,
10882 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10883 ->get_property (window, property, type, offset, length, pdelete,
10884 actual_property_type, actual_format_type,
10885 actual_length, data);
10889 * gdk_property_change: (skip)
10890 * @window: a #GdkWindow
10891 * @property: the property to change
10892 * @type: the new type for the property. If @mode is
10893 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
10894 * must match the existing type or an error will occur.
10895 * @format: the new format for the property. If @mode is
10896 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
10897 * must match the existing format or an error will occur.
10898 * @mode: a value describing how the new data is to be combined
10899 * with the current data.
10900 * @data: the data (a <literal>guchar *</literal>
10901 * <literal>gushort *</literal>, or <literal>gulong *</literal>,
10902 * depending on @format), cast to a <literal>guchar *</literal>.
10903 * @nelements: the number of elements of size determined by the format,
10904 * contained in @data.
10906 * Changes the contents of a property on a window.
10909 gdk_property_change (GdkWindow *window,
10914 const guchar *data,
10917 GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10918 ->change_property (window, property, type, format, mode, data, nelements);
10922 * gdk_property_delete:
10923 * @window: a #GdkWindow
10924 * @property: the property to delete
10926 * Deletes a property from a window.
10929 gdk_property_delete (GdkWindow *window,
10932 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->delete_property (window, property);