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 *clipped_expose_region;
3769 GList *l, *children;
3771 if (cairo_region_is_empty (expose_region))
3774 if (gdk_window_is_offscreen (window->impl_window) &&
3775 window == window->impl_window)
3776 _gdk_window_add_damage ((GdkWindow *) window->impl_window, expose_region);
3779 /* Paint the window before the children, clipped to the window region
3780 with visible child windows removed */
3781 clipped_expose_region = cairo_region_copy (expose_region);
3782 cairo_region_intersect (clipped_expose_region, window->clip_region_with_children);
3784 if (!cairo_region_is_empty (clipped_expose_region) &&
3787 if (window->event_mask & GDK_EXPOSURE_MASK)
3791 event.expose.type = GDK_EXPOSE;
3792 event.expose.window = g_object_ref (window);
3793 event.expose.send_event = FALSE;
3794 event.expose.count = 0;
3795 event.expose.region = clipped_expose_region;
3796 cairo_region_get_extents (clipped_expose_region, &event.expose.area);
3798 _gdk_event_emit (&event);
3800 g_object_unref (window);
3802 else if (window->window_type != GDK_WINDOW_FOREIGN)
3804 /* No exposure mask set, so nothing will be drawn, the
3805 * app relies on the background being what it specified
3806 * for the window. So, we need to clear this manually.
3808 * For foreign windows if expose is not set that generally
3809 * means some other client paints them, so don't clear
3812 * We use begin/end_paint around the clear so that we can
3813 * piggyback on the implicit paint */
3815 gdk_window_begin_paint_region (window, clipped_expose_region);
3816 gdk_window_clear_region_internal (window, clipped_expose_region);
3817 gdk_window_end_paint (window);
3820 cairo_region_destroy (clipped_expose_region);
3822 /* Make this reentrancy safe for expose handlers freeing windows */
3823 children = g_list_copy (window->children);
3824 g_list_foreach (children, (GFunc)g_object_ref, NULL);
3826 /* Iterate over children, starting at bottommost */
3827 for (l = g_list_last (children); l != NULL; l = l->prev)
3831 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
3834 /* Ignore offscreen children, as they don't draw in their parent and
3835 * don't take part in the clipping */
3836 if (gdk_window_is_offscreen (child))
3839 /* Client side child, expose */
3840 if (child->impl == window->impl)
3842 cairo_region_translate (expose_region, -child->x, -child->y);
3843 _gdk_window_process_updates_recurse ((GdkWindow *)child, expose_region);
3844 cairo_region_translate (expose_region, child->x, child->y);
3848 g_list_foreach (children, (GFunc)g_object_unref, NULL);
3849 g_list_free (children);
3853 /* Process and remove any invalid area on the native window by creating
3854 * expose events for the window and all non-native descendants.
3855 * Also processes any outstanding moves on the window before doing
3856 * any drawing. Note that its possible to have outstanding moves without
3857 * any invalid area as we use the update idle mechanism to coalesce
3858 * multiple moves as well as multiple invalidations.
3861 gdk_window_process_updates_internal (GdkWindow *window)
3863 GdkWindowImplClass *impl_class;
3864 gboolean save_region = FALSE;
3865 GdkRectangle clip_box;
3867 /* Ensure the window lives while updating it */
3868 g_object_ref (window);
3870 /* If an update got queued during update processing, we can get a
3871 * window in the update queue that has an empty update_area.
3874 if (window->update_area)
3876 cairo_region_t *update_area = window->update_area;
3877 window->update_area = NULL;
3879 if (gdk_window_is_viewable (window))
3881 cairo_region_t *expose_region;
3882 gboolean end_implicit;
3884 /* Clip to part visible in toplevel */
3885 cairo_region_intersect (update_area, window->clip_region);
3889 /* Make sure we see the red invalid area before redrawing. */
3890 gdk_display_sync (gdk_window_get_display (window));
3894 /* At this point we will be completely redrawing all of update_area.
3895 * If we have any outstanding moves that end up moving stuff inside
3896 * this area we don't actually need to move that as that part would
3897 * be overdrawn by the expose anyway. So, in order to copy less data
3898 * we remove these areas from the outstanding moves.
3900 if (window->outstanding_moves)
3902 GdkWindowRegionMove *move;
3903 cairo_region_t *remove;
3906 remove = cairo_region_copy (update_area);
3907 /* We iterate backwards, starting from the state that would be
3908 if we had applied all the moves. */
3909 for (l = g_list_last (window->outstanding_moves); l != NULL; l = prev)
3914 /* Don't need this area */
3915 cairo_region_subtract (move->dest_region, remove);
3917 /* However if any of the destination we do need has a source
3918 in the updated region we do need that as a destination for
3919 the earlier moves */
3920 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
3921 cairo_region_subtract (remove, move->dest_region);
3923 if (cairo_region_is_empty (move->dest_region))
3925 gdk_window_region_move_free (move);
3926 window->outstanding_moves =
3927 g_list_delete_link (window->outstanding_moves, l);
3929 else /* move back */
3930 cairo_region_translate (move->dest_region, move->dx, move->dy);
3932 cairo_region_destroy (remove);
3935 /* By now we a set of window moves that should be applied, and then
3936 * an update region that should be repainted. A trivial implementation
3937 * would just do that in order, however in order to get nicer drawing
3938 * we do some tricks:
3940 * First of all, each subwindow expose may be double buffered by
3941 * itself (depending on widget setting) via
3942 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
3943 * creating a single surface the size of the invalid area on the
3944 * native window which all the individual normal paints will draw
3945 * into. This way in the normal case there will be only one surface
3946 * allocated and only once surface draw done for all the windows
3947 * in this native window.
3948 * There are a couple of reasons this may fail, for instance, some
3949 * backends (like quartz) do its own double buffering, so we disable
3950 * gdk double buffering there. Secondly, some subwindow could be
3951 * non-double buffered and draw directly to the window outside a
3952 * begin/end_paint pair. That will be lead to a gdk_window_flush
3953 * which immediately executes all outstanding moves and paints+removes
3954 * the implicit paint (further paints will allocate their own surfaces).
3956 * Secondly, in the case of implicit double buffering we expose all
3957 * the child windows into the implicit surface before we execute
3958 * the outstanding moves. This way we minimize the time between
3959 * doing the moves and rendering the new update area, thus minimizing
3960 * flashing. Of course, if any subwindow is non-double buffered we
3961 * well flush earlier than that.
3963 * Thirdly, after having done the outstanding moves we queue an
3964 * "antiexpose" on the area that will be drawn by the expose, which
3965 * means that any invalid region on the native window side before
3966 * the first expose drawing operation will be discarded, as it
3967 * has by then been overdrawn with valid data. This means we can
3968 * avoid doing the unnecessary repaint any outstanding expose events.
3971 cairo_region_get_extents (update_area, &clip_box);
3972 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box);
3973 expose_region = cairo_region_copy (update_area);
3974 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
3977 /* Rendering is not double buffered by gdk, do outstanding
3978 * moves and queue antiexposure immediately. No need to do
3980 gdk_window_flush_outstanding_moves (window);
3981 save_region = impl_class->queue_antiexpose (window, update_area);
3983 /* Render the invalid areas to the implicit paint, by sending exposes.
3984 * May flush if non-double buffered widget draw. */
3985 impl_class->process_updates_recurse (window, expose_region);
3989 /* Do moves right before exposes are rendered to the window */
3990 gdk_window_flush_outstanding_moves (window);
3992 /* By this time we know that any outstanding expose for this
3993 * area is invalid and we can avoid it, so queue an antiexpose.
3994 * we have already started drawing to the window, so it would
3995 * be to late to anti-expose now. Since this is merely an
3996 * optimization we just avoid doing it at all in that case.
3998 if (window->implicit_paint != NULL && !window->implicit_paint->flushed)
3999 save_region = impl_class->queue_antiexpose (window, update_area);
4001 gdk_window_end_implicit_paint (window);
4003 cairo_region_destroy (expose_region);
4006 cairo_region_destroy (update_area);
4009 if (window->outstanding_moves)
4011 /* Flush any outstanding moves, may happen if we moved a window but got
4012 no actual invalid area */
4013 gdk_window_flush_outstanding_moves (window);
4016 g_object_unref (window);
4020 flush_all_displays (void)
4022 GSList *displays, *l;
4024 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4025 for (l = displays; l; l = l->next)
4026 gdk_display_flush (l->data);
4028 g_slist_free (displays);
4032 before_process_all_updates (void)
4034 GSList *displays, *l;
4035 GdkDisplayClass *display_class;
4037 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4038 display_class = GDK_DISPLAY_GET_CLASS (displays->data);
4039 for (l = displays; l; l = l->next)
4040 display_class->before_process_all_updates (l->data);
4042 g_slist_free (displays);
4046 after_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->after_process_all_updates (l->data);
4056 g_slist_free (displays);
4059 /* Currently it is not possible to override
4060 * gdk_window_process_all_updates in the same manner as
4061 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4062 * by implementing the GdkPaintable interface. If in the future a
4063 * backend would need this, the right solution would be to add a
4064 * method to GdkDisplay that can be optionally
4065 * NULL. gdk_window_process_all_updates can then walk the list of open
4066 * displays and call the mehod.
4070 * gdk_window_process_all_updates:
4072 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4073 * in the application.
4077 gdk_window_process_all_updates (void)
4079 GSList *old_update_windows = update_windows;
4080 GSList *tmp_list = update_windows;
4081 static gboolean in_process_all_updates = FALSE;
4082 static gboolean got_recursive_update = FALSE;
4084 if (in_process_all_updates)
4086 /* We can't do this now since that would recurse, so
4087 delay it until after the recursion is done. */
4088 got_recursive_update = TRUE;
4093 in_process_all_updates = TRUE;
4094 got_recursive_update = FALSE;
4097 g_source_remove (update_idle);
4099 update_windows = NULL;
4102 before_process_all_updates ();
4104 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4108 GdkWindow *window = tmp_list->data;
4110 if (!GDK_WINDOW_DESTROYED (window))
4112 if (window->update_freeze_count ||
4113 gdk_window_is_toplevel_frozen (window))
4114 gdk_window_add_update_window (window);
4116 gdk_window_process_updates_internal (window);
4119 g_object_unref (window);
4120 tmp_list = tmp_list->next;
4123 g_slist_free (old_update_windows);
4125 flush_all_displays ();
4127 after_process_all_updates ();
4129 in_process_all_updates = FALSE;
4131 /* If we ignored a recursive call, schedule a
4132 redraw now so that it eventually happens,
4133 otherwise we could miss an update if nothing
4134 else schedules an update. */
4135 if (got_recursive_update && !update_idle)
4137 gdk_threads_add_idle_full (GDK_PRIORITY_REDRAW,
4138 gdk_window_update_idle,
4143 * gdk_window_process_updates:
4144 * @window: a #GdkWindow
4145 * @update_children: whether to also process updates for child windows
4147 * Sends one or more expose events to @window. The areas in each
4148 * expose event will cover the entire update area for the window (see
4149 * gdk_window_invalidate_region() for details). Normally GDK calls
4150 * gdk_window_process_all_updates() on your behalf, so there's no
4151 * need to call this function unless you want to force expose events
4152 * to be delivered immediately and synchronously (vs. the usual
4153 * case, where GDK delivers them in an idle handler). Occasionally
4154 * this is useful to produce nicer scrolling behavior, for example.
4158 gdk_window_process_updates (GdkWindow *window,
4159 gboolean update_children)
4161 GdkWindow *impl_window;
4163 g_return_if_fail (GDK_IS_WINDOW (window));
4165 if (GDK_WINDOW_DESTROYED (window))
4168 /* Make sure the window lives during the expose callouts */
4169 g_object_ref (window);
4171 impl_window = gdk_window_get_impl_window (window);
4172 if ((impl_window->update_area ||
4173 impl_window->outstanding_moves) &&
4174 !impl_window->update_freeze_count &&
4175 !gdk_window_is_toplevel_frozen (window) &&
4177 /* Don't recurse into process_updates_internal, we'll
4178 * do the update later when idle instead. */
4179 impl_window->implicit_paint == NULL)
4181 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4182 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4185 if (update_children)
4187 /* process updates in reverse stacking order so composition or
4188 * painting over achieves the desired effect for offscreen windows
4190 GList *node, *children;
4192 children = g_list_copy (window->children);
4193 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4195 for (node = g_list_last (children); node; node = node->prev)
4197 gdk_window_process_updates (node->data, TRUE);
4198 g_object_unref (node->data);
4201 g_list_free (children);
4204 g_object_unref (window);
4208 gdk_window_invalidate_rect_full (GdkWindow *window,
4209 const GdkRectangle *rect,
4210 gboolean invalidate_children,
4213 GdkRectangle window_rect;
4214 cairo_region_t *region;
4216 g_return_if_fail (GDK_IS_WINDOW (window));
4218 if (GDK_WINDOW_DESTROYED (window))
4221 if (window->input_only || !window->viewable)
4228 window_rect.width = window->width;
4229 window_rect.height = window->height;
4230 rect = &window_rect;
4233 region = cairo_region_create_rectangle (rect);
4234 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4235 cairo_region_destroy (region);
4239 * gdk_window_invalidate_rect:
4240 * @window: a #GdkWindow
4241 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4243 * @invalidate_children: whether to also invalidate child windows
4245 * A convenience wrapper around gdk_window_invalidate_region() which
4246 * invalidates a rectangular region. See
4247 * gdk_window_invalidate_region() for details.
4250 gdk_window_invalidate_rect (GdkWindow *window,
4251 const GdkRectangle *rect,
4252 gboolean invalidate_children)
4254 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4258 draw_ugly_color (GdkWindow *window,
4259 const cairo_region_t *region)
4263 cr = gdk_cairo_create (window);
4264 /* Draw ugly color all over the newly-invalid region */
4265 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4266 gdk_cairo_region (cr, region);
4273 impl_window_add_update_area (GdkWindow *impl_window,
4274 cairo_region_t *region)
4276 if (impl_window->update_area)
4277 cairo_region_union (impl_window->update_area, region);
4280 gdk_window_add_update_window (impl_window);
4281 impl_window->update_area = cairo_region_copy (region);
4282 gdk_window_schedule_update (impl_window);
4286 /* clear_bg controls if the region will be cleared to
4287 * the background pattern if the exposure mask is not
4288 * set for the window, whereas this might not otherwise be
4289 * done (unless necessary to emulate background settings).
4290 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4291 * need to clear the background, such as when exposing the area beneath a
4292 * hidden or moved window, but not when an app requests repaint or when the
4293 * windowing system exposes a newly visible area (because then the windowing
4294 * system has already cleared the area).
4297 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4298 const cairo_region_t *region,
4300 GdkWindowChildFunc child_func,
4303 GdkWindow *impl_window;
4304 cairo_region_t *visible_region;
4307 g_return_if_fail (GDK_IS_WINDOW (window));
4309 if (GDK_WINDOW_DESTROYED (window))
4312 if (window->input_only ||
4313 !window->viewable ||
4314 cairo_region_is_empty (region) ||
4315 window->window_type == GDK_WINDOW_ROOT)
4318 visible_region = gdk_window_get_visible_region (window);
4319 cairo_region_intersect (visible_region, region);
4321 tmp_list = window->children;
4324 GdkWindow *child = tmp_list->data;
4326 if (!child->input_only)
4328 cairo_region_t *child_region;
4329 GdkRectangle child_rect;
4331 child_rect.x = child->x;
4332 child_rect.y = child->y;
4333 child_rect.width = child->width;
4334 child_rect.height = child->height;
4335 child_region = cairo_region_create_rectangle (&child_rect);
4337 /* remove child area from the invalid area of the parent */
4338 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4339 !child->composited &&
4340 !gdk_window_is_offscreen (child))
4341 cairo_region_subtract (visible_region, child_region);
4343 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4345 cairo_region_t *tmp = cairo_region_copy (region);
4347 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4348 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4349 cairo_region_intersect (child_region, tmp);
4351 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4352 child_region, clear_bg, child_func, user_data);
4354 cairo_region_destroy (tmp);
4357 cairo_region_destroy (child_region);
4360 tmp_list = tmp_list->next;
4363 impl_window = gdk_window_get_impl_window (window);
4365 if (!cairo_region_is_empty (visible_region) ||
4366 /* Even if we're not exposing anything, make sure we process
4367 idles for windows with outstanding moves */
4368 (impl_window->outstanding_moves != NULL &&
4369 impl_window->update_area == NULL))
4372 draw_ugly_color (window, region);
4374 /* Convert to impl coords */
4375 cairo_region_translate (visible_region, window->abs_x, window->abs_y);
4377 /* Only invalidate area if app requested expose events or if
4378 we need to clear the area (by request or to emulate background
4379 clearing for non-native windows or native windows with no support
4380 for window backgrounds */
4381 if (window->event_mask & GDK_EXPOSURE_MASK ||
4382 clear_bg == CLEAR_BG_ALL ||
4383 clear_bg == CLEAR_BG_WINCLEARED)
4384 impl_window_add_update_area (impl_window, visible_region);
4387 cairo_region_destroy (visible_region);
4391 * gdk_window_invalidate_maybe_recurse:
4392 * @window: a #GdkWindow
4393 * @region: a #cairo_region_t
4394 * @child_func: (scope call) (allow-none): function to use to decide if to
4395 * recurse to a child, %NULL means never recurse.
4396 * @user_data: data passed to @child_func
4398 * Adds @region to the update area for @window. The update area is the
4399 * region that needs to be redrawn, or "dirty region." The call
4400 * gdk_window_process_updates() sends one or more expose events to the
4401 * window, which together cover the entire update area. An
4402 * application would normally redraw the contents of @window in
4403 * response to those expose events.
4405 * GDK will call gdk_window_process_all_updates() on your behalf
4406 * whenever your program returns to the main loop and becomes idle, so
4407 * normally there's no need to do that manually, you just need to
4408 * invalidate regions that you know should be redrawn.
4410 * The @child_func parameter controls whether the region of
4411 * each child window that intersects @region will also be invalidated.
4412 * Only children for which @child_func returns TRUE will have the area
4416 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4417 const cairo_region_t *region,
4418 GdkWindowChildFunc child_func,
4421 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4422 child_func, user_data);
4426 true_predicate (GdkWindow *window,
4433 gdk_window_invalidate_region_full (GdkWindow *window,
4434 const cairo_region_t *region,
4435 gboolean invalidate_children,
4438 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4439 invalidate_children ?
4440 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4445 * gdk_window_invalidate_region:
4446 * @window: a #GdkWindow
4447 * @region: a #cairo_region_t
4448 * @invalidate_children: %TRUE to also invalidate child windows
4450 * Adds @region to the update area for @window. The update area is the
4451 * region that needs to be redrawn, or "dirty region." The call
4452 * gdk_window_process_updates() sends one or more expose events to the
4453 * window, which together cover the entire update area. An
4454 * application would normally redraw the contents of @window in
4455 * response to those expose events.
4457 * GDK will call gdk_window_process_all_updates() on your behalf
4458 * whenever your program returns to the main loop and becomes idle, so
4459 * normally there's no need to do that manually, you just need to
4460 * invalidate regions that you know should be redrawn.
4462 * The @invalidate_children parameter controls whether the region of
4463 * each child window that intersects @region will also be invalidated.
4464 * If %FALSE, then the update area for child windows will remain
4465 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4466 * fine grained control over which children are invalidated.
4469 gdk_window_invalidate_region (GdkWindow *window,
4470 const cairo_region_t *region,
4471 gboolean invalidate_children)
4473 gdk_window_invalidate_maybe_recurse (window, region,
4474 invalidate_children ?
4475 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4480 * _gdk_window_invalidate_for_expose:
4481 * @window: a #GdkWindow
4482 * @region: a #cairo_region_t
4484 * Adds @region to the update area for @window. The update area is the
4485 * region that needs to be redrawn, or "dirty region." The call
4486 * gdk_window_process_updates() sends one or more expose events to the
4487 * window, which together cover the entire update area. An
4488 * application would normally redraw the contents of @window in
4489 * response to those expose events.
4491 * GDK will call gdk_window_process_all_updates() on your behalf
4492 * whenever your program returns to the main loop and becomes idle, so
4493 * normally there's no need to do that manually, you just need to
4494 * invalidate regions that you know should be redrawn.
4496 * This version of invalidation is used when you recieve expose events
4497 * from the native window system. It exposes the native window, plus
4498 * any non-native child windows (but not native child windows, as those would
4499 * have gotten their own expose events).
4502 _gdk_window_invalidate_for_expose (GdkWindow *window,
4503 cairo_region_t *region)
4505 GdkWindowRegionMove *move;
4506 cairo_region_t *move_region;
4509 /* Any invalidations comming from the windowing system will
4510 be in areas that may be moved by outstanding moves,
4511 so we need to modify the expose region correspondingly,
4512 otherwise we would expose in the wrong place, as the
4513 outstanding moves will be copied before we draw the
4515 for (l = window->outstanding_moves; l != NULL; l = l->next)
4519 /* covert to move source region */
4520 move_region = cairo_region_copy (move->dest_region);
4521 cairo_region_translate (move_region, -move->dx, -move->dy);
4523 /* Move area of region that intersects with move source
4524 by dx, dy of the move*/
4525 cairo_region_intersect (move_region, region);
4526 cairo_region_subtract (region, move_region);
4527 cairo_region_translate (move_region, move->dx, move->dy);
4528 cairo_region_union (region, move_region);
4530 cairo_region_destroy (move_region);
4533 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4534 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4540 * gdk_window_get_update_area:
4541 * @window: a #GdkWindow
4543 * Transfers ownership of the update area from @window to the caller
4544 * of the function. That is, after calling this function, @window will
4545 * no longer have an invalid/dirty region; the update area is removed
4546 * from @window and handed to you. If a window has no update area,
4547 * gdk_window_get_update_area() returns %NULL. You are responsible for
4548 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4550 * Return value: the update area for @window
4553 gdk_window_get_update_area (GdkWindow *window)
4555 GdkWindow *impl_window;
4556 cairo_region_t *tmp_region;
4558 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4560 impl_window = gdk_window_get_impl_window (window);
4562 if (impl_window->update_area)
4564 tmp_region = cairo_region_copy (window->clip_region_with_children);
4565 /* Convert to impl coords */
4566 cairo_region_translate (tmp_region, window->abs_x, window->abs_y);
4567 cairo_region_intersect (tmp_region, impl_window->update_area);
4569 if (cairo_region_is_empty (tmp_region))
4571 cairo_region_destroy (tmp_region);
4576 cairo_region_subtract (impl_window->update_area, tmp_region);
4578 if (cairo_region_is_empty (impl_window->update_area) &&
4579 impl_window->outstanding_moves == NULL)
4581 cairo_region_destroy (impl_window->update_area);
4582 impl_window->update_area = NULL;
4584 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4587 /* Convert from impl coords */
4588 cairo_region_translate (tmp_region, -window->abs_x, -window->abs_y);
4598 * _gdk_window_clear_update_area:
4599 * @window: a #GdkWindow.
4601 * Internal function to clear the update area for a window. This
4602 * is called when the window is hidden or destroyed.
4605 _gdk_window_clear_update_area (GdkWindow *window)
4607 g_return_if_fail (GDK_IS_WINDOW (window));
4609 if (window->update_area)
4611 gdk_window_remove_update_window (window);
4613 cairo_region_destroy (window->update_area);
4614 window->update_area = NULL;
4619 * gdk_window_freeze_updates:
4620 * @window: a #GdkWindow
4622 * Temporarily freezes a window such that it won't receive expose
4623 * events. The window will begin receiving expose events again when
4624 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4625 * has been called more than once, gdk_window_thaw_updates() must be called
4626 * an equal number of times to begin processing exposes.
4629 gdk_window_freeze_updates (GdkWindow *window)
4631 GdkWindow *impl_window;
4633 g_return_if_fail (GDK_IS_WINDOW (window));
4635 impl_window = gdk_window_get_impl_window (window);
4636 impl_window->update_freeze_count++;
4640 * gdk_window_thaw_updates:
4641 * @window: a #GdkWindow
4643 * Thaws a window frozen with gdk_window_freeze_updates().
4646 gdk_window_thaw_updates (GdkWindow *window)
4648 GdkWindow *impl_window;
4650 g_return_if_fail (GDK_IS_WINDOW (window));
4652 impl_window = gdk_window_get_impl_window (window);
4654 g_return_if_fail (impl_window->update_freeze_count > 0);
4656 if (--impl_window->update_freeze_count == 0)
4657 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4661 * gdk_window_freeze_toplevel_updates_libgtk_only:
4662 * @window: a #GdkWindow
4664 * Temporarily freezes a window and all its descendants such that it won't
4665 * receive expose events. The window will begin receiving expose events
4666 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4667 * gdk_window_freeze_toplevel_updates_libgtk_only()
4668 * has been called more than once,
4669 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4670 * an equal number of times to begin processing exposes.
4672 * This function is not part of the GDK public API and is only
4676 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4678 g_return_if_fail (GDK_IS_WINDOW (window));
4679 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4681 window->update_and_descendants_freeze_count++;
4685 * gdk_window_thaw_toplevel_updates_libgtk_only:
4686 * @window: a #GdkWindow
4688 * Thaws a window frozen with
4689 * gdk_window_freeze_toplevel_updates_libgtk_only().
4691 * This function is not part of the GDK public API and is only
4695 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4697 g_return_if_fail (GDK_IS_WINDOW (window));
4698 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4699 g_return_if_fail (window->update_and_descendants_freeze_count > 0);
4701 window->update_and_descendants_freeze_count--;
4703 gdk_window_schedule_update (window);
4707 * gdk_window_set_debug_updates:
4708 * @setting: %TRUE to turn on update debugging
4710 * With update debugging enabled, calls to
4711 * gdk_window_invalidate_region() clear the invalidated region of the
4712 * screen to a noticeable color, and GDK pauses for a short time
4713 * before sending exposes to windows during
4714 * gdk_window_process_updates(). The net effect is that you can see
4715 * the invalid region for each window and watch redraws as they
4716 * occur. This allows you to diagnose inefficiencies in your application.
4718 * In essence, because the GDK rendering model prevents all flicker,
4719 * if you are redrawing the same region 400 times you may never
4720 * notice, aside from noticing a speed problem. Enabling update
4721 * debugging causes GTK to flicker slowly and noticeably, so you can
4722 * see exactly what's being redrawn when, in what order.
4724 * The --gtk-debug=updates command line option passed to GTK+ programs
4725 * enables this debug option at application startup time. That's
4726 * usually more useful than calling gdk_window_set_debug_updates()
4727 * yourself, though you might want to use this function to enable
4728 * updates sometime after application startup time.
4732 gdk_window_set_debug_updates (gboolean setting)
4734 debug_updates = setting;
4738 * gdk_window_constrain_size:
4739 * @geometry: a #GdkGeometry structure
4740 * @flags: a mask indicating what portions of @geometry are set
4741 * @width: desired width of window
4742 * @height: desired height of the window
4743 * @new_width: (out): location to store resulting width
4744 * @new_height: (out): location to store resulting height
4746 * Constrains a desired width and height according to a
4747 * set of geometry hints (such as minimum and maximum size).
4750 gdk_window_constrain_size (GdkGeometry *geometry,
4757 /* This routine is partially borrowed from fvwm.
4759 * Copyright 1993, Robert Nation
4760 * You may use this code for any purpose, as long as the original
4761 * copyright remains in the source code and all documentation
4763 * which in turn borrows parts of the algorithm from uwm
4766 gint min_height = 0;
4767 gint base_width = 0;
4768 gint base_height = 0;
4771 gint max_width = G_MAXINT;
4772 gint max_height = G_MAXINT;
4774 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
4776 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
4778 base_width = geometry->base_width;
4779 base_height = geometry->base_height;
4780 min_width = geometry->min_width;
4781 min_height = geometry->min_height;
4783 else if (flags & GDK_HINT_BASE_SIZE)
4785 base_width = geometry->base_width;
4786 base_height = geometry->base_height;
4787 min_width = geometry->base_width;
4788 min_height = geometry->base_height;
4790 else if (flags & GDK_HINT_MIN_SIZE)
4792 base_width = geometry->min_width;
4793 base_height = geometry->min_height;
4794 min_width = geometry->min_width;
4795 min_height = geometry->min_height;
4798 if (flags & GDK_HINT_MAX_SIZE)
4800 max_width = geometry->max_width ;
4801 max_height = geometry->max_height;
4804 if (flags & GDK_HINT_RESIZE_INC)
4806 xinc = MAX (xinc, geometry->width_inc);
4807 yinc = MAX (yinc, geometry->height_inc);
4810 /* clamp width and height to min and max values
4812 width = CLAMP (width, min_width, max_width);
4813 height = CLAMP (height, min_height, max_height);
4815 /* shrink to base + N * inc
4817 width = base_width + FLOOR (width - base_width, xinc);
4818 height = base_height + FLOOR (height - base_height, yinc);
4820 /* constrain aspect ratio, according to:
4823 * min_aspect <= -------- <= max_aspect
4827 if (flags & GDK_HINT_ASPECT &&
4828 geometry->min_aspect > 0 &&
4829 geometry->max_aspect > 0)
4833 if (geometry->min_aspect * height > width)
4835 delta = FLOOR (height - width / geometry->min_aspect, yinc);
4836 if (height - delta >= min_height)
4840 delta = FLOOR (height * geometry->min_aspect - width, xinc);
4841 if (width + delta <= max_width)
4846 if (geometry->max_aspect * height < width)
4848 delta = FLOOR (width - height * geometry->max_aspect, xinc);
4849 if (width - delta >= min_width)
4853 delta = FLOOR (width / geometry->max_aspect - height, yinc);
4854 if (height + delta <= max_height)
4863 *new_height = height;
4867 * gdk_window_get_pointer:
4868 * @window: a #GdkWindow
4869 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
4870 * return the X coordinate
4871 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
4872 * return the Y coordinate
4873 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
4876 * Obtains the current pointer position and modifier state.
4877 * The position is given in coordinates relative to the upper left
4878 * corner of @window.
4880 * Return value: (transfer none): the window containing the pointer (as with
4881 * gdk_window_at_pointer()), or %NULL if the window containing the
4882 * pointer isn't known to GDK
4884 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
4887 gdk_window_get_pointer (GdkWindow *window,
4890 GdkModifierType *mask)
4892 GdkDisplay *display;
4894 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4896 display = gdk_window_get_display (window);
4898 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
4902 * gdk_window_get_device_position:
4903 * @window: a #GdkWindow.
4904 * @device: pointer #GdkDevice to query to.
4905 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
4906 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
4907 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
4909 * Obtains the current device position and modifier state.
4910 * The position is given in coordinates relative to the upper left
4911 * corner of @window.
4913 * Return value: (transfer none): The window underneath @device (as with
4914 * gdk_device_get_window_at_position()), or %NULL if the window is not known to GDK.
4919 gdk_window_get_device_position (GdkWindow *window,
4923 GdkModifierType *mask)
4926 GdkModifierType tmp_mask;
4927 gboolean normal_child;
4929 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4930 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
4931 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
4933 normal_child = GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_device_state (window,
4937 /* We got the coords on the impl, convert to the window */
4938 tmp_x -= window->abs_x;
4939 tmp_y -= window->abs_y;
4948 _gdk_display_enable_motion_hints (gdk_window_get_display (window), device);
4951 return _gdk_window_find_child_at (window, tmp_x, tmp_y);
4956 * gdk_get_default_root_window:
4958 * Obtains the root window (parent all other windows are inside)
4959 * for the default display and screen.
4961 * Return value: (transfer none): the default root window
4964 gdk_get_default_root_window (void)
4966 return gdk_screen_get_root_window (gdk_screen_get_default ());
4970 get_all_native_children (GdkWindow *window,
4976 for (l = window->children; l != NULL; l = l->next)
4980 if (gdk_window_has_impl (child))
4981 *native = g_list_prepend (*native, child);
4983 get_all_native_children (child, native);
4989 gdk_window_raise_internal (GdkWindow *window)
4991 GdkWindow *parent = window->parent;
4993 GList *native_children;
4995 GdkWindowImplClass *impl_class;
4999 parent->children = g_list_remove (parent->children, window);
5000 parent->children = g_list_prepend (parent->children, window);
5003 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5004 /* Just do native raise for toplevels */
5005 if (gdk_window_is_toplevel (window) ||
5006 /* The restack_under codepath should work correctly even if the parent
5007 is native, but it relies on the order of ->children to be correct,
5008 and some apps like SWT reorder the x windows without gdks knowledge,
5009 so we use raise directly in order to make these behave as before
5010 when using native windows */
5011 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5013 impl_class->raise (window);
5015 else if (gdk_window_has_impl (window))
5017 above = find_native_sibling_above (parent, window);
5020 listhead.data = window;
5021 listhead.next = NULL;
5022 listhead.prev = NULL;
5023 impl_class->restack_under ((GdkWindow *)above,
5027 impl_class->raise (window);
5031 native_children = NULL;
5032 get_all_native_children (window, &native_children);
5033 if (native_children != NULL)
5035 above = find_native_sibling_above (parent, window);
5038 impl_class->restack_under (above, native_children);
5041 /* Right order, since native_children is bottom-topmost first */
5042 for (l = native_children; l != NULL; l = l->next)
5043 impl_class->raise (l->data);
5046 g_list_free (native_children);
5052 /* Returns TRUE If the native window was mapped or unmapped */
5054 set_viewable (GdkWindow *w,
5058 GdkWindowImplClass *impl_class;
5061 if (w->viewable == val)
5067 recompute_visible_regions (w, FALSE, FALSE);
5069 for (l = w->children; l != NULL; l = l->next)
5073 if (GDK_WINDOW_IS_MAPPED (child) &&
5074 child->window_type != GDK_WINDOW_FOREIGN)
5075 set_viewable (child, val);
5078 if (gdk_window_has_impl (w) &&
5079 w->window_type != GDK_WINDOW_FOREIGN &&
5080 !gdk_window_is_toplevel (w))
5082 /* For most native windows we show/hide them not when they are
5083 * mapped/unmapped, because that may not produce the correct results.
5084 * For instance, if a native window have a non-native parent which is
5085 * hidden, but its native parent is viewable then showing the window
5086 * would make it viewable to X but its not viewable wrt the non-native
5087 * hierarchy. In order to handle this we track the gdk side viewability
5088 * and only map really viewable windows.
5090 * There are two exceptions though:
5092 * For foreign windows we don't want ever change the mapped state
5093 * except when explicitly done via gdk_window_show/hide, as this may
5094 * cause problems for client owning the foreign window when its window
5095 * is suddenly mapped or unmapped.
5097 * For toplevel windows embedded in a foreign window (e.g. a plug)
5098 * we sometimes synthesize a map of a window, but the native
5099 * window is really shown by the embedder, so we don't want to
5100 * do the show ourselves. We can't really tell this case from the normal
5101 * toplevel show as such toplevels are seen by gdk as parents of the
5102 * root window, so we make an exception for all toplevels.
5105 impl_class = GDK_WINDOW_IMPL_GET_CLASS (w->impl);
5107 impl_class->show ((GdkWindow *)w, FALSE);
5109 impl_class->hide ((GdkWindow *)w);
5117 /* Returns TRUE If the native window was mapped or unmapped */
5119 _gdk_window_update_viewable (GdkWindow *window)
5123 if (window->window_type == GDK_WINDOW_FOREIGN ||
5124 window->window_type == GDK_WINDOW_ROOT)
5126 else if (gdk_window_is_toplevel (window) ||
5127 window->parent->viewable)
5128 viewable = GDK_WINDOW_IS_MAPPED (window);
5132 return set_viewable (window, viewable);
5136 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5138 GdkWindowImplClass *impl_class;
5139 gboolean was_mapped, was_viewable;
5142 g_return_if_fail (GDK_IS_WINDOW (window));
5144 if (window->destroyed)
5147 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5148 was_viewable = window->viewable;
5151 /* Keep children in (reverse) stacking order */
5152 gdk_window_raise_internal (window);
5154 if (gdk_window_has_impl (window))
5157 gdk_synthesize_window_state (window,
5158 GDK_WINDOW_STATE_WITHDRAWN,
5159 GDK_WINDOW_STATE_FOCUSED);
5166 did_show = _gdk_window_update_viewable (window);
5168 /* If it was already viewable the backend show op won't be called, call it
5169 again to ensure things happen right if the mapped tracking was not right
5170 for e.g. a foreign window.
5171 Dunno if this is strictly needed but its what happened pre-csw.
5172 Also show if not done by gdk_window_update_viewable. */
5173 if (gdk_window_has_impl (window) && (was_viewable || !did_show))
5175 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5176 impl_class->show (window, !did_show ? was_mapped : TRUE);
5179 if (!was_mapped && !gdk_window_has_impl (window))
5181 if (window->event_mask & GDK_STRUCTURE_MASK)
5182 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5184 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5185 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5188 if (!was_mapped || raise)
5190 recompute_visible_regions (window, TRUE, FALSE);
5192 /* If any decendants became visible we need to send visibility notify */
5193 gdk_window_update_visibility_recursively (window, NULL);
5195 if (gdk_window_is_viewable (window))
5197 _gdk_synthesize_crossing_events_for_geometry_change (window);
5198 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5204 * gdk_window_show_unraised:
5205 * @window: a #GdkWindow
5207 * Shows a #GdkWindow onscreen, but does not modify its stacking
5208 * order. In contrast, gdk_window_show() will raise the window
5209 * to the top of the window stack.
5211 * On the X11 platform, in Xlib terms, this function calls
5212 * XMapWindow() (it also updates some internal GDK state, which means
5213 * that you can't really use XMapWindow() directly on a GDK window).
5216 gdk_window_show_unraised (GdkWindow *window)
5218 gdk_window_show_internal (window, FALSE);
5223 * @window: a #GdkWindow
5225 * Raises @window to the top of the Z-order (stacking order), so that
5226 * other windows with the same parent window appear below @window.
5227 * This is true whether or not the windows are visible.
5229 * If @window is a toplevel, the window manager may choose to deny the
5230 * request to move the window in the Z-order, gdk_window_raise() only
5231 * requests the restack, does not guarantee it.
5234 gdk_window_raise (GdkWindow *window)
5236 cairo_region_t *old_region, *new_region;
5238 g_return_if_fail (GDK_IS_WINDOW (window));
5240 if (window->destroyed)
5243 gdk_window_flush_if_exposing (window);
5246 if (gdk_window_is_viewable (window) &&
5247 !window->input_only)
5248 old_region = cairo_region_copy (window->clip_region);
5250 /* Keep children in (reverse) stacking order */
5251 gdk_window_raise_internal (window);
5253 recompute_visible_regions (window, TRUE, FALSE);
5257 new_region = cairo_region_copy (window->clip_region);
5259 cairo_region_subtract (new_region, old_region);
5260 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_ALL);
5262 cairo_region_destroy (old_region);
5263 cairo_region_destroy (new_region);
5268 gdk_window_lower_internal (GdkWindow *window)
5270 GdkWindow *parent = window->parent;
5271 GdkWindowImplClass *impl_class;
5273 GList *native_children;
5278 parent->children = g_list_remove (parent->children, window);
5279 parent->children = g_list_append (parent->children, window);
5282 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5283 /* Just do native lower for toplevels */
5284 if (gdk_window_is_toplevel (window) ||
5285 /* The restack_under codepath should work correctly even if the parent
5286 is native, but it relies on the order of ->children to be correct,
5287 and some apps like SWT reorder the x windows without gdks knowledge,
5288 so we use lower directly in order to make these behave as before
5289 when using native windows */
5290 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5292 impl_class->lower (window);
5294 else if (gdk_window_has_impl (window))
5296 above = find_native_sibling_above (parent, window);
5299 listhead.data = window;
5300 listhead.next = NULL;
5301 listhead.prev = NULL;
5302 impl_class->restack_under ((GdkWindow *)above, &listhead);
5305 impl_class->raise (window);
5309 native_children = NULL;
5310 get_all_native_children (window, &native_children);
5311 if (native_children != NULL)
5313 above = find_native_sibling_above (parent, window);
5316 impl_class->restack_under ((GdkWindow *)above,
5320 /* Right order, since native_children is bottom-topmost first */
5321 for (l = native_children; l != NULL; l = l->next)
5322 impl_class->raise (l->data);
5325 g_list_free (native_children);
5332 gdk_window_invalidate_in_parent (GdkWindow *private)
5334 GdkRectangle r, child;
5336 if (gdk_window_is_toplevel (private))
5339 /* get the visible rectangle of the parent */
5341 r.width = private->parent->width;
5342 r.height = private->parent->height;
5344 child.x = private->x;
5345 child.y = private->y;
5346 child.width = private->width;
5347 child.height = private->height;
5348 gdk_rectangle_intersect (&r, &child, &r);
5350 gdk_window_invalidate_rect_full (private->parent, &r, TRUE, CLEAR_BG_ALL);
5356 * @window: a #GdkWindow
5358 * Lowers @window to the bottom of the Z-order (stacking order), so that
5359 * other windows with the same parent window appear above @window.
5360 * This is true whether or not the other windows are visible.
5362 * If @window is a toplevel, the window manager may choose to deny the
5363 * request to move the window in the Z-order, gdk_window_lower() only
5364 * requests the restack, does not guarantee it.
5366 * Note that gdk_window_show() raises the window again, so don't call this
5367 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5370 gdk_window_lower (GdkWindow *window)
5372 g_return_if_fail (GDK_IS_WINDOW (window));
5374 if (window->destroyed)
5377 gdk_window_flush_if_exposing (window);
5379 /* Keep children in (reverse) stacking order */
5380 gdk_window_lower_internal (window);
5382 recompute_visible_regions (window, TRUE, FALSE);
5384 _gdk_synthesize_crossing_events_for_geometry_change (window);
5385 gdk_window_invalidate_in_parent (window);
5389 * gdk_window_restack:
5390 * @window: a #GdkWindow
5391 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5394 * Changes the position of @window in the Z-order (stacking order), so that
5395 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5398 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5399 * lowers the window.
5401 * If @window is a toplevel, the window manager may choose to deny the
5402 * request to move the window in the Z-order, gdk_window_restack() only
5403 * requests the restack, does not guarantee it.
5408 gdk_window_restack (GdkWindow *window,
5412 GdkWindowImplClass *impl_class;
5414 GdkWindow *above_native;
5415 GList *sibling_link;
5416 GList *native_children;
5419 g_return_if_fail (GDK_IS_WINDOW (window));
5420 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5422 if (window->destroyed)
5425 if (sibling == NULL)
5428 gdk_window_raise (window);
5430 gdk_window_lower (window);
5434 gdk_window_flush_if_exposing (window);
5436 if (gdk_window_is_toplevel (window))
5438 g_return_if_fail (gdk_window_is_toplevel (sibling));
5439 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5440 impl_class->restack_toplevel (window, sibling, above);
5444 parent = window->parent;
5447 sibling_link = g_list_find (parent->children, sibling);
5448 g_return_if_fail (sibling_link != NULL);
5449 if (sibling_link == NULL)
5452 parent->children = g_list_remove (parent->children, window);
5454 parent->children = g_list_insert_before (parent->children,
5458 parent->children = g_list_insert_before (parent->children,
5462 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5463 if (gdk_window_has_impl (window))
5465 above_native = find_native_sibling_above (parent, window);
5468 listhead.data = window;
5469 listhead.next = NULL;
5470 listhead.prev = NULL;
5471 impl_class->restack_under (above_native, &listhead);
5474 impl_class->raise (window);
5478 native_children = NULL;
5479 get_all_native_children (window, &native_children);
5480 if (native_children != NULL)
5482 above_native = find_native_sibling_above (parent, window);
5484 impl_class->restack_under (above_native,
5488 /* Right order, since native_children is bottom-topmost first */
5489 for (l = native_children; l != NULL; l = l->next)
5490 impl_class->raise (l->data);
5493 g_list_free (native_children);
5498 recompute_visible_regions (window, TRUE, FALSE);
5500 _gdk_synthesize_crossing_events_for_geometry_change (window);
5501 gdk_window_invalidate_in_parent (window);
5507 * @window: a #GdkWindow
5509 * Like gdk_window_show_unraised(), but also raises the window to the
5510 * top of the window stack (moves the window to the front of the
5513 * This function maps a window so it's visible onscreen. Its opposite
5514 * is gdk_window_hide().
5516 * When implementing a #GtkWidget, you should call this function on the widget's
5517 * #GdkWindow as part of the "map" method.
5520 gdk_window_show (GdkWindow *window)
5522 gdk_window_show_internal (window, TRUE);
5527 * @window: a #GdkWindow
5529 * For toplevel windows, withdraws them, so they will no longer be
5530 * known to the window manager; for all windows, unmaps them, so
5531 * they won't be displayed. Normally done automatically as
5532 * part of gtk_widget_hide().
5535 gdk_window_hide (GdkWindow *window)
5537 GdkWindowImplClass *impl_class;
5538 gboolean was_mapped, did_hide;
5540 g_return_if_fail (GDK_IS_WINDOW (window));
5542 if (window->destroyed)
5545 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5547 if (gdk_window_has_impl (window))
5550 if (GDK_WINDOW_IS_MAPPED (window))
5551 gdk_synthesize_window_state (window,
5553 GDK_WINDOW_STATE_WITHDRAWN);
5555 else if (was_mapped)
5557 GdkDisplay *display;
5558 GdkDeviceManager *device_manager;
5561 /* May need to break grabs on children */
5562 display = gdk_window_get_display (window);
5563 device_manager = gdk_display_get_device_manager (display);
5565 /* Get all devices */
5566 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5567 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5568 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5570 for (d = devices; d; d = d->next)
5572 GdkDevice *device = d->data;
5574 if (_gdk_display_end_device_grab (display,
5576 _gdk_display_get_next_serial (display),
5579 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5582 window->state = GDK_WINDOW_STATE_WITHDRAWN;
5583 g_list_free (devices);
5586 did_hide = _gdk_window_update_viewable (window);
5588 /* Hide foreign window as those are not handled by update_viewable. */
5589 if (gdk_window_has_impl (window) && (!did_hide))
5591 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5592 impl_class->hide (window);
5595 recompute_visible_regions (window, TRUE, FALSE);
5597 /* all decendants became non-visible, we need to send visibility notify */
5598 gdk_window_update_visibility_recursively (window, NULL);
5600 if (was_mapped && !gdk_window_has_impl (window))
5602 if (window->event_mask & GDK_STRUCTURE_MASK)
5603 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5605 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5606 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5608 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5611 /* Invalidate the rect */
5613 gdk_window_invalidate_in_parent (window);
5617 * gdk_window_withdraw:
5618 * @window: a toplevel #GdkWindow
5620 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5621 * This function is not really useful as gdk_window_hide() automatically
5622 * withdraws toplevel windows before hiding them.
5625 gdk_window_withdraw (GdkWindow *window)
5627 GdkWindowImplClass *impl_class;
5628 gboolean was_mapped;
5630 g_return_if_fail (GDK_IS_WINDOW (window));
5632 if (window->destroyed)
5635 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5637 if (gdk_window_has_impl (window))
5639 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5640 impl_class->withdraw (window);
5644 if (window->event_mask & GDK_STRUCTURE_MASK)
5645 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5647 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5648 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5650 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5653 recompute_visible_regions (window, TRUE, FALSE);
5658 * gdk_window_set_events:
5659 * @window: a #GdkWindow
5660 * @event_mask: event mask for @window
5662 * The event mask for a window determines which events will be reported
5663 * for that window from all master input devices. For example, an event mask
5664 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5665 * press events. The event mask is the bitwise OR of values from the
5666 * #GdkEventMask enumeration.
5669 gdk_window_set_events (GdkWindow *window,
5670 GdkEventMask event_mask)
5672 GdkWindowImplClass *impl_class;
5673 GdkDisplay *display;
5675 g_return_if_fail (GDK_IS_WINDOW (window));
5677 if (window->destroyed)
5680 /* If motion hint is disabled, enable motion events again */
5681 display = gdk_window_get_display (window);
5682 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5683 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5685 GList *devices = window->devices_inside;
5689 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5690 devices = devices->next;
5694 window->event_mask = event_mask;
5696 if (gdk_window_has_impl (window))
5698 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5699 impl_class->set_events (window,
5700 get_native_event_mask (window));
5706 * gdk_window_get_events:
5707 * @window: a #GdkWindow
5709 * Gets the event mask for @window for all master input devices. See
5710 * gdk_window_set_events().
5712 * Return value: event mask for @window
5715 gdk_window_get_events (GdkWindow *window)
5717 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5719 if (window->destroyed)
5722 return window->event_mask;
5726 * gdk_window_set_device_events:
5727 * @window: a #GdkWindow
5728 * @device: #GdkDevice to enable events for.
5729 * @event_mask: event mask for @window
5731 * Sets the event mask for a given device (Normally a floating device, not
5732 * attached to any visible pointer) to @window. For example, an event mask
5733 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5734 * press events. The event mask is the bitwise OR of values from the
5735 * #GdkEventMask enumeration.
5740 gdk_window_set_device_events (GdkWindow *window,
5742 GdkEventMask event_mask)
5744 GdkEventMask device_mask;
5745 GdkDisplay *display;
5748 g_return_if_fail (GDK_IS_WINDOW (window));
5749 g_return_if_fail (GDK_IS_DEVICE (device));
5751 if (GDK_WINDOW_DESTROYED (window))
5754 /* If motion hint is disabled, enable motion events again */
5755 display = gdk_window_get_display (window);
5756 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5757 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5758 _gdk_display_enable_motion_hints (display, device);
5760 if (G_UNLIKELY (!window->device_events))
5761 window->device_events = g_hash_table_new (NULL, NULL);
5763 if (event_mask == 0)
5765 /* FIXME: unsetting events on a master device
5766 * would restore window->event_mask
5768 g_hash_table_remove (window->device_events, device);
5771 g_hash_table_insert (window->device_events, device,
5772 GINT_TO_POINTER (event_mask));
5774 native = gdk_window_get_toplevel (window);
5776 while (gdk_window_is_offscreen (native))
5778 native = gdk_offscreen_window_get_embedder (native);
5780 if (native == NULL ||
5781 (!_gdk_window_has_impl (native) &&
5782 !gdk_window_is_viewable (native)))
5785 native = gdk_window_get_toplevel (native);
5788 device_mask = get_native_device_event_mask (window, device);
5789 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
5793 * gdk_window_get_device_events:
5794 * @window: a #GdkWindow.
5795 * @device: a #GdkDevice.
5797 * Returns the event mask for @window corresponding to an specific device.
5799 * Returns: device event mask for @window
5804 gdk_window_get_device_events (GdkWindow *window,
5809 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5810 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
5812 if (GDK_WINDOW_DESTROYED (window))
5815 if (!window->device_events)
5818 mask = GPOINTER_TO_INT (g_hash_table_lookup (window->device_events, device));
5820 /* FIXME: device could be controlled by window->event_mask */
5826 gdk_window_move_resize_toplevel (GdkWindow *window,
5833 cairo_region_t *old_region, *new_region;
5834 GdkWindowImplClass *impl_class;
5841 is_resize = (width != -1) || (height != -1);
5843 if (gdk_window_is_viewable (window) &&
5844 !window->input_only)
5847 old_region = cairo_region_copy (window->clip_region);
5850 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5851 impl_class->move_resize (window, with_move, x, y, width, height);
5853 /* Avoid recomputing for pure toplevel moves, for performance reasons */
5855 recompute_visible_regions (window, TRUE, FALSE);
5859 new_region = cairo_region_copy (window->clip_region);
5861 /* This is the newly exposed area (due to any resize),
5862 * X will expose it, but lets do that without the roundtrip
5864 cairo_region_subtract (new_region, old_region);
5865 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
5867 cairo_region_destroy (old_region);
5868 cairo_region_destroy (new_region);
5871 _gdk_synthesize_crossing_events_for_geometry_change (window);
5876 move_native_children (GdkWindow *private)
5880 GdkWindowImplClass *impl_class;
5882 for (l = private->children; l; l = l->next)
5886 if (child->impl != private->impl)
5888 impl_class = GDK_WINDOW_IMPL_GET_CLASS (child->impl);
5889 impl_class->move_resize (child, TRUE,
5891 child->width, child->height);
5894 move_native_children (child);
5899 collect_native_child_region_helper (GdkWindow *window,
5900 GdkWindowImpl *impl,
5901 cairo_region_t **region,
5906 cairo_region_t *tmp;
5909 for (l = window->children; l != NULL; l = l->next)
5913 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
5916 if (child->impl != impl)
5918 tmp = cairo_region_copy (child->clip_region);
5919 cairo_region_translate (tmp,
5920 x_offset + child->x,
5921 y_offset + child->y);
5922 if (*region == NULL)
5926 cairo_region_union (*region, tmp);
5927 cairo_region_destroy (tmp);
5931 collect_native_child_region_helper (child, impl, region,
5932 x_offset + child->x,
5933 y_offset + child->y);
5939 static cairo_region_t *
5940 collect_native_child_region (GdkWindow *window,
5941 gboolean include_this)
5943 cairo_region_t *region;
5945 if (include_this && gdk_window_has_impl (window) && window->viewable)
5946 return cairo_region_copy (window->clip_region);
5950 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
5957 gdk_window_move_resize_internal (GdkWindow *window,
5964 cairo_region_t *old_region, *new_region, *copy_area;
5965 cairo_region_t *old_native_child_region, *new_native_child_region;
5966 GdkWindow *impl_window;
5967 GdkWindowImplClass *impl_class;
5969 int old_x, old_y, old_abs_x, old_abs_y;
5972 g_return_if_fail (GDK_IS_WINDOW (window));
5974 if (window->destroyed)
5977 if (gdk_window_is_toplevel (window))
5979 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
5983 /* Bail early if no change */
5984 if (window->width == width &&
5985 window->height == height &&
5991 gdk_window_flush_if_exposing (window);
5993 /* Handle child windows */
5998 impl_window = gdk_window_get_impl_window (window);
6003 old_native_child_region = NULL;
6004 if (gdk_window_is_viewable (window) &&
6005 !window->input_only)
6009 old_region = cairo_region_copy (window->clip_region);
6010 /* Adjust region to parent window coords */
6011 cairo_region_translate (old_region, window->x, window->y);
6013 old_native_child_region = collect_native_child_region (window, TRUE);
6014 if (old_native_child_region)
6016 /* Adjust region to parent window coords */
6017 cairo_region_translate (old_native_child_region, window->x, window->y);
6019 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6020 * source or destination for a delayed GdkWindowRegionMove. So, we need
6021 * to flush those here for the parent window and all overlapped subwindows
6022 * of it. And we need to do this before setting the new clips as those will be
6025 gdk_window_flush_recursive (window->parent);
6029 /* Set the new position and size */
6035 if (!(width < 0 && height < 0))
6039 window->width = width;
6042 window->height = height;
6045 dx = window->x - old_x;
6046 dy = window->y - old_y;
6048 old_abs_x = window->abs_x;
6049 old_abs_y = window->abs_y;
6051 recompute_visible_regions (window, TRUE, FALSE);
6053 new_native_child_region = NULL;
6054 if (old_native_child_region)
6056 new_native_child_region = collect_native_child_region (window, TRUE);
6057 /* Adjust region to parent window coords */
6058 cairo_region_translate (new_native_child_region, window->x, window->y);
6061 if (gdk_window_has_impl (window))
6063 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6065 /* Do the actual move after recomputing things, as this will have set the shape to
6066 the now correct one, thus avoiding copying regions that should not be copied. */
6067 impl_class->move_resize (window, TRUE,
6068 window->x, window->y,
6069 window->width, window->height);
6071 else if (old_abs_x != window->abs_x ||
6072 old_abs_y != window->abs_y)
6073 move_native_children (window);
6077 new_region = cairo_region_copy (window->clip_region);
6078 /* Adjust region to parent window coords */
6079 cairo_region_translate (new_region, window->x, window->y);
6082 * Part of the data at the new location can be copied from the
6083 * old location, this area is the intersection of the old region
6084 * moved as the copy will move it and then intersected with
6088 * Everything in the old and new regions that is not copied must be
6089 * invalidated (including children) as this is newly exposed
6091 copy_area = cairo_region_copy (new_region);
6093 cairo_region_union (new_region, old_region);
6095 if (old_native_child_region)
6097 /* Don't copy from inside native children, as this is copied by
6098 * the native window move.
6100 cairo_region_subtract (old_region, old_native_child_region);
6102 cairo_region_translate (old_region, dx, dy);
6104 cairo_region_intersect (copy_area, old_region);
6106 if (new_native_child_region)
6108 /* Don't copy any bits that would cause a read from the moved
6109 native windows, as we can't read that data */
6110 cairo_region_translate (new_native_child_region, dx, dy);
6111 cairo_region_subtract (copy_area, new_native_child_region);
6112 cairo_region_translate (new_native_child_region, -dx, -dy);
6115 cairo_region_subtract (new_region, copy_area);
6117 /* Convert old region to impl coords */
6118 cairo_region_translate (old_region, -dx + window->abs_x - window->x, -dy + window->abs_y - window->y);
6120 /* convert from parent coords to impl */
6121 cairo_region_translate (copy_area, window->abs_x - window->x, window->abs_y - window->y);
6123 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6125 /* Invalidate affected part in the parent window
6126 * (no higher window should be affected)
6127 * We also invalidate any children in that area, which could include
6128 * this window if it still overlaps that area.
6130 if (old_native_child_region)
6132 /* No need to expose the region that the native window move copies */
6133 cairo_region_translate (old_native_child_region, dx, dy);
6134 cairo_region_intersect (old_native_child_region, new_native_child_region);
6135 cairo_region_subtract (new_region, old_native_child_region);
6137 gdk_window_invalidate_region_full (window->parent, new_region, TRUE, CLEAR_BG_ALL);
6139 cairo_region_destroy (old_region);
6140 cairo_region_destroy (new_region);
6143 if (old_native_child_region)
6145 cairo_region_destroy (old_native_child_region);
6146 cairo_region_destroy (new_native_child_region);
6149 _gdk_synthesize_crossing_events_for_geometry_change (window);
6156 * @window: a #GdkWindow
6157 * @x: X coordinate relative to window's parent
6158 * @y: Y coordinate relative to window's parent
6160 * Repositions a window relative to its parent window.
6161 * For toplevel windows, window managers may ignore or modify the move;
6162 * you should probably use gtk_window_move() on a #GtkWindow widget
6163 * anyway, instead of using GDK functions. For child windows,
6164 * the move will reliably succeed.
6166 * If you're also planning to resize the window, use gdk_window_move_resize()
6167 * to both move and resize simultaneously, for a nicer visual effect.
6170 gdk_window_move (GdkWindow *window,
6174 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6178 * gdk_window_resize:
6179 * @window: a #GdkWindow
6180 * @width: new width of the window
6181 * @height: new height of the window
6183 * Resizes @window; for toplevel windows, asks the window manager to resize
6184 * the window. The window manager may not allow the resize. When using GTK+,
6185 * use gtk_window_resize() instead of this low-level GDK function.
6187 * Windows may not be resized below 1x1.
6189 * If you're also planning to move the window, use gdk_window_move_resize()
6190 * to both move and resize simultaneously, for a nicer visual effect.
6193 gdk_window_resize (GdkWindow *window,
6197 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6202 * gdk_window_move_resize:
6203 * @window: a #GdkWindow
6204 * @x: new X position relative to window's parent
6205 * @y: new Y position relative to window's parent
6207 * @height: new height
6209 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6210 * except that both operations are performed at once, avoiding strange
6211 * visual effects. (i.e. the user may be able to see the window first
6212 * move, then resize, if you don't use gdk_window_move_resize().)
6215 gdk_window_move_resize (GdkWindow *window,
6221 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6226 * gdk_window_scroll:
6227 * @window: a #GdkWindow
6228 * @dx: Amount to scroll in the X direction
6229 * @dy: Amount to scroll in the Y direction
6231 * Scroll the contents of @window, both pixels and children, by the
6232 * given amount. @window itself does not move. Portions of the window
6233 * that the scroll operation brings in from offscreen areas are
6234 * invalidated. The invalidated region may be bigger than what would
6235 * strictly be necessary.
6237 * For X11, a minimum area will be invalidated if the window has no
6238 * subwindows, or if the edges of the window's parent do not extend
6239 * beyond the edges of the window. In other cases, a multi-step process
6240 * is used to scroll the window which may produce temporary visual
6241 * artifacts and unnecessary invalidations.
6244 gdk_window_scroll (GdkWindow *window,
6248 GdkWindow *impl_window;
6249 cairo_region_t *copy_area, *noncopy_area;
6250 cairo_region_t *old_native_child_region, *new_native_child_region;
6253 g_return_if_fail (GDK_IS_WINDOW (window));
6255 if (dx == 0 && dy == 0)
6258 if (window->destroyed)
6261 gdk_window_flush_if_exposing (window);
6263 old_native_child_region = collect_native_child_region (window, FALSE);
6264 if (old_native_child_region)
6266 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6267 * source or destination for a delayed GdkWindowRegionMove. So, we need
6268 * to flush those here for the window and all overlapped subwindows
6269 * of it. And we need to do this before setting the new clips as those will be
6272 gdk_window_flush_recursive (window);
6276 /* First move all child windows, without causing invalidation */
6278 tmp_list = window->children;
6281 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6283 /* Just update the positions, the bits will move with the copy */
6287 tmp_list = tmp_list->next;
6290 recompute_visible_regions (window, FALSE, TRUE);
6292 new_native_child_region = NULL;
6293 if (old_native_child_region)
6294 new_native_child_region = collect_native_child_region (window, FALSE);
6296 move_native_children (window);
6298 /* Then copy the actual bits of the window w/ child windows */
6300 impl_window = gdk_window_get_impl_window (window);
6302 /* Calculate the area that can be gotten by copying the old area */
6303 copy_area = cairo_region_copy (window->clip_region);
6304 if (old_native_child_region)
6306 /* Don't copy from inside native children, as this is copied by
6307 * the native window move.
6309 cairo_region_subtract (copy_area, old_native_child_region);
6311 /* Don't copy any bits that would cause a read from the moved
6312 native windows, as we can't read that data */
6313 cairo_region_subtract (copy_area, new_native_child_region);
6315 cairo_region_translate (copy_area, dx, dy);
6316 cairo_region_intersect (copy_area, window->clip_region);
6318 /* And the rest need to be invalidated */
6319 noncopy_area = cairo_region_copy (window->clip_region);
6320 cairo_region_subtract (noncopy_area, copy_area);
6322 /* convert from window coords to impl */
6323 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6325 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6327 /* Invalidate not copied regions */
6328 if (old_native_child_region)
6330 /* No need to expose the region that the native window move copies */
6331 cairo_region_translate (old_native_child_region, dx, dy);
6332 cairo_region_intersect (old_native_child_region, new_native_child_region);
6333 cairo_region_subtract (noncopy_area, old_native_child_region);
6335 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6337 cairo_region_destroy (noncopy_area);
6339 if (old_native_child_region)
6341 cairo_region_destroy (old_native_child_region);
6342 cairo_region_destroy (new_native_child_region);
6345 _gdk_synthesize_crossing_events_for_geometry_change (window);
6349 * gdk_window_move_region:
6350 * @window: a #GdkWindow
6351 * @region: The #cairo_region_t to move
6352 * @dx: Amount to move in the X direction
6353 * @dy: Amount to move in the Y direction
6355 * Move the part of @window indicated by @region by @dy pixels in the Y
6356 * direction and @dx pixels in the X direction. The portions of @region
6357 * that not covered by the new position of @region are invalidated.
6359 * Child windows are not moved.
6364 gdk_window_move_region (GdkWindow *window,
6365 const cairo_region_t *region,
6369 GdkWindow *impl_window;
6370 cairo_region_t *nocopy_area;
6371 cairo_region_t *copy_area;
6373 g_return_if_fail (GDK_IS_WINDOW (window));
6374 g_return_if_fail (region != NULL);
6376 if (dx == 0 && dy == 0)
6379 if (window->destroyed)
6382 impl_window = gdk_window_get_impl_window (window);
6384 /* compute source regions */
6385 copy_area = cairo_region_copy (region);
6386 cairo_region_intersect (copy_area, window->clip_region_with_children);
6388 /* compute destination regions */
6389 cairo_region_translate (copy_area, dx, dy);
6390 cairo_region_intersect (copy_area, window->clip_region_with_children);
6392 /* Invalidate parts of the region (source and dest) not covered
6394 nocopy_area = cairo_region_copy (region);
6395 cairo_region_translate (nocopy_area, dx, dy);
6396 cairo_region_union (nocopy_area, region);
6397 cairo_region_subtract (nocopy_area, copy_area);
6399 /* convert from window coords to impl */
6400 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6401 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6403 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6404 cairo_region_destroy (nocopy_area);
6408 * gdk_window_set_background:
6409 * @window: a #GdkWindow
6410 * @color: a #GdkColor
6412 * Sets the background color of @window. (However, when using GTK+,
6413 * set the background of a widget with gtk_widget_modify_bg() - if
6414 * you're an application - or gtk_style_set_background() - if you're
6415 * implementing a custom widget.)
6417 * See also gdk_window_set_background_pattern().
6420 gdk_window_set_background (GdkWindow *window,
6421 const GdkColor *color)
6423 cairo_pattern_t *pattern;
6425 g_return_if_fail (GDK_IS_WINDOW (window));
6427 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6428 color->green / 65535.,
6429 color->blue / 65535.);
6431 gdk_window_set_background_pattern (window, pattern);
6433 cairo_pattern_destroy (pattern);
6437 * gdk_window_set_background_rgba:
6438 * @window: a #GdkWindow
6439 * @rgba: a #GdkRGBA color
6441 * Sets the background color of @window.
6443 * See also gdk_window_set_background_pattern().
6446 gdk_window_set_background_rgba (GdkWindow *window,
6449 cairo_pattern_t *pattern;
6451 g_return_if_fail (GDK_IS_WINDOW (window));
6452 g_return_if_fail (rgba != NULL);
6454 pattern = cairo_pattern_create_rgba (rgba->red, rgba->green,
6455 rgba->blue, rgba->alpha);
6457 gdk_window_set_background_pattern (window, pattern);
6459 cairo_pattern_destroy (pattern);
6463 * gdk_window_set_background_pattern:
6464 * @window: a #GdkWindow
6465 * @pattern: (allow-none): a pattern to use, or %NULL
6467 * Sets the background of @window.
6469 * A background of %NULL means that the window will inherit its
6470 * background form its parent window.
6472 * The windowing system will normally fill a window with its background
6473 * when the window is obscured then exposed.
6476 gdk_window_set_background_pattern (GdkWindow *window,
6477 cairo_pattern_t *pattern)
6480 cairo_pattern_type_t type;
6482 g_return_if_fail (GDK_IS_WINDOW (window));
6484 if (window->input_only)
6488 cairo_pattern_reference (pattern);
6489 if (window->background)
6490 cairo_pattern_destroy (window->background);
6491 window->background = pattern;
6494 type = cairo_pattern_get_type (pattern);
6496 if (type == CAIRO_PATTERN_TYPE_SOLID)
6499 cairo_pattern_get_rgba (pattern, NULL, NULL, NULL, &alpha);
6503 else if (type == CAIRO_PATTERN_TYPE_LINEAR ||
6504 type == CAIRO_PATTERN_TYPE_RADIAL)
6510 cairo_pattern_get_color_stop_count (pattern, &n);
6512 for (i = 0; i < n; i++)
6514 cairo_pattern_get_color_stop_rgba (pattern, i, NULL,
6515 NULL, NULL, NULL, &alpha);
6523 else if (type == CAIRO_PATTERN_TYPE_SURFACE)
6525 cairo_surface_t *surface;
6526 cairo_content_t content;
6528 cairo_pattern_get_surface (pattern, &surface);
6529 content = cairo_surface_get_content (surface);
6531 (content == CAIRO_CONTENT_ALPHA) ||
6532 (content == CAIRO_CONTENT_COLOR_ALPHA);
6535 if (has_alpha != window->has_alpha_background)
6537 window->has_alpha_background = has_alpha;
6538 recompute_visible_regions (window, TRUE, FALSE);
6541 if (gdk_window_has_impl (window))
6543 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6544 impl_class->set_background (window, pattern);
6547 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
6551 * gdk_window_get_background_pattern:
6554 * Gets the pattern used to clear the background on @window. If @window
6555 * does not have its own background and reuses the parent's, %NULL is
6556 * returned and you'll have to query it yourself.
6558 * Returns: (transfer none): The pattern to use for the background or
6559 * %NULL to use the parent's background.
6564 gdk_window_get_background_pattern (GdkWindow *window)
6566 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6568 return window->background;
6572 gdk_window_set_cursor_internal (GdkWindow *window,
6576 if (GDK_WINDOW_DESTROYED (window))
6579 if (window->window_type == GDK_WINDOW_ROOT ||
6580 window->window_type == GDK_WINDOW_FOREIGN)
6581 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_device_cursor (window, device, cursor);
6584 GdkPointerWindowInfo *pointer_info;
6585 GdkDisplay *display;
6587 display = gdk_window_get_display (window);
6588 pointer_info = _gdk_display_get_pointer_info (display, device);
6590 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6591 update_cursor (display, device);
6596 * gdk_window_get_cursor:
6597 * @window: a #GdkWindow
6599 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6600 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6601 * there is no custom cursor set on the specified window, and it is
6602 * using the cursor for its parent window.
6604 * Return value: (transfer none): a #GdkCursor, or %NULL. The returned
6605 * object is owned by the #GdkWindow and should not be unreferenced
6606 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6612 gdk_window_get_cursor (GdkWindow *window)
6614 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6616 return window->cursor;
6620 * gdk_window_set_cursor:
6621 * @window: a #GdkWindow
6622 * @cursor: (allow-none): a cursor
6624 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6625 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6626 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6627 * to gdk_window_set_cursor() means that @window will use the cursor of its
6628 * parent window. Most windows should use this default.
6631 gdk_window_set_cursor (GdkWindow *window,
6634 GdkDisplay *display;
6636 g_return_if_fail (GDK_IS_WINDOW (window));
6638 display = gdk_window_get_display (window);
6642 g_object_unref (window->cursor);
6643 window->cursor = NULL;
6646 if (!GDK_WINDOW_DESTROYED (window))
6648 GdkDeviceManager *device_manager;
6652 window->cursor = g_object_ref (cursor);
6654 device_manager = gdk_display_get_device_manager (display);
6655 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6657 for (d = devices; d; d = d->next)
6663 if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
6666 gdk_window_set_cursor_internal (window, device, window->cursor);
6669 g_list_free (devices);
6670 g_object_notify (G_OBJECT (window), "cursor");
6675 * gdk_window_get_device_cursor:
6676 * @window: a #GdkWindow.
6677 * @device: a master, pointer #GdkDevice.
6679 * Retrieves a #GdkCursor pointer for the @device currently set on the
6680 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6681 * there is no custom cursor set on the specified window, and it is
6682 * using the cursor for its parent window.
6684 * Returns: (transfer none): a #GdkCursor, or %NULL. The returned
6685 * object is owned by the #GdkWindow and should not be unreferenced
6686 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6692 gdk_window_get_device_cursor (GdkWindow *window,
6695 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6696 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6697 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
6698 g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER, NULL);
6700 return g_hash_table_lookup (window->device_cursor, device);
6704 * gdk_window_set_device_cursor:
6705 * @window: a #Gdkwindow
6706 * @device: a master, pointer #GdkDevice
6707 * @cursor: a #GdkCursor
6709 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6710 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6711 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6712 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6713 * @window will use the cursor of its parent window. Most windows should
6719 gdk_window_set_device_cursor (GdkWindow *window,
6723 g_return_if_fail (GDK_IS_WINDOW (window));
6724 g_return_if_fail (GDK_IS_DEVICE (device));
6725 g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
6726 g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
6729 g_hash_table_remove (window->device_cursor, device);
6731 g_hash_table_replace (window->device_cursor, device, g_object_ref (cursor));
6733 gdk_window_set_cursor_internal (window, device, cursor);
6737 * gdk_window_get_geometry:
6738 * @window: a #GdkWindow
6739 * @x: (out) (allow-none): return location for X coordinate of window (relative to its parent)
6740 * @y: (out) (allow-none): return location for Y coordinate of window (relative to its parent)
6741 * @width: (out) (allow-none): return location for width of window
6742 * @height: (out) (allow-none): return location for height of window
6744 * Any of the return location arguments to this function may be %NULL,
6745 * if you aren't interested in getting the value of that field.
6747 * The X and Y coordinates returned are relative to the parent window
6748 * of @window, which for toplevels usually means relative to the
6749 * window decorations (titlebar, etc.) rather than relative to the
6750 * root window (screen-size background window).
6752 * On the X11 platform, the geometry is obtained from the X server,
6753 * so reflects the latest position of @window; this may be out-of-sync
6754 * with the position of @window delivered in the most-recently-processed
6755 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
6756 * position from the most recent configure event.
6759 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
6760 * to call gdk_window_get_position(), gdk_window_get_width() and
6761 * gdk_window_get_height() instead, because it avoids the roundtrip to
6762 * the X server and because these functions support the full 32-bit
6763 * coordinate space, whereas gdk_window_get_geometry() is restricted to
6764 * the 16-bit coordinates of X11.
6768 gdk_window_get_geometry (GdkWindow *window,
6775 GdkWindowImplClass *impl_class;
6779 GDK_NOTE (MULTIHEAD,
6780 g_message ("gdk_window_get_geometry(): Window needs "
6781 "to be non-NULL to be multi head safe"));
6782 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
6785 g_return_if_fail (GDK_IS_WINDOW (window));
6787 if (!GDK_WINDOW_DESTROYED (window))
6789 if (gdk_window_has_impl (window))
6791 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6792 impl_class->get_geometry (window, x, y,
6794 /* This reports the position wrt to the native parent, we need to convert
6795 it to be relative to the client side parent */
6796 parent = window->parent;
6797 if (parent && !gdk_window_has_impl (parent))
6800 *x -= parent->abs_x;
6802 *y -= parent->abs_y;
6812 *width = window->width;
6814 *height = window->height;
6820 * gdk_window_get_width:
6821 * @window: a #GdkWindow
6823 * Returns the width of the given @window.
6825 * On the X11 platform the returned size is the size reported in the
6826 * most-recently-processed configure event, rather than the current
6827 * size on the X server.
6829 * Returns: The width of @window
6834 gdk_window_get_width (GdkWindow *window)
6836 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6838 return window->width;
6842 * gdk_window_get_height:
6843 * @window: a #GdkWindow
6845 * Returns the height of the given @window.
6847 * On the X11 platform the returned size is the size reported in the
6848 * most-recently-processed configure event, rather than the current
6849 * size on the X server.
6851 * Returns: The height of @window
6856 gdk_window_get_height (GdkWindow *window)
6858 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6860 return window->height;
6864 * gdk_window_get_origin:
6865 * @window: a #GdkWindow
6866 * @x: (out) (allow-none): return location for X coordinate
6867 * @y: (out) (allow-none): return location for Y coordinate
6869 * Obtains the position of a window in root window coordinates.
6870 * (Compare with gdk_window_get_position() and
6871 * gdk_window_get_geometry() which return the position of a window
6872 * relative to its parent window.)
6874 * Return value: not meaningful, ignore
6877 gdk_window_get_origin (GdkWindow *window,
6881 GdkWindowImplClass *impl_class;
6883 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6885 if (GDK_WINDOW_DESTROYED (window))
6894 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6895 impl_class->get_root_coords (window,
6904 * gdk_window_get_root_coords:
6905 * @window: a #GdkWindow
6906 * @x: X coordinate in window
6907 * @y: Y coordinate in window
6908 * @root_x: (out): return location for X coordinate
6909 * @root_y: (out): return location for Y coordinate
6911 * Obtains the position of a window position in root
6912 * window coordinates. This is similar to
6913 * gdk_window_get_origin() but allows you go pass
6914 * in any position in the window, not just the origin.
6919 gdk_window_get_root_coords (GdkWindow *window,
6925 GdkWindowImplClass *impl_class;
6927 g_return_if_fail (GDK_IS_WINDOW (window));
6929 if (GDK_WINDOW_DESTROYED (window))
6936 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6937 impl_class->get_root_coords (window,
6944 * gdk_window_coords_to_parent:
6945 * @window: a child window
6946 * @x: X coordinate in child's coordinate system
6947 * @y: Y coordinate in child's coordinate system
6948 * @parent_x: (out) (allow-none): return location for X coordinate
6949 * in parent's coordinate system, or %NULL
6950 * @parent_y: (out) (allow-none): return location for Y coordinate
6951 * in parent's coordinate system, or %NULL
6953 * Transforms window coordinates from a child window to its parent
6954 * window, where the parent window is the normal parent as returned by
6955 * gdk_window_get_parent() for normal windows, and the window's
6956 * embedder as returned by gdk_offscreen_window_get_embedder() for
6957 * offscreen windows.
6959 * For normal windows, calling this function is equivalent to adding
6960 * the return values of gdk_window_get_position() to the child coordinates.
6961 * For offscreen windows however (which can be arbitrarily transformed),
6962 * this function calls the GdkWindow::to-embedder: signal to translate
6965 * You should always use this function when writing generic code that
6966 * walks up a window hierarchy.
6968 * See also: gdk_window_coords_from_parent()
6973 gdk_window_coords_to_parent (GdkWindow *window,
6979 g_return_if_fail (GDK_IS_WINDOW (window));
6981 if (gdk_window_is_offscreen (window))
6985 to_embedder (window, x, y, &px, &py);
6996 *parent_x = x + window->x;
6999 *parent_y = y + window->y;
7004 * gdk_window_coords_from_parent:
7005 * @window: a child window
7006 * @parent_x: X coordinate in parent's coordinate system
7007 * @parent_y: Y coordinate in parent's coordinate system
7008 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7009 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7011 * Transforms window coordinates from a parent window to a child
7012 * window, where the parent window is the normal parent as returned by
7013 * gdk_window_get_parent() for normal windows, and the window's
7014 * embedder as returned by gdk_offscreen_window_get_embedder() for
7015 * offscreen windows.
7017 * For normal windows, calling this function is equivalent to subtracting
7018 * the return values of gdk_window_get_position() from the parent coordinates.
7019 * For offscreen windows however (which can be arbitrarily transformed),
7020 * this function calls the GdkWindow::from-embedder: signal to translate
7023 * You should always use this function when writing generic code that
7024 * walks down a window hierarchy.
7026 * See also: gdk_window_coords_to_parent()
7031 gdk_window_coords_from_parent (GdkWindow *window,
7037 g_return_if_fail (GDK_IS_WINDOW (window));
7039 if (gdk_window_is_offscreen (window))
7043 from_embedder (window, parent_x, parent_y, &cx, &cy);
7054 *x = parent_x - window->x;
7057 *y = parent_y - window->y;
7062 * gdk_window_shape_combine_region:
7063 * @window: a #GdkWindow
7064 * @shape_region: (allow-none): region of window to be non-transparent
7065 * @offset_x: X position of @shape_region in @window coordinates
7066 * @offset_y: Y position of @shape_region in @window coordinates
7068 * Makes pixels in @window outside @shape_region be transparent,
7069 * so that the window may be nonrectangular.
7071 * If @shape_region is %NULL, the shape will be unset, so the whole
7072 * window will be opaque again. @offset_x and @offset_y are ignored
7073 * if @shape_region is %NULL.
7075 * On the X11 platform, this uses an X server extension which is
7076 * widely available on most common platforms, but not available on
7077 * very old X servers, and occasionally the implementation will be
7078 * buggy. On servers without the shape extension, this function
7081 * This function works on both toplevel and child windows.
7084 gdk_window_shape_combine_region (GdkWindow *window,
7085 const cairo_region_t *shape_region,
7089 cairo_region_t *old_region, *new_region, *diff;
7091 g_return_if_fail (GDK_IS_WINDOW (window));
7093 if (GDK_WINDOW_DESTROYED (window))
7096 if (!window->shape && shape_region == NULL)
7099 window->shaped = (shape_region != NULL);
7102 cairo_region_destroy (window->shape);
7105 if (GDK_WINDOW_IS_MAPPED (window))
7106 old_region = cairo_region_copy (window->clip_region);
7110 window->shape = cairo_region_copy (shape_region);
7111 cairo_region_translate (window->shape, offset_x, offset_y);
7114 window->shape = NULL;
7116 recompute_visible_regions (window, TRUE, FALSE);
7118 if (gdk_window_has_impl (window) &&
7119 !should_apply_clip_as_shape (window))
7120 apply_shape (window, window->shape);
7124 new_region = cairo_region_copy (window->clip_region);
7126 /* New area in the window, needs invalidation */
7127 diff = cairo_region_copy (new_region);
7128 cairo_region_subtract (diff, old_region);
7130 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7132 cairo_region_destroy (diff);
7134 if (!gdk_window_is_toplevel (window))
7136 /* New area in the non-root parent window, needs invalidation */
7137 diff = cairo_region_copy (old_region);
7138 cairo_region_subtract (diff, new_region);
7140 /* Adjust region to parent window coords */
7141 cairo_region_translate (diff, window->x, window->y);
7143 gdk_window_invalidate_region_full (window->parent, diff, TRUE, CLEAR_BG_ALL);
7145 cairo_region_destroy (diff);
7148 cairo_region_destroy (new_region);
7149 cairo_region_destroy (old_region);
7154 do_child_shapes (GdkWindow *window,
7158 cairo_region_t *region;
7162 r.width = window->width;
7163 r.height = window->height;
7165 region = cairo_region_create_rectangle (&r);
7166 remove_child_area (window, NULL, FALSE, region);
7168 if (merge && window->shape)
7169 cairo_region_subtract (region, window->shape);
7171 gdk_window_shape_combine_region (window, region, 0, 0);
7175 * gdk_window_set_child_shapes:
7176 * @window: a #GdkWindow
7178 * Sets the shape mask of @window to the union of shape masks
7179 * for all children of @window, ignoring the shape mask of @window
7180 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7181 * the shape mask of @window in the masks to be merged.
7184 gdk_window_set_child_shapes (GdkWindow *window)
7186 g_return_if_fail (GDK_IS_WINDOW (window));
7188 do_child_shapes (window, FALSE);
7192 * gdk_window_merge_child_shapes:
7193 * @window: a #GdkWindow
7195 * Merges the shape masks for any child windows into the
7196 * shape mask for @window. i.e. the union of all masks
7197 * for @window and its children will become the new mask
7198 * for @window. See gdk_window_shape_combine_region().
7200 * This function is distinct from gdk_window_set_child_shapes()
7201 * because it includes @window's shape mask in the set of shapes to
7205 gdk_window_merge_child_shapes (GdkWindow *window)
7207 g_return_if_fail (GDK_IS_WINDOW (window));
7209 do_child_shapes (window, TRUE);
7213 * gdk_window_input_shape_combine_region:
7214 * @window: a #GdkWindow
7215 * @shape_region: region of window to be non-transparent
7216 * @offset_x: X position of @shape_region in @window coordinates
7217 * @offset_y: Y position of @shape_region in @window coordinates
7219 * Like gdk_window_shape_combine_region(), but the shape applies
7220 * only to event handling. Mouse events which happen while
7221 * the pointer position corresponds to an unset bit in the
7222 * mask will be passed on the window below @window.
7224 * An input shape is typically used with RGBA windows.
7225 * The alpha channel of the window defines which pixels are
7226 * invisible and allows for nicely antialiased borders,
7227 * and the input shape controls where the window is
7230 * On the X11 platform, this requires version 1.1 of the
7233 * On the Win32 platform, this functionality is not present and the
7234 * function does nothing.
7239 gdk_window_input_shape_combine_region (GdkWindow *window,
7240 const cairo_region_t *shape_region,
7244 GdkWindowImplClass *impl_class;
7246 g_return_if_fail (GDK_IS_WINDOW (window));
7248 if (GDK_WINDOW_DESTROYED (window))
7251 if (window->input_shape)
7252 cairo_region_destroy (window->input_shape);
7256 window->input_shape = cairo_region_copy (shape_region);
7257 cairo_region_translate (window->input_shape, offset_x, offset_y);
7260 window->input_shape = NULL;
7262 if (gdk_window_has_impl (window))
7264 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7265 impl_class->input_shape_combine_region (window, window->input_shape, 0, 0);
7268 /* Pointer may have e.g. moved outside window due to the input mask change */
7269 _gdk_synthesize_crossing_events_for_geometry_change (window);
7273 do_child_input_shapes (GdkWindow *window,
7277 cairo_region_t *region;
7281 r.width = window->width;
7282 r.height = window->height;
7284 region = cairo_region_create_rectangle (&r);
7285 remove_child_area (window, NULL, TRUE, region);
7287 if (merge && window->shape)
7288 cairo_region_subtract (region, window->shape);
7289 if (merge && window->input_shape)
7290 cairo_region_subtract (region, window->input_shape);
7292 gdk_window_input_shape_combine_region (window, region, 0, 0);
7297 * gdk_window_set_child_input_shapes:
7298 * @window: a #GdkWindow
7300 * Sets the input shape mask of @window to the union of input shape masks
7301 * for all children of @window, ignoring the input shape mask of @window
7302 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7303 * the input shape mask of @window in the masks to be merged.
7308 gdk_window_set_child_input_shapes (GdkWindow *window)
7310 g_return_if_fail (GDK_IS_WINDOW (window));
7312 do_child_input_shapes (window, FALSE);
7316 * gdk_window_merge_child_input_shapes:
7317 * @window: a #GdkWindow
7319 * Merges the input shape masks for any child windows into the
7320 * input shape mask for @window. i.e. the union of all input masks
7321 * for @window and its children will become the new input mask
7322 * for @window. See gdk_window_input_shape_combine_region().
7324 * This function is distinct from gdk_window_set_child_input_shapes()
7325 * because it includes @window's input shape mask in the set of
7326 * shapes to be merged.
7331 gdk_window_merge_child_input_shapes (GdkWindow *window)
7333 g_return_if_fail (GDK_IS_WINDOW (window));
7335 do_child_input_shapes (window, TRUE);
7340 * gdk_window_set_static_gravities:
7341 * @window: a #GdkWindow
7342 * @use_static: %TRUE to turn on static gravity
7344 * Set the bit gravity of the given window to static, and flag it so
7345 * all children get static subwindow gravity. This is used if you are
7346 * implementing scary features that involve deep knowledge of the
7347 * windowing system. Don't worry about it unless you have to.
7349 * Return value: %TRUE if the server supports static gravity
7352 gdk_window_set_static_gravities (GdkWindow *window,
7353 gboolean use_static)
7355 GdkWindowImplClass *impl_class;
7357 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7359 if (gdk_window_has_impl (window))
7361 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7362 return impl_class->set_static_gravities (window, use_static);
7369 * gdk_window_get_composited:
7370 * @window: a #GdkWindow
7372 * Determines whether @window is composited.
7374 * See gdk_window_set_composited().
7376 * Returns: %TRUE if the window is composited.
7381 gdk_window_get_composited (GdkWindow *window)
7383 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7385 return window->composited;
7389 * gdk_window_set_composited:
7390 * @window: a #GdkWindow
7391 * @composited: %TRUE to set the window as composited
7393 * Sets a #GdkWindow as composited, or unsets it. Composited
7394 * windows do not automatically have their contents drawn to
7395 * the screen. Drawing is redirected to an offscreen buffer
7396 * and an expose event is emitted on the parent of the composited
7397 * window. It is the responsibility of the parent's expose handler
7398 * to manually merge the off-screen content onto the screen in
7399 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7402 * It only makes sense for child windows to be composited; see
7403 * gdk_window_set_opacity() if you need translucent toplevel
7406 * An additional effect of this call is that the area of this
7407 * window is no longer clipped from regions marked for
7408 * invalidation on its parent. Draws done on the parent
7409 * window are also no longer clipped by the child.
7411 * This call is only supported on some systems (currently,
7412 * only X11 with new enough Xcomposite and Xdamage extensions).
7413 * You must call gdk_display_supports_composite() to check if
7414 * setting a window as composited is supported before
7415 * attempting to do so.
7420 gdk_window_set_composited (GdkWindow *window,
7421 gboolean composited)
7423 GdkDisplay *display;
7424 GdkWindowImplClass *impl_class;
7426 g_return_if_fail (GDK_IS_WINDOW (window));
7428 composited = composited != FALSE;
7430 if (window->composited == composited)
7434 gdk_window_ensure_native (window);
7436 display = gdk_window_get_display (window);
7438 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7440 if (composited && (!gdk_display_supports_composite (display) || !impl_class->set_composited))
7442 g_warning ("gdk_window_set_composited called but "
7443 "compositing is not supported");
7447 impl_class->set_composited (window, composited);
7449 recompute_visible_regions (window, TRUE, FALSE);
7451 if (GDK_WINDOW_IS_MAPPED (window))
7452 gdk_window_invalidate_in_parent (window);
7454 window->composited = composited;
7458 * gdk_window_get_modal_hint:
7459 * @window: A toplevel #GdkWindow.
7461 * Determines whether or not the window manager is hinted that @window
7462 * has modal behaviour.
7464 * Return value: whether or not the window has the modal hint set.
7469 gdk_window_get_modal_hint (GdkWindow *window)
7471 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7473 return window->modal_hint;
7477 * gdk_window_get_accept_focus:
7478 * @window: a toplevel #GdkWindow.
7480 * Determines whether or not the desktop environment shuld be hinted that
7481 * the window does not want to receive input focus.
7483 * Return value: whether or not the window should receive input focus.
7488 gdk_window_get_accept_focus (GdkWindow *window)
7490 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7492 return window->accept_focus;
7496 * gdk_window_get_focus_on_map:
7497 * @window: a toplevel #GdkWindow.
7499 * Determines whether or not the desktop environment should be hinted that the
7500 * window does not want to receive input focus when it is mapped.
7502 * Return value: whether or not the window wants to receive input focus when
7508 gdk_window_get_focus_on_map (GdkWindow *window)
7510 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7512 return window->focus_on_map;
7516 * gdk_window_is_input_only:
7517 * @window: a toplevel #GdkWindow
7519 * Determines whether or not the window is an input only window.
7521 * Return value: %TRUE if @window is input only
7526 gdk_window_is_input_only (GdkWindow *window)
7528 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7530 return window->input_only;
7534 * gdk_window_is_shaped:
7535 * @window: a toplevel #GdkWindow
7537 * Determines whether or not the window is shaped.
7539 * Return value: %TRUE if @window is shaped
7544 gdk_window_is_shaped (GdkWindow *window)
7546 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7548 return window->shaped;
7552 window_get_size_rectangle (GdkWindow *window,
7555 rect->x = rect->y = 0;
7556 rect->width = window->width;
7557 rect->height = window->height;
7560 /* Calculates the real clipping region for a window, in window coordinates,
7561 * taking into account other windows, gc clip region and gc clip mask.
7564 _gdk_window_calculate_full_clip_region (GdkWindow *window,
7565 GdkWindow *base_window,
7566 gboolean do_children,
7567 gint *base_x_offset,
7568 gint *base_y_offset)
7570 GdkRectangle visible_rect;
7571 cairo_region_t *real_clip_region;
7572 gint x_offset, y_offset;
7573 GdkWindow *parentwin, *lastwin;
7580 if (!window->viewable || window->input_only)
7581 return cairo_region_create ();
7583 window_get_size_rectangle (window, &visible_rect);
7585 /* real_clip_region is in window coordinates */
7586 real_clip_region = cairo_region_create_rectangle (&visible_rect);
7588 x_offset = y_offset = 0;
7592 parentwin = lastwin;
7594 parentwin = lastwin->parent;
7596 /* Remove the areas of all overlapping windows above parentwin in the hiearachy */
7597 for (; parentwin != NULL &&
7598 (parentwin == window || lastwin != base_window);
7599 lastwin = parentwin, parentwin = lastwin->parent)
7602 GdkRectangle real_clip_rect;
7604 if (parentwin != window)
7606 x_offset += lastwin->x;
7607 y_offset += lastwin->y;
7610 /* children is ordered in reverse stack order */
7611 for (cur = parentwin->children;
7612 cur && cur->data != lastwin;
7615 GdkWindow *child = cur->data;
7617 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
7620 /* Ignore offscreen children, as they don't draw in their parent and
7621 * don't take part in the clipping */
7622 if (gdk_window_is_offscreen (child))
7625 window_get_size_rectangle (child, &visible_rect);
7627 /* Convert rect to "window" coords */
7628 visible_rect.x += child->x - x_offset;
7629 visible_rect.y += child->y - y_offset;
7631 /* This shortcut is really necessary for performance when there are a lot of windows */
7632 cairo_region_get_extents (real_clip_region, &real_clip_rect);
7633 if (visible_rect.x >= real_clip_rect.x + real_clip_rect.width ||
7634 visible_rect.x + visible_rect.width <= real_clip_rect.x ||
7635 visible_rect.y >= real_clip_rect.y + real_clip_rect.height ||
7636 visible_rect.y + visible_rect.height <= real_clip_rect.y)
7639 cairo_region_subtract_rectangle (real_clip_region, &visible_rect);
7642 /* Clip to the parent */
7643 window_get_size_rectangle ((GdkWindow *)parentwin, &visible_rect);
7644 /* Convert rect to "window" coords */
7645 visible_rect.x += - x_offset;
7646 visible_rect.y += - y_offset;
7648 cairo_region_intersect_rectangle (real_clip_region, &visible_rect);
7652 *base_x_offset = x_offset;
7654 *base_y_offset = y_offset;
7656 return real_clip_region;
7660 _gdk_window_add_damage (GdkWindow *toplevel,
7661 cairo_region_t *damaged_region)
7663 GdkDisplay *display;
7664 GdkEvent event = { 0, };
7665 event.expose.type = GDK_DAMAGE;
7666 event.expose.window = toplevel;
7667 event.expose.send_event = FALSE;
7668 event.expose.region = damaged_region;
7669 cairo_region_get_extents (event.expose.region, &event.expose.area);
7670 display = gdk_window_get_display (event.expose.window);
7671 _gdk_event_queue_append (display, gdk_event_copy (&event));
7674 /* Gets the toplevel for a window as used for events,
7675 i.e. including offscreen parents */
7677 get_event_parent (GdkWindow *window)
7679 if (gdk_window_is_offscreen (window))
7680 return gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7682 return window->parent;
7685 /* Gets the toplevel for a window as used for events,
7686 i.e. including offscreen parents going up to the native
7689 get_event_toplevel (GdkWindow *window)
7693 while ((parent = get_event_parent (window)) != NULL &&
7694 (parent->window_type != GDK_WINDOW_ROOT))
7701 _gdk_window_event_parent_of (GdkWindow *parent,
7712 w = get_event_parent (w);
7719 update_cursor (GdkDisplay *display,
7722 GdkWindow *cursor_window, *parent, *toplevel;
7723 GdkWindow *pointer_window;
7724 GdkWindowImplClass *impl_class;
7725 GdkPointerWindowInfo *pointer_info;
7726 GdkDeviceGrabInfo *grab;
7729 pointer_info = _gdk_display_get_pointer_info (display, device);
7730 pointer_window = pointer_info->window_under_pointer;
7732 /* We ignore the serials here and just pick the last grab
7733 we've sent, as that would shortly be used anyway. */
7734 grab = _gdk_display_get_last_device_grab (display, device);
7737 /* the pointer is not in a descendant of the grab window */
7738 !_gdk_window_event_parent_of (grab->window, pointer_window))
7740 /* use the cursor from the grab window */
7741 cursor_window = grab->window;
7745 /* otherwise use the cursor from the pointer window */
7746 cursor_window = pointer_window;
7749 /* Find the first window with the cursor actually set, as
7750 the cursor is inherited from the parent */
7751 while (cursor_window->cursor == NULL &&
7752 (parent = get_event_parent (cursor_window)) != NULL &&
7753 parent->window_type != GDK_WINDOW_ROOT)
7754 cursor_window = parent;
7756 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
7759 cursor = cursor_window->cursor;
7761 /* Set all cursors on toplevel, otherwise its tricky to keep track of
7762 * which native window has what cursor set. */
7763 toplevel = get_event_toplevel (pointer_window);
7764 impl_class = GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl);
7765 impl_class->set_device_cursor (toplevel, device, cursor);
7769 point_in_window (GdkWindow *window,
7774 x >= 0 && x < window->width &&
7775 y >= 0 && y < window->height &&
7776 (window->shape == NULL ||
7777 cairo_region_contains_point (window->shape,
7779 (window->input_shape == NULL ||
7780 cairo_region_contains_point (window->input_shape,
7785 convert_native_coords_to_toplevel (GdkWindow *window,
7788 gdouble *toplevel_x,
7789 gdouble *toplevel_y)
7796 while (!gdk_window_is_toplevel (window))
7800 window = window->parent;
7810 convert_toplevel_coords_to_window (GdkWindow *window,
7818 GList *children, *l;
7824 while ((parent = get_event_parent (window)) != NULL &&
7825 (parent->window_type != GDK_WINDOW_ROOT))
7827 children = g_list_prepend (children, window);
7831 for (l = children; l != NULL; l = l->next)
7832 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
7834 g_list_free (children);
7841 pick_embedded_child (GdkWindow *window,
7848 g_signal_emit (window,
7849 signals[PICK_EMBEDDED_CHILD], 0,
7856 _gdk_window_find_child_at (GdkWindow *window,
7861 double child_x, child_y;
7864 if (point_in_window (window, x, y))
7866 /* Children is ordered in reverse stack order, i.e. first is topmost */
7867 for (l = window->children; l != NULL; l = l->next)
7871 if (!GDK_WINDOW_IS_MAPPED (sub))
7874 gdk_window_coords_from_parent ((GdkWindow *)sub,
7876 &child_x, &child_y);
7877 if (point_in_window (sub, child_x, child_y))
7878 return (GdkWindow *)sub;
7881 if (window->num_offscreen_children > 0)
7883 sub = pick_embedded_child (window,
7886 return (GdkWindow *)sub;
7894 _gdk_window_find_descendant_at (GdkWindow *window,
7901 gdouble child_x, child_y;
7905 if (point_in_window (window, x, y))
7910 /* Children is ordered in reverse stack order, i.e. first is topmost */
7911 for (l = window->children; l != NULL; l = l->next)
7915 if (!GDK_WINDOW_IS_MAPPED (sub))
7918 gdk_window_coords_from_parent ((GdkWindow *)sub,
7920 &child_x, &child_y);
7921 if (point_in_window (sub, child_x, child_y))
7931 window->num_offscreen_children > 0)
7933 sub = pick_embedded_child (window,
7939 from_embedder (sub, x, y, &x, &y);
7947 /* Not in window at all */
7961 * @window: a toplevel #GdkWindow
7963 * Emits a short beep associated to @window in the appropriate
7964 * display, if supported. Otherwise, emits a short beep on
7965 * the display just as gdk_display_beep().
7970 gdk_window_beep (GdkWindow *window)
7972 GdkDisplay *display;
7973 GdkWindow *toplevel;
7975 g_return_if_fail (GDK_IS_WINDOW (window));
7977 if (GDK_WINDOW_DESTROYED (window))
7980 toplevel = get_event_toplevel (window);
7981 display = gdk_window_get_display (window);
7985 if (GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl)->beep (toplevel))
7989 /* If windows fail to beep, we beep the display. */
7990 gdk_display_beep (display);
7994 * gdk_window_set_support_multidevice:
7995 * @window: a #GdkWindow.
7996 * @support_multidevice: %TRUE to enable multidevice support in @window.
7998 * This function will enable multidevice features in @window.
8000 * Multidevice aware windows will need to handle properly multiple,
8001 * per device enter/leave events, device grabs and grab ownerships.
8006 gdk_window_set_support_multidevice (GdkWindow *window,
8007 gboolean support_multidevice)
8009 g_return_if_fail (GDK_IS_WINDOW (window));
8011 if (GDK_WINDOW_DESTROYED (window))
8014 if (window->support_multidevice == support_multidevice)
8017 window->support_multidevice = support_multidevice;
8019 /* FIXME: What to do if called when some pointers are inside the window ? */
8023 * gdk_window_get_support_multidevice:
8024 * @window: a #GdkWindow.
8026 * Returns %TRUE if the window is aware of the existence of multiple
8029 * Returns: %TRUE if the window handles multidevice features.
8034 gdk_window_get_support_multidevice (GdkWindow *window)
8036 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8038 if (GDK_WINDOW_DESTROYED (window))
8041 return window->support_multidevice;
8044 static const guint type_masks[] = {
8045 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8046 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8047 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8048 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8049 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8050 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8051 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8052 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8053 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8054 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8055 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8056 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8057 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8058 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8059 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8060 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8061 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8062 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8063 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8064 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8065 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8066 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8067 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8068 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8069 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8070 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8071 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8072 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8073 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8074 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8075 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8076 GDK_SCROLL_MASK | GDK_BUTTON_PRESS_MASK,/* GDK_SCROLL= 31 */
8077 0, /* GDK_WINDOW_STATE = 32 */
8078 0, /* GDK_SETTING = 33 */
8079 0, /* GDK_OWNER_CHANGE = 34 */
8080 0, /* GDK_GRAB_BROKEN = 35 */
8081 0, /* GDK_DAMAGE = 36 */
8083 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8085 /* send motion events if the right buttons are down */
8087 update_evmask_for_button_motion (guint evmask,
8088 GdkModifierType mask)
8090 if (evmask & GDK_BUTTON_MOTION_MASK &&
8091 mask & (GDK_BUTTON1_MASK |
8096 evmask |= GDK_POINTER_MOTION_MASK;
8098 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8099 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8100 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8101 evmask |= GDK_POINTER_MOTION_MASK;
8107 is_button_type (GdkEventType type)
8109 return type == GDK_BUTTON_PRESS ||
8110 type == GDK_2BUTTON_PRESS ||
8111 type == GDK_3BUTTON_PRESS ||
8112 type == GDK_BUTTON_RELEASE ||
8117 is_motion_type (GdkEventType type)
8119 return type == GDK_MOTION_NOTIFY ||
8120 type == GDK_ENTER_NOTIFY ||
8121 type == GDK_LEAVE_NOTIFY;
8125 find_common_ancestor (GdkWindow *win1,
8129 GList *path1 = NULL, *path2 = NULL;
8130 GList *list1, *list2;
8133 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8135 path1 = g_list_prepend (path1, tmp);
8136 tmp = get_event_parent (tmp);
8140 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8142 path2 = g_list_prepend (path2, tmp);
8143 tmp = get_event_parent (tmp);
8149 while (list1 && list2 && (list1->data == list2->data))
8152 list1 = g_list_next (list1);
8153 list2 = g_list_next (list2);
8155 g_list_free (path1);
8156 g_list_free (path2);
8162 _gdk_make_event (GdkWindow *window,
8164 GdkEvent *event_in_queue,
8165 gboolean before_event)
8167 GdkEvent *event = gdk_event_new (type);
8169 GdkModifierType the_state;
8171 the_time = gdk_event_get_time (event_in_queue);
8172 gdk_event_get_state (event_in_queue, &the_state);
8174 event->any.window = g_object_ref (window);
8175 event->any.send_event = FALSE;
8176 if (event_in_queue && event_in_queue->any.send_event)
8177 event->any.send_event = TRUE;
8181 case GDK_MOTION_NOTIFY:
8182 event->motion.time = the_time;
8183 event->motion.axes = NULL;
8184 event->motion.state = the_state;
8187 case GDK_BUTTON_PRESS:
8188 case GDK_2BUTTON_PRESS:
8189 case GDK_3BUTTON_PRESS:
8190 case GDK_BUTTON_RELEASE:
8191 event->button.time = the_time;
8192 event->button.axes = NULL;
8193 event->button.state = the_state;
8197 event->scroll.time = the_time;
8198 event->scroll.state = the_state;
8202 case GDK_KEY_RELEASE:
8203 event->key.time = the_time;
8204 event->key.state = the_state;
8207 case GDK_ENTER_NOTIFY:
8208 case GDK_LEAVE_NOTIFY:
8209 event->crossing.time = the_time;
8210 event->crossing.state = the_state;
8213 case GDK_PROPERTY_NOTIFY:
8214 event->property.time = the_time;
8215 event->property.state = the_state;
8218 case GDK_SELECTION_CLEAR:
8219 case GDK_SELECTION_REQUEST:
8220 case GDK_SELECTION_NOTIFY:
8221 event->selection.time = the_time;
8224 case GDK_PROXIMITY_IN:
8225 case GDK_PROXIMITY_OUT:
8226 event->proximity.time = the_time;
8229 case GDK_DRAG_ENTER:
8230 case GDK_DRAG_LEAVE:
8231 case GDK_DRAG_MOTION:
8232 case GDK_DRAG_STATUS:
8233 case GDK_DROP_START:
8234 case GDK_DROP_FINISHED:
8235 event->dnd.time = the_time;
8238 case GDK_FOCUS_CHANGE:
8242 case GDK_CLIENT_EVENT:
8243 case GDK_VISIBILITY_NOTIFY:
8254 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8256 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8259 _gdk_event_queue_append (gdk_window_get_display (window), event);
8265 send_crossing_event (GdkDisplay *display,
8266 GdkWindow *toplevel,
8269 GdkCrossingMode mode,
8270 GdkNotifyType notify_type,
8271 GdkWindow *subwindow,
8273 GdkDevice *source_device,
8276 GdkModifierType mask,
8278 GdkEvent *event_in_queue,
8282 guint32 window_event_mask, type_event_mask;
8283 GdkDeviceGrabInfo *grab;
8284 gboolean block_event = FALSE;
8286 grab = _gdk_display_has_device_grab (display, device, serial);
8289 !grab->owner_events)
8291 /* !owner_event => only report events wrt grab window, ignore rest */
8292 if ((GdkWindow *)window != grab->window)
8294 window_event_mask = grab->event_mask;
8297 window_event_mask = window->event_mask;
8299 if (type == GDK_LEAVE_NOTIFY)
8301 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8302 window->devices_inside = g_list_remove (window->devices_inside, device);
8304 if (!window->support_multidevice && window->devices_inside)
8306 /* Block leave events unless it's the last pointer */
8312 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8314 if (!window->support_multidevice && window->devices_inside)
8316 /* Only emit enter events for the first device */
8320 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8321 gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
8322 !g_list_find (window->devices_inside, device))
8323 window->devices_inside = g_list_prepend (window->devices_inside, device);
8329 if (window_event_mask & type_event_mask)
8331 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8332 gdk_event_set_device (event, device);
8335 gdk_event_set_source_device (event, source_device);
8337 event->crossing.time = time_;
8338 event->crossing.subwindow = subwindow;
8340 g_object_ref (subwindow);
8341 convert_toplevel_coords_to_window ((GdkWindow *)window,
8342 toplevel_x, toplevel_y,
8343 &event->crossing.x, &event->crossing.y);
8344 event->crossing.x_root = toplevel_x + toplevel->x;
8345 event->crossing.y_root = toplevel_y + toplevel->y;
8346 event->crossing.mode = mode;
8347 event->crossing.detail = notify_type;
8348 event->crossing.focus = FALSE;
8349 event->crossing.state = mask;
8354 /* The coordinates are in the toplevel window that src/dest are in.
8355 * src and dest are always (if != NULL) in the same toplevel, as
8356 * we get a leave-notify and set the window_under_pointer to null
8357 * before crossing to another toplevel.
8360 _gdk_synthesize_crossing_events (GdkDisplay *display,
8364 GdkDevice *source_device,
8365 GdkCrossingMode mode,
8368 GdkModifierType mask,
8370 GdkEvent *event_in_queue,
8372 gboolean non_linear)
8375 GdkWindow *win, *last, *next;
8379 GdkWindow *toplevel;
8380 GdkNotifyType notify_type;
8382 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8387 return; /* No crossings generated between src and dest */
8389 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8391 if (a && gdk_window_get_device_events (src, device) == 0)
8394 if (b && gdk_window_get_device_events (dest, device) == 0)
8401 c = find_common_ancestor (a, b);
8403 non_linear |= (c != a) && (c != b);
8405 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8407 toplevel = gdk_window_get_toplevel (a);
8409 /* Traverse up from a to (excluding) c sending leave events */
8411 notify_type = GDK_NOTIFY_NONLINEAR;
8413 notify_type = GDK_NOTIFY_INFERIOR;
8415 notify_type = GDK_NOTIFY_ANCESTOR;
8416 send_crossing_event (display, toplevel,
8417 a, GDK_LEAVE_NOTIFY,
8420 NULL, device, source_device,
8421 toplevel_x, toplevel_y,
8429 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8431 notify_type = GDK_NOTIFY_VIRTUAL;
8434 win = get_event_parent (a);
8435 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8437 send_crossing_event (display, toplevel,
8438 win, GDK_LEAVE_NOTIFY,
8442 device, source_device,
8443 toplevel_x, toplevel_y,
8449 win = get_event_parent (win);
8454 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8456 toplevel = gdk_window_get_toplevel ((GdkWindow *)b);
8458 /* Traverse down from c to b */
8462 win = get_event_parent (b);
8463 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8465 path = g_list_prepend (path, win);
8466 win = get_event_parent (win);
8470 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8472 notify_type = GDK_NOTIFY_VIRTUAL;
8478 list = g_list_next (list);
8484 send_crossing_event (display, toplevel,
8485 win, GDK_ENTER_NOTIFY,
8489 device, source_device,
8490 toplevel_x, toplevel_y,
8500 notify_type = GDK_NOTIFY_NONLINEAR;
8502 notify_type = GDK_NOTIFY_ANCESTOR;
8504 notify_type = GDK_NOTIFY_INFERIOR;
8506 send_crossing_event (display, toplevel,
8507 b, GDK_ENTER_NOTIFY,
8511 device, source_device,
8512 toplevel_x, toplevel_y,
8519 /* Returns the window inside the event window with the pointer in it
8520 * at the specified coordinates, or NULL if its not in any child of
8521 * the toplevel. It also takes into account !owner_events grabs.
8524 get_pointer_window (GdkDisplay *display,
8525 GdkWindow *event_window,
8531 GdkWindow *pointer_window;
8532 GdkDeviceGrabInfo *grab;
8533 GdkPointerWindowInfo *pointer_info;
8535 pointer_info = _gdk_display_get_pointer_info (display, device);
8537 if (event_window == pointer_info->toplevel_under_pointer)
8539 _gdk_window_find_descendant_at (event_window,
8540 toplevel_x, toplevel_y,
8543 pointer_window = NULL;
8545 grab = _gdk_display_has_device_grab (display, device, serial);
8547 !grab->owner_events &&
8548 pointer_window != grab->window)
8549 pointer_window = NULL;
8551 return pointer_window;
8555 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8559 GdkPointerWindowInfo *device_info;
8561 device_info = _gdk_display_get_pointer_info (display, device);
8563 if (device_info->window_under_pointer)
8564 g_object_unref (device_info->window_under_pointer);
8565 device_info->window_under_pointer = window;
8569 g_object_ref (window);
8570 update_cursor (display, device);
8573 _gdk_display_enable_motion_hints (display, device);
8578 * @window: the #GdkWindow which will own the grab (the grab window).
8579 * @owner_events: if %FALSE then all pointer events are reported with respect to
8580 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8581 * events for this application are reported as normal, but pointer events outside
8582 * this application are reported with respect to @window and only if selected by
8583 * @event_mask. In either mode, unreported events are discarded.
8584 * @event_mask: specifies the event mask, which is used in accordance with
8585 * @owner_events. Note that only pointer events (i.e. button and motion events)
8587 * @confine_to: (allow-none): If non-%NULL, the pointer will be confined to this
8588 * window during the grab. If the pointer is outside @confine_to, it will
8589 * automatically be moved to the closest edge of @confine_to and enter
8590 * and leave events will be generated as necessary.
8591 * @cursor: (allow-none): the cursor to display while the grab is active. If this is %NULL then
8592 * the normal cursors are used for @window and its descendants, and the cursor
8593 * for @window is used for all other windows.
8594 * @time_: the timestamp of the event which led to this pointer grab. This usually
8595 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8596 * the time isn't known.
8598 * Grabs the pointer (usually a mouse) so that all events are passed to this
8599 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8600 * the grab window becomes unviewable.
8601 * This overrides any previous pointer grab by this client.
8603 * Pointer grabs are used for operations which need complete control over mouse
8604 * events, even if the mouse leaves the application.
8605 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8606 * the #GtkHPaned and #GtkVPaned widgets.
8608 * Note that if the event mask of an X window has selected both button press and
8609 * button release events, then a button press event will cause an automatic
8610 * pointer grab until the button is released.
8611 * X does this automatically since most applications expect to receive button
8612 * press and release events in pairs.
8613 * It is equivalent to a pointer grab on the window with @owner_events set to
8616 * If you set up anything at the time you take the grab that needs to be cleaned
8617 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8618 * are emitted when the grab ends unvoluntarily.
8620 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8622 * Deprecated: 3.0: Use gdk_device_grab() instead.
8625 gdk_pointer_grab (GdkWindow * window,
8626 gboolean owner_events,
8627 GdkEventMask event_mask,
8628 GdkWindow * confine_to,
8633 GdkDisplay *display;
8634 GdkDeviceManager *device_manager;
8636 GdkGrabStatus res = 0;
8638 GList *devices, *dev;
8640 g_return_val_if_fail (window != NULL, 0);
8641 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8642 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8644 /* We need a native window for confine to to work, ensure we have one */
8647 if (!gdk_window_ensure_native (confine_to))
8649 g_warning ("Can't confine to grabbed window, not native");
8654 /* Non-viewable client side window => fail */
8655 if (!_gdk_window_has_impl (window) &&
8656 !gdk_window_is_viewable (window))
8657 return GDK_GRAB_NOT_VIEWABLE;
8659 native = gdk_window_get_toplevel (window);
8660 while (gdk_window_is_offscreen (native))
8662 native = gdk_offscreen_window_get_embedder (native);
8664 if (native == NULL ||
8665 (!_gdk_window_has_impl (native) &&
8666 !gdk_window_is_viewable (native)))
8667 return GDK_GRAB_NOT_VIEWABLE;
8669 native = gdk_window_get_toplevel (native);
8672 display = gdk_window_get_display (window);
8674 serial = _gdk_display_get_next_serial (display);
8675 device_manager = gdk_display_get_device_manager (display);
8676 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8678 /* FIXME: Should this be generic to all backends? */
8679 /* FIXME: What happens with extended devices? */
8680 for (dev = devices; dev; dev = dev->next)
8684 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
8687 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
8690 get_native_grab_event_mask (event_mask),
8695 if (res == GDK_GRAB_SUCCESS)
8696 _gdk_display_add_device_grab (display,
8708 /* FIXME: handle errors when grabbing */
8710 g_list_free (devices);
8716 * gdk_keyboard_grab:
8717 * @window: the #GdkWindow which will own the grab (the grab window).
8718 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8719 * @window. If %TRUE then keyboard events for this application are
8720 * reported as normal, but keyboard events outside this application
8721 * are reported with respect to @window. Both key press and key
8722 * release events are always reported, independant of the event mask
8723 * set by the application.
8724 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8727 * Grabs the keyboard so that all events are passed to this
8728 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8729 * This overrides any previous keyboard grab by this client.
8731 * If you set up anything at the time you take the grab that needs to be cleaned
8732 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8733 * are emitted when the grab ends unvoluntarily.
8735 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8737 * Deprecated: 3.0: Use gdk_device_grab() instead.
8740 gdk_keyboard_grab (GdkWindow *window,
8741 gboolean owner_events,
8745 GdkDisplay *display;
8746 GdkDeviceManager *device_manager;
8748 GdkGrabStatus res = 0;
8750 GList *devices, *dev;
8752 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8754 /* Non-viewable client side window => fail */
8755 if (!_gdk_window_has_impl (window) &&
8756 !gdk_window_is_viewable (window))
8757 return GDK_GRAB_NOT_VIEWABLE;
8759 native = gdk_window_get_toplevel (window);
8761 while (gdk_window_is_offscreen (native))
8763 native = gdk_offscreen_window_get_embedder (native);
8765 if (native == NULL ||
8766 (!_gdk_window_has_impl (native) &&
8767 !gdk_window_is_viewable (native)))
8768 return GDK_GRAB_NOT_VIEWABLE;
8770 native = gdk_window_get_toplevel (native);
8773 display = gdk_window_get_display (window);
8774 serial = _gdk_display_get_next_serial (display);
8775 device_manager = gdk_display_get_device_manager (display);
8776 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8778 /* FIXME: Should this be generic to all backends? */
8779 /* FIXME: What happens with extended devices? */
8780 for (dev = devices; dev; dev = dev->next)
8784 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
8787 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
8790 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
8795 if (res == GDK_GRAB_SUCCESS)
8796 _gdk_display_add_device_grab (display,
8807 /* FIXME: handle errors when grabbing */
8809 g_list_free (devices);
8815 * gdk_window_geometry_changed:
8816 * @window: an embedded offscreen #GdkWindow
8818 * This function informs GDK that the geometry of an embedded
8819 * offscreen window has changed. This is necessary for GDK to keep
8820 * track of which offscreen window the pointer is in.
8825 gdk_window_geometry_changed (GdkWindow *window)
8827 _gdk_synthesize_crossing_events_for_geometry_change (window);
8831 source_events_device_added (GdkDeviceManager *device_manager,
8836 GdkEventMask event_mask;
8837 GdkInputSource source;
8839 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_FLOATING)
8843 source = gdk_device_get_source (device);
8845 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
8846 GINT_TO_POINTER (source)));
8848 gdk_window_set_device_events (window, device, event_mask);
8852 source_events_device_changed (GdkDeviceManager *device_manager,
8857 GdkInputSource source;
8858 GdkEventMask event_mask;
8862 type = gdk_device_get_device_type (device);
8863 source = gdk_device_get_source (device);
8865 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
8866 GINT_TO_POINTER (source)));
8871 if (type == GDK_DEVICE_TYPE_FLOATING)
8873 /* The device was just floated, enable its event mask */
8874 gdk_window_set_device_events (window, device, event_mask);
8876 else if (type == GDK_DEVICE_TYPE_SLAVE)
8877 gdk_window_set_device_events (window, device, 0);
8881 * gdk_window_set_source_events:
8882 * @window: a #GdkWindow
8883 * @source: a #GdkInputSource to define the source class.
8884 * @event_mask: event mask for @window
8886 * Sets the event mask for any floating device (i.e. not attached to any
8887 * visible pointer) that has the source defined as @source. This event
8888 * mask will be applied both to currently existing, newly added devices
8889 * after this call, and devices being attached/detached.
8894 gdk_window_set_source_events (GdkWindow *window,
8895 GdkInputSource source,
8896 GdkEventMask event_mask)
8898 GdkDeviceManager *device_manager;
8899 GdkDisplay *display;
8903 g_return_if_fail (GDK_IS_WINDOW (window));
8905 display = gdk_window_get_display (window);
8906 device_manager = gdk_display_get_device_manager (display);
8908 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
8910 /* Set event mask for existing devices */
8911 for (d = devices; d; d = d->next)
8913 GdkDevice *device = d->data;
8915 if (source == gdk_device_get_source (device))
8916 gdk_window_set_device_events (window, device, event_mask);
8919 g_list_free (devices);
8921 /* Update accounting */
8922 if (G_UNLIKELY (!window->source_event_masks))
8923 window->source_event_masks = g_hash_table_new (NULL, NULL);
8926 g_hash_table_insert (window->source_event_masks,
8927 GUINT_TO_POINTER (source),
8928 GUINT_TO_POINTER (event_mask));
8930 g_hash_table_remove (window->source_event_masks,
8931 GUINT_TO_POINTER (source));
8933 size = g_hash_table_size (window->source_event_masks);
8935 /* Update handler if needed */
8936 if (!window->device_added_handler_id && size > 0)
8938 window->device_added_handler_id =
8939 g_signal_connect (device_manager, "device-added",
8940 G_CALLBACK (source_events_device_added), window);
8941 window->device_changed_handler_id =
8942 g_signal_connect (device_manager, "device-changed",
8943 G_CALLBACK (source_events_device_changed), window);
8945 else if (window->device_added_handler_id && size == 0)
8946 g_signal_handler_disconnect (device_manager, window->device_added_handler_id);
8950 * gdk_window_get_source_events:
8951 * @window: a #GdkWindow
8952 * @source: a #GdkInputSource to define the source class.
8954 * Returns the event mask for @window corresponding to the device class specified
8957 * Returns: source event mask for @window
8960 gdk_window_get_source_events (GdkWindow *window,
8961 GdkInputSource source)
8963 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8965 return GPOINTER_TO_UINT (g_hash_table_lookup (window->source_event_masks,
8966 GUINT_TO_POINTER (source)));
8970 do_synthesize_crossing_event (gpointer data)
8972 GdkDisplay *display;
8973 GdkWindow *changed_toplevel;
8974 GHashTableIter iter;
8975 gpointer key, value;
8978 changed_toplevel = data;
8980 changed_toplevel->synthesize_crossing_event_queued = FALSE;
8982 if (GDK_WINDOW_DESTROYED (changed_toplevel))
8985 display = gdk_window_get_display (changed_toplevel);
8986 serial = _gdk_display_get_next_serial (display);
8987 g_hash_table_iter_init (&iter, display->pointers_info);
8989 while (g_hash_table_iter_next (&iter, &key, &value))
8991 GdkWindow *new_window_under_pointer;
8992 GdkPointerWindowInfo *pointer_info = value;
8993 GdkDevice *device = key;
8995 if (changed_toplevel == pointer_info->toplevel_under_pointer)
8997 new_window_under_pointer =
8998 get_pointer_window (display, changed_toplevel,
9000 pointer_info->toplevel_x,
9001 pointer_info->toplevel_y,
9003 if (new_window_under_pointer != pointer_info->window_under_pointer)
9005 _gdk_synthesize_crossing_events (display,
9006 pointer_info->window_under_pointer,
9007 new_window_under_pointer,
9009 GDK_CROSSING_NORMAL,
9010 pointer_info->toplevel_x,
9011 pointer_info->toplevel_y,
9012 pointer_info->state,
9017 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9026 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9028 GdkWindow *toplevel;
9030 toplevel = get_event_toplevel (changed_window);
9032 if (!toplevel->synthesize_crossing_event_queued)
9034 toplevel->synthesize_crossing_event_queued = TRUE;
9036 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9037 do_synthesize_crossing_event,
9038 g_object_ref (toplevel),
9043 /* Don't use for crossing events */
9045 get_event_window (GdkDisplay *display,
9047 GdkWindow *pointer_window,
9049 GdkModifierType mask,
9054 GdkWindow *grab_window;
9055 GdkDeviceGrabInfo *grab;
9057 grab = _gdk_display_has_device_grab (display, device, serial);
9059 if (grab != NULL && !grab->owner_events)
9061 evmask = grab->event_mask;
9062 evmask = update_evmask_for_button_motion (evmask, mask);
9064 grab_window = grab->window;
9066 if (evmask & type_masks[type])
9069 *evmask_out = evmask;
9076 while (pointer_window != NULL)
9078 evmask = pointer_window->event_mask;
9079 evmask = update_evmask_for_button_motion (evmask, mask);
9081 if (evmask & type_masks[type])
9084 *evmask_out = evmask;
9085 return pointer_window;
9088 pointer_window = get_event_parent (pointer_window);
9094 evmask = grab->event_mask;
9095 evmask = update_evmask_for_button_motion (evmask, mask);
9097 if (evmask & type_masks[type])
9100 *evmask_out = evmask;
9101 return grab->window;
9111 proxy_pointer_event (GdkDisplay *display,
9112 GdkEvent *source_event,
9115 GdkWindow *toplevel_window, *event_window;
9116 GdkWindow *pointer_window;
9117 GdkPointerWindowInfo *pointer_info;
9118 GdkDevice *device, *source_device;
9121 gdouble toplevel_x, toplevel_y;
9123 gboolean non_linear;
9125 event_window = source_event->any.window;
9126 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9127 gdk_event_get_state (source_event, &state);
9128 time_ = gdk_event_get_time (source_event);
9129 device = gdk_event_get_device (source_event);
9130 source_device = gdk_event_get_source_device (source_event);
9131 pointer_info = _gdk_display_get_pointer_info (display, device);
9132 toplevel_window = convert_native_coords_to_toplevel (event_window,
9133 toplevel_x, toplevel_y,
9134 &toplevel_x, &toplevel_y);
9137 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9138 source_event->type == GDK_ENTER_NOTIFY) &&
9139 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9140 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9143 /* If we get crossing events with subwindow unexpectedly being NULL
9144 that means there is a native subwindow that gdk doesn't know about.
9145 We track these and forward them, with the correct virtual window
9147 This is important to get right, as metacity uses gdk for the frame
9148 windows, but gdk doesn't know about the client windows reparented
9150 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9151 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9152 (source_event->type == GDK_ENTER_NOTIFY &&
9153 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9154 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9155 source_event->crossing.subwindow == NULL)
9157 /* Left for an unknown (to gdk) subwindow */
9159 /* Send leave events from window under pointer to event window
9160 that will get the subwindow == NULL window */
9161 _gdk_synthesize_crossing_events (display,
9162 pointer_info->window_under_pointer,
9164 device, source_device,
9165 source_event->crossing.mode,
9166 toplevel_x, toplevel_y,
9172 /* Send subwindow == NULL event */
9173 send_crossing_event (display,
9177 source_event->crossing.mode,
9178 source_event->crossing.detail,
9180 device, source_device,
9181 toplevel_x, toplevel_y,
9186 _gdk_display_set_window_under_pointer (display, device, NULL);
9190 pointer_window = get_pointer_window (display, toplevel_window, device,
9191 toplevel_x, toplevel_y, serial);
9193 if (((source_event->type == GDK_ENTER_NOTIFY &&
9194 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9195 (source_event->type == GDK_LEAVE_NOTIFY &&
9196 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9197 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9198 source_event->crossing.subwindow == NULL)
9200 /* Entered from an unknown (to gdk) subwindow */
9202 /* Send subwindow == NULL event */
9203 send_crossing_event (display,
9207 source_event->crossing.mode,
9208 source_event->crossing.detail,
9210 device, source_device,
9211 toplevel_x, toplevel_y,
9216 /* Send enter events from event window to pointer_window */
9217 _gdk_synthesize_crossing_events (display,
9220 device, source_device,
9221 source_event->crossing.mode,
9222 toplevel_x, toplevel_y,
9225 serial, non_linear);
9226 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9230 if (pointer_info->window_under_pointer != pointer_window)
9232 /* Either a toplevel crossing notify that ended up inside a child window,
9233 or a motion notify that got into another child window */
9235 /* Different than last time, send crossing events */
9236 _gdk_synthesize_crossing_events (display,
9237 pointer_info->window_under_pointer,
9239 device, source_device,
9240 GDK_CROSSING_NORMAL,
9241 toplevel_x, toplevel_y,
9244 serial, non_linear);
9245 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9247 else if (source_event->type == GDK_MOTION_NOTIFY)
9249 GdkWindow *event_win;
9253 event_win = get_event_window (display,
9262 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9263 gdk_window_get_device_events (event_win, device) == 0)
9269 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9271 gulong *device_serial;
9273 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9275 if (!device_serial ||
9276 (*device_serial != 0 &&
9277 serial < *device_serial))
9278 event_win = NULL; /* Ignore event */
9282 *device_serial = G_MAXULONG;
9286 if (event_win && !display->ignore_core_events)
9288 event = _gdk_make_event (event_win, GDK_MOTION_NOTIFY, source_event, FALSE);
9289 event->motion.time = time_;
9290 convert_toplevel_coords_to_window (event_win,
9291 toplevel_x, toplevel_y,
9292 &event->motion.x, &event->motion.y);
9293 event->motion.x_root = source_event->motion.x_root;
9294 event->motion.y_root = source_event->motion.y_root;
9295 event->motion.state = state;
9296 event->motion.is_hint = is_hint;
9297 event->motion.device = source_event->motion.device;
9298 event->motion.axes = g_memdup (source_event->motion.axes,
9299 sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
9300 gdk_event_set_source_device (event, source_device);
9304 /* unlink all move events from queue.
9305 We handle our own, including our emulated masks. */
9309 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9310 GDK_BUTTON2_MASK | \
9311 GDK_BUTTON3_MASK | \
9312 GDK_BUTTON4_MASK | \
9316 proxy_button_event (GdkEvent *source_event,
9319 GdkWindow *toplevel_window, *event_window;
9320 GdkWindow *event_win;
9321 GdkWindow *pointer_window;
9327 gdouble toplevel_x, toplevel_y;
9328 GdkDisplay *display;
9330 GdkDevice *device, *source_device;
9332 type = source_event->any.type;
9333 event_window = source_event->any.window;
9334 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9335 gdk_event_get_state (source_event, &state);
9336 time_ = gdk_event_get_time (source_event);
9337 device = gdk_event_get_device (source_event);
9338 source_device = gdk_event_get_source_device (source_event);
9339 display = gdk_window_get_display (source_event->any.window);
9340 toplevel_window = convert_native_coords_to_toplevel (event_window,
9341 toplevel_x, toplevel_y,
9342 &toplevel_x, &toplevel_y);
9344 if (type == GDK_BUTTON_PRESS &&
9345 !source_event->any.send_event &&
9346 _gdk_display_has_device_grab (display, device, serial) == NULL)
9349 _gdk_window_find_descendant_at (toplevel_window,
9350 toplevel_x, toplevel_y,
9353 /* Find the event window, that gets the grab */
9356 (parent = get_event_parent (w)) != NULL &&
9357 parent->window_type != GDK_WINDOW_ROOT)
9359 if (w->event_mask & GDK_BUTTON_PRESS_MASK)
9363 pointer_window = (GdkWindow *)w;
9365 _gdk_display_add_device_grab (display,
9371 gdk_window_get_events (pointer_window),
9375 _gdk_display_device_grab_update (display, device, source_device, serial);
9378 pointer_window = get_pointer_window (display, toplevel_window, device,
9379 toplevel_x, toplevel_y,
9382 event_win = get_event_window (display,
9388 if (event_win == NULL || display->ignore_core_events)
9391 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9392 gdk_window_get_device_events (event_win, device) == 0)
9395 event = _gdk_make_event (event_win, type, source_event, FALSE);
9399 case GDK_BUTTON_PRESS:
9400 case GDK_BUTTON_RELEASE:
9401 event->button.button = source_event->button.button;
9402 convert_toplevel_coords_to_window (event_win,
9403 toplevel_x, toplevel_y,
9404 &event->button.x, &event->button.y);
9405 event->button.x_root = source_event->button.x_root;
9406 event->button.y_root = source_event->button.y_root;
9407 event->button.state = state;
9408 event->button.device = source_event->button.device;
9409 event->button.axes = g_memdup (source_event->button.axes,
9410 sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
9412 gdk_event_set_source_device (event, source_device);
9414 if (type == GDK_BUTTON_PRESS)
9415 _gdk_event_button_generate (display, event);
9419 event->scroll.direction = source_event->scroll.direction;
9420 convert_toplevel_coords_to_window (event_win,
9421 toplevel_x, toplevel_y,
9422 &event->scroll.x, &event->scroll.y);
9423 event->scroll.x_root = source_event->scroll.x_root;
9424 event->scroll.y_root = source_event->scroll.y_root;
9425 event->scroll.state = state;
9426 event->scroll.device = source_event->scroll.device;
9427 gdk_event_set_source_device (event, source_device);
9434 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9437 #ifdef DEBUG_WINDOW_PRINTING
9439 gdk_window_print (GdkWindow *window,
9443 const char *window_types[] = {
9453 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9454 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9455 window->x, window->y,
9456 window->width, window->height
9459 if (gdk_window_has_impl (window))
9461 #ifdef GDK_WINDOWING_X11
9462 g_print (" impl(0x%lx)", gdk_x11_window_get_xid (window));
9466 if (window->window_type != GDK_WINDOW_CHILD)
9467 g_print (" %s", window_types[window->window_type]);
9469 if (window->input_only)
9470 g_print (" input-only");
9473 g_print (" shaped");
9475 if (!gdk_window_is_visible ((GdkWindow *)window))
9476 g_print (" hidden");
9478 g_print (" abs[%d,%d]",
9479 window->abs_x, window->abs_y);
9481 cairo_region_get_extents (window->clip_region, &r);
9482 if (cairo_region_is_empty (window->clip_region))
9483 g_print (" clipbox[empty]");
9485 g_print (" clipbox[%d,%d %dx%d]", r.x, r.y, r.width, r.height);
9492 gdk_window_print_tree (GdkWindow *window,
9494 gboolean include_input_only)
9498 if (window->input_only && !include_input_only)
9501 gdk_window_print (window, indent);
9503 for (l = window->children; l != NULL; l = l->next)
9504 gdk_window_print_tree (l->data, indent + 4, include_input_only);
9507 #endif /* DEBUG_WINDOW_PRINTING */
9510 _gdk_windowing_got_event (GdkDisplay *display,
9515 GdkWindow *event_window;
9517 gboolean unlink_event;
9518 guint old_state, old_button;
9519 GdkDeviceGrabInfo *button_release_grab;
9520 GdkPointerWindowInfo *pointer_info;
9521 GdkDevice *device, *source_device;
9522 gboolean is_toplevel;
9524 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
9525 display->last_event_time = gdk_event_get_time (event);
9527 device = gdk_event_get_device (event);
9528 source_device = gdk_event_get_source_device (event);
9534 g_object_get (device, "input-mode", &mode, NULL);
9535 _gdk_display_device_grab_update (display, device, source_device, serial);
9537 if (mode == GDK_MODE_DISABLED ||
9538 !_gdk_display_check_grab_ownership (display, device, serial))
9540 /* Device events are blocked by another
9541 * device grab, or the device is disabled
9543 unlink_event = TRUE;
9548 event_window = event->any.window;
9552 pointer_info = _gdk_display_get_pointer_info (display, device);
9554 #ifdef DEBUG_WINDOW_PRINTING
9555 if (event->type == GDK_KEY_PRESS &&
9556 (event->key.keyval == 0xa7 ||
9557 event->key.keyval == 0xbd))
9559 gdk_window_print_tree (event_window, 0,
9560 event->key.keyval == 0xbd);
9564 if (event->type == GDK_VISIBILITY_NOTIFY)
9566 event_window->native_visibility = event->visibility.state;
9567 gdk_window_update_visibility_recursively (event_window,
9572 if (!(is_button_type (event->type) ||
9573 is_motion_type (event->type)) ||
9574 event_window->window_type == GDK_WINDOW_ROOT)
9577 is_toplevel = gdk_window_is_toplevel (event_window);
9579 if ((event->type == GDK_ENTER_NOTIFY ||
9580 event->type == GDK_LEAVE_NOTIFY) &&
9581 (event->crossing.mode == GDK_CROSSING_GRAB ||
9582 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
9583 (_gdk_display_has_device_grab (display, device, serial) ||
9584 event->crossing.detail == GDK_NOTIFY_INFERIOR))
9586 /* We synthesize all crossing events due to grabs ourselves,
9587 * so we ignore the native ones caused by our native pointer_grab
9588 * calls. Otherwise we would proxy these crossing event and cause
9589 * multiple copies of crossing events for grabs.
9591 * We do want to handle grabs from other clients though, as for
9592 * instance alt-tab in metacity causes grabs like these and
9593 * we want to handle those. Thus the has_pointer_grab check.
9595 * Implicit grabs on child windows create some grabbing events
9596 * that are sent before the button press. This means we can't
9597 * detect these with the has_pointer_grab check (as the implicit
9598 * grab is only noticed when we get button press event), so we
9599 * detect these events by checking for INFERIOR enter or leave
9600 * events. These should never be a problem to filter out.
9603 /* We ended up in this window after some (perhaps other clients)
9604 grab, so update the toplevel_under_window state */
9606 event->type == GDK_ENTER_NOTIFY &&
9607 event->crossing.mode == GDK_CROSSING_UNGRAB)
9609 if (pointer_info->toplevel_under_pointer)
9610 g_object_unref (pointer_info->toplevel_under_pointer);
9611 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9614 unlink_event = TRUE;
9618 /* Track toplevel_under_pointer */
9621 if (event->type == GDK_ENTER_NOTIFY &&
9622 event->crossing.detail != GDK_NOTIFY_INFERIOR)
9624 if (pointer_info->toplevel_under_pointer)
9625 g_object_unref (pointer_info->toplevel_under_pointer);
9626 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
9628 else if (event->type == GDK_LEAVE_NOTIFY &&
9629 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
9630 pointer_info->toplevel_under_pointer == event_window)
9632 if (pointer_info->toplevel_under_pointer)
9633 g_object_unref (pointer_info->toplevel_under_pointer);
9634 pointer_info->toplevel_under_pointer = NULL;
9638 /* Store last pointer window and position/state */
9639 old_state = pointer_info->state;
9640 old_button = pointer_info->button;
9642 gdk_event_get_coords (event, &x, &y);
9643 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
9644 pointer_info->toplevel_x = x;
9645 pointer_info->toplevel_y = y;
9646 gdk_event_get_state (event, &pointer_info->state);
9647 if (event->type == GDK_BUTTON_PRESS ||
9648 event->type == GDK_BUTTON_RELEASE)
9649 pointer_info->button = event->button.button;
9652 (pointer_info->state != old_state ||
9653 pointer_info->button != old_button))
9654 _gdk_display_enable_motion_hints (display, device);
9656 unlink_event = FALSE;
9657 if (is_motion_type (event->type))
9658 unlink_event = proxy_pointer_event (display,
9661 else if (is_button_type (event->type))
9662 unlink_event = proxy_button_event (event,
9665 if (event->type == GDK_BUTTON_RELEASE &&
9666 !event->any.send_event)
9668 button_release_grab =
9669 _gdk_display_has_device_grab (display, device, serial);
9670 if (button_release_grab &&
9671 button_release_grab->implicit &&
9672 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
9674 button_release_grab->serial_end = serial;
9675 button_release_grab->implicit_ungrab = FALSE;
9676 _gdk_display_device_grab_update (display, device, source_device, serial);
9683 _gdk_event_queue_remove_link (display, event_link);
9684 g_list_free_1 (event_link);
9685 gdk_event_free (event);
9690 * gdk_window_create_similar_surface:
9691 * @window: window to make new surface similar to
9692 * @content: the content for the new surface
9693 * @width: width of the new surface
9694 * @height: height of the new surface
9696 * Create a new surface that is as compatible as possible with the
9697 * given @window. For example the new surface will have the same
9698 * fallback resolution and font options as @window. Generally, the new
9699 * surface will also use the same backend as @window, unless that is
9700 * not possible for some reason. The type of the returned surface may
9701 * be examined with cairo_surface_get_type().
9703 * Initially the surface contents are all 0 (transparent if contents
9704 * have transparency, black otherwise.)
9706 * Returns: a pointer to the newly allocated surface. The caller
9707 * owns the surface and should call cairo_surface_destroy() when done
9710 * This function always returns a valid pointer, but it will return a
9711 * pointer to a "nil" surface if @other is already in an error state
9712 * or any other error occurs.
9717 gdk_window_create_similar_surface (GdkWindow * window,
9718 cairo_content_t content,
9722 cairo_surface_t *window_surface, *surface;
9724 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
9726 window_surface = _gdk_window_ref_cairo_surface (window);
9728 switch (_gdk_rendering_mode)
9730 case GDK_RENDERING_MODE_RECORDING:
9732 cairo_rectangle_t rect = { 0, 0, width, height };
9733 surface = cairo_recording_surface_create (content, &rect);
9736 case GDK_RENDERING_MODE_IMAGE:
9737 surface = cairo_image_surface_create (content == CAIRO_CONTENT_COLOR ? CAIRO_FORMAT_RGB24 :
9738 content == CAIRO_CONTENT_ALPHA ? CAIRO_FORMAT_A8 : CAIRO_FORMAT_ARGB32,
9741 case GDK_RENDERING_MODE_SIMILAR:
9743 surface = cairo_surface_create_similar (window_surface,
9749 cairo_surface_destroy (window_surface);
9756 * @window: a #GdkWindow
9757 * @timestamp: timestamp of the event triggering the window focus
9759 * Sets keyboard focus to @window. In most cases, gtk_window_present()
9760 * should be used on a #GtkWindow, rather than calling this function.
9764 gdk_window_focus (GdkWindow *window,
9767 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->focus (window, timestamp);
9771 * gdk_window_set_type_hint:
9772 * @window: A toplevel #GdkWindow
9773 * @hint: A hint of the function this window will have
9775 * The application can use this call to provide a hint to the window
9776 * manager about the functionality of a window. The window manager
9777 * can use this information when determining the decoration and behaviour
9780 * The hint must be set before the window is mapped.
9783 gdk_window_set_type_hint (GdkWindow *window,
9784 GdkWindowTypeHint hint)
9786 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_type_hint (window, hint);
9790 * gdk_window_get_type_hint:
9791 * @window: A toplevel #GdkWindow
9793 * This function returns the type hint set for a window.
9795 * Return value: The type hint set for @window
9800 gdk_window_get_type_hint (GdkWindow *window)
9802 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_type_hint (window);
9806 * gdk_window_set_modal_hint:
9807 * @window: A toplevel #GdkWindow
9808 * @modal: %TRUE if the window is modal, %FALSE otherwise.
9810 * The application can use this hint to tell the window manager
9811 * that a certain window has modal behaviour. The window manager
9812 * can use this information to handle modal windows in a special
9815 * You should only use this on windows for which you have
9816 * previously called gdk_window_set_transient_for()
9819 gdk_window_set_modal_hint (GdkWindow *window,
9822 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_modal_hint (window, modal);
9826 * gdk_window_set_skip_taskbar_hint:
9827 * @window: a toplevel #GdkWindow
9828 * @skips_taskbar: %TRUE to skip the taskbar
9830 * Toggles whether a window should appear in a task list or window
9831 * list. If a window's semantic type as specified with
9832 * gdk_window_set_type_hint() already fully describes the window, this
9833 * function should <emphasis>not</emphasis> be called in addition,
9834 * instead you should allow the window to be treated according to
9835 * standard policy for its semantic type.
9840 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
9841 gboolean skips_taskbar)
9843 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_taskbar_hint (window, skips_taskbar);
9847 * gdk_window_set_skip_pager_hint:
9848 * @window: a toplevel #GdkWindow
9849 * @skips_pager: %TRUE to skip the pager
9851 * Toggles whether a window should appear in a pager (workspace
9852 * switcher, or other desktop utility program that displays a small
9853 * thumbnail representation of the windows on the desktop). If a
9854 * window's semantic type as specified with gdk_window_set_type_hint()
9855 * already fully describes the window, this function should
9856 * <emphasis>not</emphasis> be called in addition, instead you should
9857 * allow the window to be treated according to standard policy for
9858 * its semantic type.
9863 gdk_window_set_skip_pager_hint (GdkWindow *window,
9864 gboolean skips_pager)
9866 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_pager_hint (window, skips_pager);
9870 * gdk_window_set_urgency_hint:
9871 * @window: a toplevel #GdkWindow
9872 * @urgent: %TRUE if the window is urgent
9874 * Toggles whether a window needs the user's
9880 gdk_window_set_urgency_hint (GdkWindow *window,
9883 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_urgency_hint (window, urgent);
9887 * gdk_window_set_geometry_hints:
9888 * @window: a toplevel #GdkWindow
9889 * @geometry: geometry hints
9890 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
9892 * Sets the geometry hints for @window. Hints flagged in @geom_mask
9893 * are set, hints not flagged in @geom_mask are unset.
9894 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
9896 * This function provides hints to the windowing system about
9897 * acceptable sizes for a toplevel window. The purpose of
9898 * this is to constrain user resizing, but the windowing system
9899 * will typically (but is not required to) also constrain the
9900 * current size of the window to the provided values and
9901 * constrain programatic resizing via gdk_window_resize() or
9902 * gdk_window_move_resize().
9904 * Note that on X11, this effect has no effect on windows
9905 * of type %GDK_WINDOW_TEMP or windows where override redirect
9906 * has been turned on via gdk_window_set_override_redirect()
9907 * since these windows are not resizable by the user.
9909 * Since you can't count on the windowing system doing the
9910 * constraints for programmatic resizes, you should generally
9911 * call gdk_window_constrain_size() yourself to determine
9912 * appropriate sizes.
9916 gdk_window_set_geometry_hints (GdkWindow *window,
9917 const GdkGeometry *geometry,
9918 GdkWindowHints geom_mask)
9920 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_geometry_hints (window, geometry, geom_mask);
9924 * gdk_window_set_title:
9925 * @window: a toplevel #GdkWindow
9926 * @title: title of @window
9928 * Sets the title of a toplevel window, to be displayed in the titlebar.
9929 * If you haven't explicitly set the icon name for the window
9930 * (using gdk_window_set_icon_name()), the icon name will be set to
9931 * @title as well. @title must be in UTF-8 encoding (as with all
9932 * user-readable strings in GDK/GTK+). @title may not be %NULL.
9935 gdk_window_set_title (GdkWindow *window,
9938 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_title (window, title);
9942 * gdk_window_set_role:
9943 * @window: a toplevel #GdkWindow
9944 * @role: a string indicating its role
9946 * When using GTK+, typically you should use gtk_window_set_role() instead
9947 * of this low-level function.
9949 * The window manager and session manager use a window's role to
9950 * distinguish it from other kinds of window in the same application.
9951 * When an application is restarted after being saved in a previous
9952 * session, all windows with the same title and role are treated as
9953 * interchangeable. So if you have two windows with the same title
9954 * that should be distinguished for session management purposes, you
9955 * should set the role on those windows. It doesn't matter what string
9956 * you use for the role, as long as you have a different role for each
9957 * non-interchangeable kind of window.
9961 gdk_window_set_role (GdkWindow *window,
9964 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_role (window, role);
9968 * gdk_window_set_startup_id:
9969 * @window: a toplevel #GdkWindow
9970 * @startup_id: a string with startup-notification identifier
9972 * When using GTK+, typically you should use gtk_window_set_startup_id()
9973 * instead of this low-level function.
9979 gdk_window_set_startup_id (GdkWindow *window,
9980 const gchar *startup_id)
9982 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_startup_id (window, startup_id);
9986 * gdk_window_set_transient_for:
9987 * @window: a toplevel #GdkWindow
9988 * @parent: another toplevel #GdkWindow
9990 * Indicates to the window manager that @window is a transient dialog
9991 * associated with the application window @parent. This allows the
9992 * window manager to do things like center @window on @parent and
9993 * keep @window above @parent.
9995 * See gtk_window_set_transient_for() if you're using #GtkWindow or
9999 gdk_window_set_transient_for (GdkWindow *window,
10002 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_transient_for (window, parent);
10006 * gdk_window_get_root_origin:
10007 * @window: a toplevel #GdkWindow
10008 * @x: (out): return location for X position of window frame
10009 * @y: (out): return location for Y position of window frame
10011 * Obtains the top-left corner of the window manager frame in root
10012 * window coordinates.
10016 gdk_window_get_root_origin (GdkWindow *window,
10020 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_root_origin (window, x, y);
10024 * gdk_window_get_frame_extents:
10025 * @window: a toplevel #GdkWindow
10026 * @rect: rectangle to fill with bounding box of the window frame
10028 * Obtains the bounding box of the window, including window manager
10029 * titlebar/borders if any. The frame position is given in root window
10030 * coordinates. To get the position of the window itself (rather than
10031 * the frame) in root window coordinates, use gdk_window_get_origin().
10035 gdk_window_get_frame_extents (GdkWindow *window,
10036 GdkRectangle *rect)
10038 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_frame_extents (window, rect);
10042 * gdk_window_set_override_redirect:
10043 * @window: a toplevel #GdkWindow
10044 * @override_redirect: %TRUE if window should be override redirect
10046 * An override redirect window is not under the control of the window manager.
10047 * This means it won't have a titlebar, won't be minimizable, etc. - it will
10048 * be entirely under the control of the application. The window manager
10049 * can't see the override redirect window at all.
10051 * Override redirect should only be used for short-lived temporary
10052 * windows, such as popup menus. #GtkMenu uses an override redirect
10053 * window in its implementation, for example.
10057 gdk_window_set_override_redirect (GdkWindow *window,
10058 gboolean override_redirect)
10060 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_override_redirect (window, override_redirect);
10064 * gdk_window_set_accept_focus:
10065 * @window: a toplevel #GdkWindow
10066 * @accept_focus: %TRUE if the window should receive input focus
10068 * Setting @accept_focus to %FALSE hints the desktop environment that the
10069 * window doesn't want to receive input focus.
10071 * On X, it is the responsibility of the window manager to interpret this
10072 * hint. ICCCM-compliant window manager usually respect it.
10077 gdk_window_set_accept_focus (GdkWindow *window,
10078 gboolean accept_focus)
10080 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_accept_focus (window, accept_focus);
10084 * gdk_window_set_focus_on_map:
10085 * @window: a toplevel #GdkWindow
10086 * @focus_on_map: %TRUE if the window should receive input focus when mapped
10088 * Setting @focus_on_map to %FALSE hints the desktop environment that the
10089 * window doesn't want to receive input focus when it is mapped.
10090 * focus_on_map should be turned off for windows that aren't triggered
10091 * interactively (such as popups from network activity).
10093 * On X, it is the responsibility of the window manager to interpret
10094 * this hint. Window managers following the freedesktop.org window
10095 * manager extension specification should respect it.
10100 gdk_window_set_focus_on_map (GdkWindow *window,
10101 gboolean focus_on_map)
10103 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_focus_on_map (window, focus_on_map);
10107 * gdk_window_set_icon_list:
10108 * @window: The #GdkWindow toplevel window to set the icon of.
10109 * @pixbufs: (transfer none) (element-type GdkPixbuf):
10110 * A list of pixbufs, of different sizes.
10112 * Sets a list of icons for the window. One of these will be used
10113 * to represent the window when it has been iconified. The icon is
10114 * usually shown in an icon box or some sort of task bar. Which icon
10115 * size is shown depends on the window manager. The window manager
10116 * can scale the icon but setting several size icons can give better
10117 * image quality since the window manager may only need to scale the
10118 * icon by a small amount or not at all.
10122 gdk_window_set_icon_list (GdkWindow *window,
10125 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_list (window, pixbufs);
10129 * gdk_window_set_icon_name:
10130 * @window: a toplevel #GdkWindow
10131 * @name: (allow-none): name of window while iconified (minimized)
10133 * Windows may have a name used while minimized, distinct from the
10134 * name they display in their titlebar. Most of the time this is a bad
10135 * idea from a user interface standpoint. But you can set such a name
10136 * with this function, if you like.
10138 * After calling this with a non-%NULL @name, calls to gdk_window_set_title()
10139 * will not update the icon title.
10141 * Using %NULL for @name unsets the icon title; further calls to
10142 * gdk_window_set_title() will again update the icon title as well.
10145 gdk_window_set_icon_name (GdkWindow *window,
10148 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_name (window, name);
10152 * gdk_window_iconify:
10153 * @window: a toplevel #GdkWindow
10155 * Asks to iconify (minimize) @window. The window manager may choose
10156 * to ignore the request, but normally will honor it. Using
10157 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
10159 * This function only makes sense when @window is a toplevel window.
10163 gdk_window_iconify (GdkWindow *window)
10165 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->iconify (window);
10169 * gdk_window_deiconify:
10170 * @window: a toplevel #GdkWindow
10172 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
10173 * choose to ignore the request to deiconify. When using GTK+,
10174 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
10175 * you probably want to use gtk_window_present(), which raises the window, focuses it,
10176 * unminimizes it, and puts it on the current desktop.
10180 gdk_window_deiconify (GdkWindow *window)
10182 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->deiconify (window);
10186 * gdk_window_stick:
10187 * @window: a toplevel #GdkWindow
10189 * "Pins" a window such that it's on all workspaces and does not scroll
10190 * with viewports, for window managers that have scrollable viewports.
10191 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
10193 * On the X11 platform, this function depends on window manager
10194 * support, so may have no effect with many window managers. However,
10195 * GDK will do the best it can to convince the window manager to stick
10196 * the window. For window managers that don't support this operation,
10197 * there's nothing you can do to force it to happen.
10201 gdk_window_stick (GdkWindow *window)
10203 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->stick (window);
10207 * gdk_window_unstick:
10208 * @window: a toplevel #GdkWindow
10210 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
10211 * and gtk_window_unstick().
10215 gdk_window_unstick (GdkWindow *window)
10217 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unstick (window);
10221 * gdk_window_maximize:
10222 * @window: a toplevel #GdkWindow
10224 * Maximizes the window. If the window was already maximized, then
10225 * this function does nothing.
10227 * On X11, asks the window manager to maximize @window, if the window
10228 * manager supports this operation. Not all window managers support
10229 * this, and some deliberately ignore it or don't have a concept of
10230 * "maximized"; so you can't rely on the maximization actually
10231 * happening. But it will happen with most standard window managers,
10232 * and GDK makes a best effort to get it to happen.
10234 * On Windows, reliably maximizes the window.
10238 gdk_window_maximize (GdkWindow *window)
10240 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->maximize (window);
10244 * gdk_window_unmaximize:
10245 * @window: a toplevel #GdkWindow
10247 * Unmaximizes the window. If the window wasn't maximized, then this
10248 * function does nothing.
10250 * On X11, asks the window manager to unmaximize @window, if the
10251 * window manager supports this operation. Not all window managers
10252 * support this, and some deliberately ignore it or don't have a
10253 * concept of "maximized"; so you can't rely on the unmaximization
10254 * actually happening. But it will happen with most standard window
10255 * managers, and GDK makes a best effort to get it to happen.
10257 * On Windows, reliably unmaximizes the window.
10261 gdk_window_unmaximize (GdkWindow *window)
10263 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unmaximize (window);
10267 * gdk_window_fullscreen:
10268 * @window: a toplevel #GdkWindow
10270 * Moves the window into fullscreen mode. This means the
10271 * window covers the entire screen and is above any panels
10274 * If the window was already fullscreen, then this function does nothing.
10276 * On X11, asks the window manager to put @window in a fullscreen
10277 * state, if the window manager supports this operation. Not all
10278 * window managers support this, and some deliberately ignore it or
10279 * don't have a concept of "fullscreen"; so you can't rely on the
10280 * fullscreenification actually happening. But it will happen with
10281 * most standard window managers, and GDK makes a best effort to get
10287 gdk_window_fullscreen (GdkWindow *window)
10289 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->fullscreen (window);
10293 * gdk_window_unfullscreen:
10294 * @window: a toplevel #GdkWindow
10296 * Moves the window out of fullscreen mode. If the window was not
10297 * fullscreen, does nothing.
10299 * On X11, asks the window manager to move @window out of the fullscreen
10300 * state, if the window manager supports this operation. Not all
10301 * window managers support this, and some deliberately ignore it or
10302 * don't have a concept of "fullscreen"; so you can't rely on the
10303 * unfullscreenification actually happening. But it will happen with
10304 * most standard window managers, and GDK makes a best effort to get
10310 gdk_window_unfullscreen (GdkWindow *window)
10312 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unfullscreen (window);
10316 * gdk_window_set_keep_above:
10317 * @window: a toplevel #GdkWindow
10318 * @setting: whether to keep @window above other windows
10320 * Set if @window must be kept above other windows. If the
10321 * window was already above, then this function does nothing.
10323 * On X11, asks the window manager to keep @window above, if the window
10324 * manager supports this operation. Not all window managers support
10325 * this, and some deliberately ignore it or don't have a concept of
10326 * "keep above"; so you can't rely on the window being kept above.
10327 * But it will happen with most standard window managers,
10328 * and GDK makes a best effort to get it to happen.
10333 gdk_window_set_keep_above (GdkWindow *window,
10336 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_above (window, setting);
10340 * gdk_window_set_keep_below:
10341 * @window: a toplevel #GdkWindow
10342 * @setting: whether to keep @window below other windows
10344 * Set if @window must be kept below other windows. If the
10345 * window was already below, then this function does nothing.
10347 * On X11, asks the window manager to keep @window below, if the window
10348 * manager supports this operation. Not all window managers support
10349 * this, and some deliberately ignore it or don't have a concept of
10350 * "keep below"; so you can't rely on the window being kept below.
10351 * But it will happen with most standard window managers,
10352 * and GDK makes a best effort to get it to happen.
10357 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
10359 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_below (window, setting);
10363 * gdk_window_get_group:
10364 * @window: a toplevel #GdkWindow
10366 * Returns the group leader window for @window. See gdk_window_set_group().
10368 * Return value: (transfer none): the group leader window for @window
10373 gdk_window_get_group (GdkWindow *window)
10375 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_group (window);
10379 * gdk_window_set_group:
10380 * @window: a toplevel #GdkWindow
10381 * @leader: (allow-none): group leader window, or %NULL to restore the default group leader window
10383 * Sets the group leader window for @window. By default,
10384 * GDK sets the group leader for all toplevel windows
10385 * to a global window implicitly created by GDK. With this function
10386 * you can override this default.
10388 * The group leader window allows the window manager to distinguish
10389 * all windows that belong to a single application. It may for example
10390 * allow users to minimize/unminimize all windows belonging to an
10391 * application at once. You should only set a non-default group window
10392 * if your application pretends to be multiple applications.
10395 gdk_window_set_group (GdkWindow *window,
10398 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_group (window, leader);
10402 * gdk_window_set_decorations:
10403 * @window: a toplevel #GdkWindow
10404 * @decorations: decoration hint mask
10406 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
10407 * This function sets the traditional Motif window manager hints that tell the
10408 * window manager which decorations you would like your window to have.
10409 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
10410 * using the GDK function directly.
10412 * The @decorations argument is the logical OR of the fields in
10413 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
10414 * mask, the other bits indicate which decorations should be turned off.
10415 * If #GDK_DECOR_ALL is not included, then the other bits indicate
10416 * which decorations should be turned on.
10418 * Most window managers honor a decorations hint of 0 to disable all decorations,
10419 * but very few honor all possible combinations of bits.
10423 gdk_window_set_decorations (GdkWindow *window,
10424 GdkWMDecoration decorations)
10426 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_decorations (window, decorations);
10430 * gdk_window_get_decorations:
10431 * @window: The toplevel #GdkWindow to get the decorations from
10432 * @decorations: (out): The window decorations will be written here
10434 * Returns the decorations set on the GdkWindow with
10435 * gdk_window_set_decorations().
10437 * Returns: %TRUE if the window has decorations set, %FALSE otherwise.
10440 gdk_window_get_decorations(GdkWindow *window,
10441 GdkWMDecoration *decorations)
10443 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_decorations (window, decorations);
10447 * gdk_window_set_functions:
10448 * @window: a toplevel #GdkWindow
10449 * @functions: bitmask of operations to allow on @window
10451 * Sets hints about the window management functions to make available
10452 * via buttons on the window frame.
10454 * On the X backend, this function sets the traditional Motif window
10455 * manager hint for this purpose. However, few window managers do
10456 * anything reliable or interesting with this hint. Many ignore it
10459 * The @functions argument is the logical OR of values from the
10460 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
10461 * then the other bits indicate which functions to disable; if
10462 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
10467 gdk_window_set_functions (GdkWindow *window,
10468 GdkWMFunction functions)
10470 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_functions (window, functions);
10474 * gdk_window_begin_resize_drag_for_device:
10475 * @window: a toplevel #GdkWindow
10476 * @edge: the edge or corner from which the drag is started
10477 * @device: the device used for the operation
10478 * @button: the button being used to drag
10479 * @root_x: root window X coordinate of mouse click that began the drag
10480 * @root_y: root window Y coordinate of mouse click that began the drag
10481 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
10483 * Begins a window resize operation (for a toplevel window).
10484 * You might use this function to implement a "window resize grip," for
10485 * example; in fact #GtkStatusbar uses it. The function works best
10486 * with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a
10487 * fallback implementation for other window managers.
10492 gdk_window_begin_resize_drag_for_device (GdkWindow *window,
10493 GdkWindowEdge edge,
10500 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_resize_drag (window, edge, device, button, root_x, root_y, timestamp);
10504 * gdk_window_begin_resize_drag:
10505 * @window: a toplevel #GdkWindow
10506 * @edge: the edge or corner from which the drag is started
10507 * @button: the button being used to drag
10508 * @root_x: root window X coordinate of mouse click that began the drag
10509 * @root_y: root window Y coordinate of mouse click that began the drag
10510 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
10512 * Begins a window resize operation (for a toplevel window).
10514 * This function assumes that the drag is controlled by the
10515 * client pointer device, use gdk_window_begin_resize_drag_for_device()
10516 * to begin a drag with a different device.
10519 gdk_window_begin_resize_drag (GdkWindow *window,
10520 GdkWindowEdge edge,
10526 GdkDeviceManager *device_manager;
10529 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
10530 device = gdk_device_manager_get_client_pointer (device_manager);
10531 gdk_window_begin_resize_drag_for_device (window, edge,
10532 device, button, root_x, root_y, timestamp);
10536 * gdk_window_begin_move_drag_for_device:
10537 * @window: a toplevel #GdkWindow
10538 * @device: the device used for the operation
10539 * @button: the button being used to drag
10540 * @root_x: root window X coordinate of mouse click that began the drag
10541 * @root_y: root window Y coordinate of mouse click that began the drag
10542 * @timestamp: timestamp of mouse click that began the drag
10544 * Begins a window move operation (for a toplevel window).
10545 * You might use this function to implement a "window move grip," for
10546 * example. The function works best with window managers that support
10547 * the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
10548 * Window Manager Hints</ulink>, but has a fallback implementation for
10549 * other window managers.
10554 gdk_window_begin_move_drag_for_device (GdkWindow *window,
10561 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_move_drag (window,
10562 device, button, root_x, root_y, timestamp);
10566 * gdk_window_begin_move_drag:
10567 * @window: a toplevel #GdkWindow
10568 * @button: the button being used to drag
10569 * @root_x: root window X coordinate of mouse click that began the drag
10570 * @root_y: root window Y coordinate of mouse click that began the drag
10571 * @timestamp: timestamp of mouse click that began the drag
10573 * Begins a window move operation (for a toplevel window).
10575 * This function assumes that the drag is controlled by the
10576 * client pointer device, use gdk_window_begin_move_drag_for_device()
10577 * to begin a drag with a different device.
10580 gdk_window_begin_move_drag (GdkWindow *window,
10586 GdkDeviceManager *device_manager;
10589 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
10590 device = gdk_device_manager_get_client_pointer (device_manager);
10591 gdk_window_begin_move_drag_for_device (window, device, button, root_x, root_y, timestamp);
10595 * gdk_window_enable_synchronized_configure:
10596 * @window: a toplevel #GdkWindow
10598 * Indicates that the application will cooperate with the window
10599 * system in synchronizing the window repaint with the window
10600 * manager during resizing operations. After an application calls
10601 * this function, it must call gdk_window_configure_finished() every
10602 * time it has finished all processing associated with a set of
10603 * Configure events. Toplevel GTK+ windows automatically use this
10606 * On X, calling this function makes @window participate in the
10607 * _NET_WM_SYNC_REQUEST window manager protocol.
10612 gdk_window_enable_synchronized_configure (GdkWindow *window)
10614 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->enable_synchronized_configure (window);
10618 * gdk_window_configure_finished:
10619 * @window: a toplevel #GdkWindow
10621 * Signal to the window system that the application has finished
10622 * handling Configure events it has received. Window Managers can
10623 * use this to better synchronize the frame repaint with the
10624 * application. GTK+ applications will automatically call this
10625 * function when appropriate.
10627 * This function can only be called if gdk_window_enable_synchronized_configure()
10628 * was called previously.
10633 gdk_window_configure_finished (GdkWindow *window)
10635 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->configure_finished (window);
10639 * gdk_window_set_opacity:
10640 * @window: a top-level #GdkWindow
10641 * @opacity: opacity
10643 * Request the windowing system to make @window partially transparent,
10644 * with opacity 0 being fully transparent and 1 fully opaque. (Values
10645 * of the opacity parameter are clamped to the [0,1] range.)
10647 * On X11, this works only on X screens with a compositing manager
10650 * For setting up per-pixel alpha, see gdk_screen_get_rgba_visual().
10651 * For making non-toplevel windows translucent, see
10652 * gdk_window_set_composited().
10657 gdk_window_set_opacity (GdkWindow *window,
10660 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_opacity (window, opacity);
10663 /* This function is called when the XWindow is really gone.
10666 gdk_window_destroy_notify (GdkWindow *window)
10668 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->destroy_notify (window);
10672 * gdk_window_register_dnd:
10673 * @window: a #GdkWindow.
10675 * Registers a window as a potential drop destination.
10678 gdk_window_register_dnd (GdkWindow *window)
10680 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->register_dnd (window);
10684 * gdk_window_get_drag_protocol:
10685 * @window: the destination window
10686 * @target: (out) (allow-none) (transfer full): location of the window
10687 * where the drop should happen. This may be @window or a proxy window,
10688 * or %NULL if @window does not support Drag and Drop.
10690 * Finds out the DND protocol supported by a window.
10692 * Returns: the supported DND protocol.
10697 gdk_window_get_drag_protocol (GdkWindow *window,
10698 GdkWindow **target)
10700 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_DRAG_PROTO_NONE);
10702 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_drag_protocol (window, target);
10707 * @window: the source window for this drag.
10708 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
10709 * as list of #GdkAtoms
10711 * Starts a drag and creates a new drag context for it.
10712 * This function assumes that the drag is controlled by the
10713 * client pointer device, use gdk_drag_begin_for_device() to
10714 * begin a drag with a different device.
10716 * This function is called by the drag source.
10718 * Return value: (transfer full): a newly created #GdkDragContext
10721 gdk_drag_begin (GdkWindow *window,
10724 GdkDeviceManager *device_manager;
10727 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
10728 device = gdk_device_manager_get_client_pointer (device_manager);
10730 return gdk_drag_begin_for_device (window, device, targets);
10734 * gdk_drag_begin_for_device:
10735 * @window: the source window for this drag
10736 * @device: the device that controls this drag
10737 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
10738 * as list of #GdkAtoms
10740 * Starts a drag and creates a new drag context for it.
10742 * This function is called by the drag source.
10744 * Return value: (transfer full): a newly created #GdkDragContext
10747 gdk_drag_begin_for_device (GdkWindow *window,
10751 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, targets);
10755 * gdk_test_render_sync:
10756 * @window: a mapped #GdkWindow
10758 * Retrieves a pixel from @window to force the windowing
10759 * system to carry out any pending rendering commands.
10761 * This function is intended to be used to synchronize with rendering
10762 * pipelines, to benchmark windowing system rendering operations.
10767 gdk_test_render_sync (GdkWindow *window)
10769 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->sync_rendering (window);
10773 * gdk_test_simulate_key:
10774 * @window: a #GdkWindow to simulate a key event for
10775 * @x: x coordinate within @window for the key event
10776 * @y: y coordinate within @window for the key event
10777 * @keyval: A GDK keyboard value
10778 * @modifiers: Keyboard modifiers the event is setup with
10779 * @key_pressrelease: either %GDK_KEY_PRESS or %GDK_KEY_RELEASE
10781 * This function is intended to be used in GTK+ test programs.
10782 * If (@x,@y) are > (-1,-1), it will warp the mouse pointer to
10783 * the given (@x,@y) coordinates within @window and simulate a
10784 * key press or release event.
10786 * When the mouse pointer is warped to the target location, use
10787 * of this function outside of test programs that run in their
10788 * own virtual windowing system (e.g. Xvfb) is not recommended.
10789 * If (@x,@y) are passed as (-1,-1), the mouse pointer will not
10790 * be warped and @window origin will be used as mouse pointer
10791 * location for the event.
10793 * Also, gdk_test_simulate_key() is a fairly low level function,
10794 * for most testing purposes, gtk_test_widget_send_key() is the
10795 * right function to call which will generate a key press event
10796 * followed by its accompanying key release event.
10798 * Returns: whether all actions necessary for a key event simulation
10799 * were carried out successfully
10804 gdk_test_simulate_key (GdkWindow *window,
10808 GdkModifierType modifiers,
10809 GdkEventType key_pressrelease)
10811 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10812 ->simulate_key (window, x, y, keyval, modifiers, key_pressrelease);
10816 * gdk_test_simulate_button:
10817 * @window: a #GdkWindow to simulate a button event for
10818 * @x: x coordinate within @window for the button event
10819 * @y: y coordinate within @window for the button event
10820 * @button: Number of the pointer button for the event, usually 1, 2 or 3
10821 * @modifiers: Keyboard modifiers the event is setup with
10822 * @button_pressrelease: either %GDK_BUTTON_PRESS or %GDK_BUTTON_RELEASE
10824 * This function is intended to be used in GTK+ test programs.
10825 * It will warp the mouse pointer to the given (@x,@y) coordinates
10826 * within @window and simulate a button press or release event.
10827 * Because the mouse pointer needs to be warped to the target
10828 * location, use of this function outside of test programs that
10829 * run in their own virtual windowing system (e.g. Xvfb) is not
10832 * Also, gdk_test_simulate_button() is a fairly low level function,
10833 * for most testing purposes, gtk_test_widget_click() is the right
10834 * function to call which will generate a button press event followed
10835 * by its accompanying button release event.
10837 * Returns: whether all actions necessary for a button event simulation
10838 * were carried out successfully
10843 gdk_test_simulate_button (GdkWindow *window,
10846 guint button, /*1..3*/
10847 GdkModifierType modifiers,
10848 GdkEventType button_pressrelease)
10850 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10851 ->simulate_button (window, x, y, button, modifiers, button_pressrelease);
10855 * gdk_property_get:
10856 * @window: a #GdkWindow
10857 * @property: the property to retrieve
10858 * @type: the desired property type, or %GDK_NONE, if any type of data
10859 * is acceptable. If this does not match the actual
10860 * type, then @actual_format and @actual_length will
10861 * be filled in, a warning will be printed to stderr
10862 * and no data will be returned.
10863 * @offset: the offset into the property at which to begin
10864 * retrieving data, in 4 byte units.
10865 * @length: the length of the data to retrieve in bytes. Data is
10866 * considered to be retrieved in 4 byte chunks, so @length
10867 * will be rounded up to the next highest 4 byte boundary
10868 * (so be careful not to pass a value that might overflow
10869 * when rounded up).
10870 * @pdelete: if %TRUE, delete the property after retrieving the
10872 * @actual_property_type: (out) (transfer none): location to store the
10873 * actual type of the property.
10874 * @actual_format: (out): location to store the actual return format of the
10875 * data; either 8, 16 or 32 bits.
10876 * @actual_length: location to store the length of the retrieved data, in
10877 * bytes. Data returned in the 32 bit format is stored
10878 * in a long variable, so the actual number of 32 bit
10879 * elements should be be calculated via
10880 * @actual_length / sizeof(glong) to ensure portability to
10882 * @data: (out) (array length=actual_length) (transfer full): location
10883 * to store a pointer to the data. The retrieved data should be
10884 * freed with g_free() when you are finished using it.
10886 * Retrieves a portion of the contents of a property. If the
10887 * property does not exist, then the function returns %FALSE,
10888 * and %GDK_NONE will be stored in @actual_property_type.
10892 * The XGetWindowProperty() function that gdk_property_get()
10893 * uses has a very confusing and complicated set of semantics.
10894 * Unfortunately, gdk_property_get() makes the situation
10895 * worse instead of better (the semantics should be considered
10896 * undefined), and also prints warnings to stderr in cases where it
10897 * should return a useful error to the program. You are advised to use
10898 * XGetWindowProperty() directly until a replacement function for
10899 * gdk_property_get()
10904 * Returns: %TRUE if data was successfully received and stored
10905 * in @data, otherwise %FALSE.
10908 gdk_property_get (GdkWindow *window,
10914 GdkAtom *actual_property_type,
10915 gint *actual_format_type,
10916 gint *actual_length,
10919 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10920 ->get_property (window, property, type, offset, length, pdelete,
10921 actual_property_type, actual_format_type,
10922 actual_length, data);
10926 * gdk_property_change: (skip)
10927 * @window: a #GdkWindow
10928 * @property: the property to change
10929 * @type: the new type for the property. If @mode is
10930 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
10931 * must match the existing type or an error will occur.
10932 * @format: the new format for the property. If @mode is
10933 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
10934 * must match the existing format or an error will occur.
10935 * @mode: a value describing how the new data is to be combined
10936 * with the current data.
10937 * @data: the data (a <literal>guchar *</literal>
10938 * <literal>gushort *</literal>, or <literal>gulong *</literal>,
10939 * depending on @format), cast to a <literal>guchar *</literal>.
10940 * @nelements: the number of elements of size determined by the format,
10941 * contained in @data.
10943 * Changes the contents of a property on a window.
10946 gdk_property_change (GdkWindow *window,
10951 const guchar *data,
10954 GDK_WINDOW_IMPL_GET_CLASS (window->impl)
10955 ->change_property (window, property, type, format, mode, data, nelements);
10959 * gdk_property_delete:
10960 * @window: a #GdkWindow
10961 * @property: the property to delete
10963 * Deletes a property from a window.
10966 gdk_property_delete (GdkWindow *window,
10969 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->delete_property (window, property);