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, see <http://www.gnu.org/licenses/>.
20 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
21 * file for a list of people on the GTK+ Team. See the ChangeLog
22 * files for a list of changes. These files are distributed with
23 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
28 #include <cairo-gobject.h>
30 #include "gdkwindow.h"
32 #include "gdkrectangle.h"
33 #include "gdkinternals.h"
35 #include "gdkscreenprivate.h"
36 #include "gdkdisplayprivate.h"
37 #include "gdkdeviceprivate.h"
38 #include "gdkvisualprivate.h"
39 #include "gdkmarshalers.h"
40 #include "gdkframeclockidle.h"
41 #include "gdkwindowimpl.h"
45 #undef DEBUG_WINDOW_PRINTING
50 * @Short_description: Onscreen display areas in the target window system
53 * A #GdkWindow is a (usually) rectangular region on the screen.
54 * It's a low-level object, used to implement high-level objects such as
55 * #GtkWidget and #GtkWindow on the GTK+ level. A #GtkWindow is a toplevel
56 * window, the thing a user might think of as a "window" with a titlebar and
57 * so on; a #GtkWindow may contain many #GdkWindows. For example, each
58 * #GtkButton has a #GdkWindow associated with it.
60 * <refsect2 id="COMPOSITED-WINDOWS">
61 * <title>Composited Windows</title>
63 * Normally, the windowing system takes care of rendering the contents of a
64 * child window onto its parent window. This mechanism can be intercepted by
65 * calling gdk_window_set_composited() on the child window. For a
66 * <firstterm>composited</firstterm> window it is the responsibility of the
67 * application to render the window contents at the right spot.
70 * <refsect2 id="OFFSCREEN-WINDOWS">
71 * <title>Offscreen Windows</title>
73 * Offscreen windows are more general than composited windows, since they allow
74 * not only to modify the rendering of the child window onto its parent, but
75 * also to apply coordinate transformations.
77 * To integrate an offscreen window into a window hierarchy, one has to call
78 * gdk_offscreen_window_set_embedder() and handle a number of signals. The
79 * #GdkWindow::pick-embedded-child signal on the embedder window is used to
80 * select an offscreen child at given coordinates, and the
81 * #GdkWindow::to-embedder and #GdkWindow::from-embedder signals on the
82 * offscreen window are used to translate coordinates between the embedder and
83 * the offscreen window.
85 * For rendering an offscreen window onto its embedder, the contents of the
86 * offscreen window are available as a surface, via
87 * gdk_offscreen_window_get_surface().
93 /* Historically a GdkWindow always matches a platform native window,
94 * be it a toplevel window or a child window. In this setup the
95 * GdkWindow (and other GdkDrawables) were platform independent classes,
96 * and the actual platform specific implementation was in a delegate
97 * object available as "impl" in the window object.
99 * With the addition of client side windows and offscreen windows this
100 * changes a bit. The application-visible GdkWindow object behaves as
101 * it did before, but not all such windows now have a corresponding native
102 * window. Instead windows that are "client side" are emulated by the gdk
103 * code such that clipping, drawing, moving, events etc work as expected.
105 * For GdkWindows that have a native window the "impl" object is the
106 * same as before. However, for all client side windows the impl object
107 * is shared with its parent (i.e. all client windows descendants of one
108 * native window has the same impl.
110 * Additionally there is a new type of platform independent impl object,
111 * GdkOffscreenWindow. All windows of type GDK_WINDOW_OFFSCREEN get an impl
112 * of this type (while their children are generally GDK_WINDOW_CHILD virtual
113 * windows). Such windows work by allocating a #cairo_surface_t as the backing
114 * store for drawing operations, which is resized with the window.
116 * GdkWindows have a pointer to the "impl window" they are in, i.e.
117 * the topmost GdkWindow which have the same "impl" value. This is stored
118 * in impl_window, which is different from the window itself only for client
120 * All GdkWindows (native or not) track the position of the window in the parent
121 * (x, y), the size of the window (width, height), the position of the window
122 * with respect to the impl window (abs_x, abs_y). We also track the clip
123 * region of the window wrt parent windows and siblings, in window-relative
124 * coordinates with and without child windows included (clip_region,
125 * clip_region_with_children).
127 * All toplevel windows are native windows, but also child windows can be
128 * native (although not children of offscreens). We always listen to
129 * a basic set of events (see get_native_event_mask) for these windows
130 * so that we can emulate events for any client side children.
132 * For native windows we apply the calculated clip region as a window shape
133 * so that eg. client side siblings that overlap the native child properly
134 * draws over the native child window.
136 * In order to minimize flicker and for performance we use a couple of cacheing
137 * tricks. First of all, every time we do a window to window copy area, for instance
138 * when moving a client side window or when scrolling/moving a region in a window
139 * we store this in outstanding_moves instead of applying immediately. We then
140 * delay this move until we really need it (because something depends on being
141 * able to read it), or until we're handing a redraw from an expose/invalidation
142 * (actually we delay it past redraw, but before blitting the double buffer
143 * to the window). This gives us two advantages. First of all it minimizes the time
144 * from the window is moved to the exposes related to that move, secondly it allows
145 * us to be smart about how to do the copy. We combine multiple moves into one (when
146 * possible) and we don't actually do copies to anything that is or will be
147 * invalidated and exposed anyway.
149 * Secondly, we use something called a "implicit paint" during repaint handling.
150 * An implicit paint is similar to a regular paint for the paint stack, but it is
151 * not put on the stack. Instead, it is set on the impl window, and later when
152 * regular gdk_window_begin_paint_region() happen on a window of this impl window
153 * we reuse the surface from the implicit paint. During repaint we create and at the
154 * end flush an implicit paint, which means we can collect all the paints on
155 * multiple client side windows in the same backing store.
158 #define USE_BACKING_STORE /* Appears to work on Win32, too, now. */
160 /* This adds a local value to the GdkVisibilityState enum */
161 #define GDK_VISIBILITY_NOT_VIEWABLE 3
164 PICK_EMBEDDED_CHILD, /* only called if children are embedded */
178 CLEAR_BG_WINCLEARED, /* Clear backgrounds except those that the window system clears */
182 struct _GdkWindowPaint
184 cairo_region_t *region;
185 cairo_surface_t *surface;
186 cairo_region_t *flushed;
188 guint uses_implicit : 1;
192 cairo_region_t *dest_region; /* The destination region */
193 int dx, dy; /* The amount that the source was moved to reach dest_region */
194 } GdkWindowRegionMove;
198 static void gdk_window_drop_cairo_surface (GdkWindow *private);
200 static void gdk_window_free_paint_stack (GdkWindow *window);
202 static void gdk_window_finalize (GObject *object);
204 static void gdk_window_set_property (GObject *object,
208 static void gdk_window_get_property (GObject *object,
213 static void gdk_window_clear_backing_region (GdkWindow *window,
214 cairo_region_t *region);
216 static void recompute_visible_regions (GdkWindow *private,
217 gboolean recalculate_siblings,
218 gboolean recalculate_children);
219 static void gdk_window_flush_outstanding_moves (GdkWindow *window);
220 static void gdk_window_flush_recursive (GdkWindow *window);
221 static void do_move_region_bits_on_impl (GdkWindow *window,
222 cairo_region_t *region, /* In impl window coords */
224 static void gdk_window_invalidate_in_parent (GdkWindow *private);
225 static void move_native_children (GdkWindow *private);
226 static void update_cursor (GdkDisplay *display,
228 static void impl_window_add_update_area (GdkWindow *impl_window,
229 cairo_region_t *region);
230 static void gdk_window_region_move_free (GdkWindowRegionMove *move);
231 static void gdk_window_invalidate_region_full (GdkWindow *window,
232 const cairo_region_t *region,
233 gboolean invalidate_children,
235 static void gdk_window_invalidate_rect_full (GdkWindow *window,
236 const GdkRectangle *rect,
237 gboolean invalidate_children,
239 static void _gdk_window_propagate_has_alpha_background (GdkWindow *window);
240 static cairo_surface_t *gdk_window_ref_impl_surface (GdkWindow *window);
242 static void gdk_window_set_frame_clock (GdkWindow *window,
243 GdkFrameClock *clock);
245 static guint signals[LAST_SIGNAL] = { 0 };
247 static gpointer parent_class = NULL;
249 static const cairo_user_data_key_t gdk_window_cairo_key;
251 G_DEFINE_ABSTRACT_TYPE (GdkWindow, gdk_window, G_TYPE_OBJECT)
253 #ifdef DEBUG_WINDOW_PRINTING
255 print_region (cairo_region_t *region)
257 GString *s = g_string_new ("{");
258 if (cairo_region_is_empty (region))
260 g_string_append (s, "empty");
264 int num = cairo_region_num_rectangles (region);
265 cairo_rectangle_int_t r;
269 cairo_region_get_rectangle (region, 0, &r);
270 g_string_append_printf (s, "%dx%d @%d,%d", r.width, r.height, r.x, r.y);
275 cairo_region_get_extents (region, &r);
276 g_string_append_printf (s, "extent: %dx%d @%d,%d, details: ", r.width, r.height, r.x, r.y);
277 for (i = 0; i < num; i++)
279 g_string_append_printf (s, "[%dx%d @%d,%d]", r.width, r.height, r.x, r.y);
281 g_string_append (s, ", ");
285 g_string_append (s, "}");
286 return g_string_free (s, FALSE);
291 _gdk_paintable_get_type (void)
293 static GType paintable_type = 0;
297 const GTypeInfo paintable_info =
299 sizeof (GdkPaintableIface), /* class_size */
300 NULL, /* base_init */
301 NULL, /* base_finalize */
304 paintable_type = g_type_register_static (G_TYPE_INTERFACE,
305 g_intern_static_string ("GdkPaintable"),
308 g_type_interface_add_prerequisite (paintable_type, G_TYPE_OBJECT);
311 return paintable_type;
315 gdk_window_init (GdkWindow *window)
317 /* 0-initialization is good for all other fields. */
319 window->window_type = GDK_WINDOW_CHILD;
321 window->state = GDK_WINDOW_STATE_WITHDRAWN;
322 window->fullscreen_mode = GDK_FULLSCREEN_ON_CURRENT_MONITOR;
325 window->toplevel_window_type = -1;
327 window->effective_visibility = GDK_VISIBILITY_NOT_VIEWABLE;
328 window->visibility = GDK_VISIBILITY_FULLY_OBSCURED;
329 /* Default to unobscured since some backends don't send visibility events */
330 window->native_visibility = GDK_VISIBILITY_UNOBSCURED;
332 window->device_cursor = g_hash_table_new_full (NULL, NULL,
333 NULL, g_object_unref);
336 /* Stop and return on the first non-NULL parent */
338 accumulate_get_window (GSignalInvocationHint *ihint,
340 const GValue *handler_return,
343 g_value_copy (handler_return, return_accu);
344 /* Continue while returning NULL */
345 return g_value_get_object (handler_return) == NULL;
349 create_surface_accumulator (GSignalInvocationHint *ihint,
351 const GValue *handler_return,
354 g_value_copy (handler_return, return_accu);
356 /* Stop on the first non-NULL return value */
357 return g_value_get_boxed (handler_return) == NULL;
360 static GQuark quark_pointer_window = 0;
363 gdk_window_class_init (GdkWindowClass *klass)
365 GObjectClass *object_class = G_OBJECT_CLASS (klass);
367 parent_class = g_type_class_peek_parent (klass);
369 object_class->finalize = gdk_window_finalize;
370 object_class->set_property = gdk_window_set_property;
371 object_class->get_property = gdk_window_get_property;
373 klass->create_surface = _gdk_offscreen_window_create_surface;
375 quark_pointer_window = g_quark_from_static_string ("gtk-pointer-window");
383 * The mouse pointer for a #GdkWindow. See gdk_window_set_cursor() and
384 * gdk_window_get_cursor() for details.
388 g_object_class_install_property (object_class,
390 g_param_spec_object ("cursor",
397 * GdkWindow::pick-embedded-child:
398 * @window: the window on which the signal is emitted
399 * @x: x coordinate in the window
400 * @y: y coordinate in the window
402 * The ::pick-embedded-child signal is emitted to find an embedded
403 * child at the given position.
405 * Returns: (transfer none): the #GdkWindow of the embedded child at
410 signals[PICK_EMBEDDED_CHILD] =
411 g_signal_new (g_intern_static_string ("pick-embedded-child"),
412 G_OBJECT_CLASS_TYPE (object_class),
414 G_STRUCT_OFFSET (GdkWindowClass, pick_embedded_child),
415 accumulate_get_window, NULL,
416 _gdk_marshal_OBJECT__DOUBLE_DOUBLE,
423 * GdkWindow::to-embedder:
424 * @window: the offscreen window on which the signal is emitted
425 * @offscreen_x: x coordinate in the offscreen window
426 * @offscreen_y: y coordinate in the offscreen window
427 * @embedder_x: (out) (type double): return location for the x
428 * coordinate in the embedder window
429 * @embedder_y: (out) (type double): return location for the y
430 * coordinate in the embedder window
432 * The ::to-embedder signal is emitted to translate coordinates
433 * in an offscreen window to its embedder.
435 * See also #GtkWindow::from-embedder.
439 signals[TO_EMBEDDER] =
440 g_signal_new (g_intern_static_string ("to-embedder"),
441 G_OBJECT_CLASS_TYPE (object_class),
443 G_STRUCT_OFFSET (GdkWindowClass, to_embedder),
445 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
454 * GdkWindow::from-embedder:
455 * @window: the offscreen window on which the signal is emitted
456 * @embedder_x: x coordinate in the embedder window
457 * @embedder_y: y coordinate in the embedder window
458 * @offscreen_x: (out) (type double): return location for the x
459 * coordinate in the offscreen window
460 * @offscreen_y: (out) (type double): return location for the y
461 * coordinate in the offscreen window
463 * The ::from-embedder signal is emitted to translate coordinates
464 * in the embedder of an offscreen window to the offscreen window.
466 * See also #GtkWindow::to-embedder.
470 signals[FROM_EMBEDDER] =
471 g_signal_new (g_intern_static_string ("from-embedder"),
472 G_OBJECT_CLASS_TYPE (object_class),
474 G_STRUCT_OFFSET (GdkWindowClass, from_embedder),
476 _gdk_marshal_VOID__DOUBLE_DOUBLE_POINTER_POINTER,
485 * GdkWindow::create-surface:
486 * @window: the offscreen window on which the signal is emitted
487 * @width: the width of the offscreen surface to create
488 * @height: the height of the offscreen surface to create
490 * The ::create-surface signal is emitted when an offscreen window
491 * needs its surface (re)created, which happens either when the the
492 * window is first drawn to, or when the window is being
493 * resized. The first signal handler that returns a non-%NULL
494 * surface will stop any further signal emission, and its surface
497 * Note that it is not possible to access the window's previous
498 * surface from within any callback of this signal. Calling
499 * gdk_offscreen_window_get_surface() will lead to a crash.
501 * Returns: the newly created #cairo_surface_t for the offscreen window
505 signals[CREATE_SURFACE] =
506 g_signal_new (g_intern_static_string ("create-surface"),
507 G_OBJECT_CLASS_TYPE (object_class),
509 G_STRUCT_OFFSET (GdkWindowClass, create_surface),
510 create_surface_accumulator, NULL,
511 _gdk_marshal_BOXED__INT_INT,
512 CAIRO_GOBJECT_TYPE_SURFACE,
519 device_removed_cb (GdkDeviceManager *device_manager,
523 window->devices_inside = g_list_remove (window->devices_inside, device);
524 g_hash_table_remove (window->device_cursor, device);
526 if (window->device_events)
527 g_hash_table_remove (window->device_events, device);
531 gdk_window_finalize (GObject *object)
533 GdkWindow *window = GDK_WINDOW (object);
534 GdkDeviceManager *device_manager;
536 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
537 g_signal_handlers_disconnect_by_func (device_manager, device_removed_cb, window);
539 if (!GDK_WINDOW_DESTROYED (window))
541 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
543 g_warning ("losing last reference to undestroyed window\n");
544 _gdk_window_destroy (window, FALSE);
547 /* We use TRUE here, to keep us from actually calling
548 * XDestroyWindow() on the window
550 _gdk_window_destroy (window, TRUE);
553 gdk_window_drop_cairo_surface (window);
557 g_object_unref (window->impl);
561 if (window->impl_window != window)
563 g_object_unref (window->impl_window);
564 window->impl_window = NULL;
568 cairo_region_destroy (window->shape);
570 if (window->input_shape)
571 cairo_region_destroy (window->input_shape);
574 g_object_unref (window->cursor);
576 if (window->device_cursor)
577 g_hash_table_destroy (window->device_cursor);
579 if (window->device_events)
580 g_hash_table_destroy (window->device_events);
582 if (window->source_event_masks)
583 g_hash_table_destroy (window->source_event_masks);
585 if (window->devices_inside)
586 g_list_free (window->devices_inside);
588 if (window->layered_region)
589 cairo_region_destroy (window->layered_region);
591 G_OBJECT_CLASS (parent_class)->finalize (object);
595 gdk_window_set_property (GObject *object,
600 GdkWindow *window = (GdkWindow *)object;
605 gdk_window_set_cursor (window, g_value_get_object (value));
609 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
615 gdk_window_get_property (GObject *object,
620 GdkWindow *window = (GdkWindow *) object;
625 g_value_set_object (value, gdk_window_get_cursor (window));
629 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
635 gdk_window_is_offscreen (GdkWindow *window)
637 return window->window_type == GDK_WINDOW_OFFSCREEN;
641 gdk_window_get_impl_window (GdkWindow *window)
643 return window->impl_window;
647 _gdk_window_get_impl_window (GdkWindow *window)
649 return gdk_window_get_impl_window (window);
653 gdk_window_has_impl (GdkWindow *window)
655 return window->impl_window == window;
659 gdk_window_is_toplevel (GdkWindow *window)
662 window->parent == NULL ||
663 window->parent->window_type == GDK_WINDOW_ROOT;
667 _gdk_window_has_impl (GdkWindow *window)
669 return gdk_window_has_impl (window);
673 gdk_window_has_no_impl (GdkWindow *window)
675 return window->impl_window != window;
679 gdk_window_has_alpha (GdkWindow *window)
681 return !gdk_window_has_impl (window) &&
682 (window->has_alpha_background || window->alpha != 255);
686 remove_layered_child_area (GdkWindow *window,
687 cairo_region_t *region)
690 cairo_region_t *child_region;
694 for (l = window->children; l; l = l->next)
698 /* If region is empty already, no need to do
699 anything potentially costly */
700 if (cairo_region_is_empty (region))
703 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
706 /* Ignore offscreen children, as they don't draw in their parent and
707 * don't take part in the clipping */
708 if (gdk_window_is_offscreen (child))
711 /* Only non-impl children with alpha add to the layered region */
712 if (!gdk_window_has_alpha (child))
717 r.width = child->width;
718 r.height = child->height;
720 /* Bail early if child totally outside region */
721 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
724 child_region = cairo_region_create_rectangle (&r);
727 /* Adjust shape region to parent window coords */
728 cairo_region_translate (child->shape, child->x, child->y);
729 cairo_region_intersect (child_region, child->shape);
730 cairo_region_translate (child->shape, -child->x, -child->y);
733 cairo_region_subtract (region, child_region);
734 cairo_region_destroy (child_region);
739 remove_child_area (GdkWindow *window,
742 cairo_region_t *region,
743 cairo_region_t *layered_region)
746 cairo_region_t *child_region;
749 cairo_region_t *shape;
751 for (l = window->children; l; l = l->next)
758 /* If region is empty already, no need to do
759 anything potentially costly */
760 if (cairo_region_is_empty (region))
763 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
766 /* Ignore offscreen children, as they don't draw in their parent and
767 * don't take part in the clipping */
768 if (gdk_window_is_offscreen (child))
773 r.width = child->width;
774 r.height = child->height;
776 /* Bail early if child totally outside region */
777 if (cairo_region_contains_rectangle (region, &r) == CAIRO_REGION_OVERLAP_OUT)
780 child_region = cairo_region_create_rectangle (&r);
784 /* Adjust shape region to parent window coords */
785 cairo_region_translate (child->shape, child->x, child->y);
786 cairo_region_intersect (child_region, child->shape);
787 cairo_region_translate (child->shape, -child->x, -child->y);
789 else if (window->window_type == GDK_WINDOW_FOREIGN)
791 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_shape (child);
794 cairo_region_intersect (child_region, shape);
795 cairo_region_destroy (shape);
801 if (child->input_shape)
802 cairo_region_intersect (child_region, child->input_shape);
803 else if (window->window_type == GDK_WINDOW_FOREIGN)
805 shape = GDK_WINDOW_IMPL_GET_CLASS (child)->get_input_shape (child);
808 cairo_region_intersect (child_region, shape);
809 cairo_region_destroy (shape);
814 if (gdk_window_has_alpha (child))
816 if (layered_region != NULL)
817 cairo_region_union (layered_region, child_region);
820 cairo_region_subtract (region, child_region);
821 cairo_region_destroy (child_region);
825 static GdkVisibilityState
826 effective_visibility (GdkWindow *window)
828 GdkVisibilityState native;
830 if (!gdk_window_is_viewable (window))
831 return GDK_VISIBILITY_NOT_VIEWABLE;
833 native = window->impl_window->native_visibility;
835 if (native == GDK_VISIBILITY_FULLY_OBSCURED ||
836 window->visibility == GDK_VISIBILITY_FULLY_OBSCURED)
837 return GDK_VISIBILITY_FULLY_OBSCURED;
838 else if (native == GDK_VISIBILITY_UNOBSCURED)
839 return window->visibility;
840 else /* native PARTIAL, private partial or unobscured */
841 return GDK_VISIBILITY_PARTIAL;
845 gdk_window_update_visibility (GdkWindow *window)
847 GdkVisibilityState new_visibility;
850 new_visibility = effective_visibility (window);
852 if (new_visibility != window->effective_visibility)
854 window->effective_visibility = new_visibility;
856 if (new_visibility != GDK_VISIBILITY_NOT_VIEWABLE &&
857 window->event_mask & GDK_VISIBILITY_NOTIFY_MASK)
859 event = _gdk_make_event (window, GDK_VISIBILITY_NOTIFY,
861 event->visibility.state = new_visibility;
867 gdk_window_update_visibility_recursively (GdkWindow *window,
868 GdkWindow *only_for_impl)
873 gdk_window_update_visibility (window);
874 for (l = window->children; l != NULL; l = l->next)
877 if ((only_for_impl == NULL) ||
878 (only_for_impl == child->impl_window))
879 gdk_window_update_visibility_recursively (child, only_for_impl);
884 should_apply_clip_as_shape (GdkWindow *window)
887 gdk_window_has_impl (window) &&
888 /* Not for offscreens */
889 !gdk_window_is_offscreen (window) &&
890 /* or for toplevels */
891 !gdk_window_is_toplevel (window) &&
892 /* or for foreign windows */
893 window->window_type != GDK_WINDOW_FOREIGN &&
894 /* or for the root window */
895 window->window_type != GDK_WINDOW_ROOT;
899 apply_shape (GdkWindow *window,
900 cairo_region_t *region)
902 GdkWindowImplClass *impl_class;
904 /* We trash whether we applied a shape so that
905 we can avoid unsetting it many times, which
906 could happen in e.g. apply_clip_as_shape as
907 windows get resized */
908 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
910 impl_class->shape_combine_region (window,
912 else if (window->applied_shape)
913 impl_class->shape_combine_region (window,
916 window->applied_shape = region != NULL;
920 region_rect_equal (const cairo_region_t *region,
921 const GdkRectangle *rect)
923 GdkRectangle extents;
925 if (cairo_region_num_rectangles (region) != 1)
928 cairo_region_get_extents (region, &extents);
930 return extents.x == rect->x &&
931 extents.y == rect->y &&
932 extents.width == rect->width &&
933 extents.height == rect->height;
937 apply_clip_as_shape (GdkWindow *window)
942 r.width = window->width;
943 r.height = window->height;
945 /* We only apply the clip region if would differ
946 from the actual clip region implied by the size
947 of the window. This is to avoid unneccessarily
948 adding meaningless shapes to all native subwindows */
949 if (!region_rect_equal (window->clip_region, &r))
950 apply_shape (window, window->clip_region);
952 apply_shape (window, NULL);
956 recompute_visible_regions_internal (GdkWindow *private,
957 gboolean recalculate_clip,
958 gboolean recalculate_siblings,
959 gboolean recalculate_children)
964 cairo_region_t *new_clip, *new_layered;
965 gboolean clip_region_changed;
966 gboolean abs_pos_changed;
967 int old_abs_x, old_abs_y;
969 old_abs_x = private->abs_x;
970 old_abs_y = private->abs_y;
972 /* Update absolute position */
973 if (gdk_window_has_impl (private))
975 /* Native window starts here */
981 private->abs_x = private->parent->abs_x + private->x;
982 private->abs_y = private->parent->abs_y + private->y;
986 private->abs_x != old_abs_x ||
987 private->abs_y != old_abs_y;
989 /* Update clip region based on:
992 * siblings in parents above window
994 clip_region_changed = FALSE;
995 if (recalculate_clip)
997 new_layered = cairo_region_create ();
998 if (private->viewable)
1000 /* Calculate visible region (sans children) in parent window coords */
1003 r.width = private->width;
1004 r.height = private->height;
1005 new_clip = cairo_region_create_rectangle (&r);
1007 if (!gdk_window_is_toplevel (private))
1009 cairo_region_intersect (new_clip, private->parent->clip_region);
1010 cairo_region_union (new_layered, private->parent->layered_region);
1012 /* Remove all overlapping children from parent. */
1013 remove_child_area (private->parent, private, FALSE, new_clip, new_layered);
1016 /* Convert from parent coords to window coords */
1017 cairo_region_translate (new_clip, -private->x, -private->y);
1018 cairo_region_translate (new_layered, -private->x, -private->y);
1021 cairo_region_intersect (new_clip, private->shape);
1024 new_clip = cairo_region_create ();
1026 cairo_region_intersect (new_layered, new_clip);
1028 if (private->clip_region == NULL ||
1029 !cairo_region_equal (private->clip_region, new_clip))
1030 clip_region_changed = TRUE;
1032 if (private->layered_region == NULL ||
1033 !cairo_region_equal (private->layered_region, new_layered))
1034 clip_region_changed = TRUE;
1036 if (private->clip_region)
1037 cairo_region_destroy (private->clip_region);
1038 private->clip_region = new_clip;
1040 if (private->layered_region != NULL)
1041 cairo_region_destroy (private->layered_region);
1042 private->layered_region = new_layered;
1044 if (private->clip_region_with_children)
1045 cairo_region_destroy (private->clip_region_with_children);
1046 private->clip_region_with_children = cairo_region_copy (private->clip_region);
1047 if (private->window_type != GDK_WINDOW_ROOT)
1048 remove_child_area (private, NULL, FALSE, private->clip_region_with_children, NULL);
1051 if (clip_region_changed)
1053 GdkVisibilityState visibility;
1054 gboolean fully_visible;
1056 if (cairo_region_is_empty (private->clip_region))
1057 visibility = GDK_VISIBILITY_FULLY_OBSCURED;
1062 fully_visible = cairo_region_equal (private->clip_region,
1069 r.width = private->width;
1070 r.height = private->height;
1071 fully_visible = region_rect_equal (private->clip_region, &r);
1075 visibility = GDK_VISIBILITY_UNOBSCURED;
1077 visibility = GDK_VISIBILITY_PARTIAL;
1080 if (private->visibility != visibility)
1082 private->visibility = visibility;
1083 gdk_window_update_visibility (private);
1087 /* Update all children, recursively (except for root, where children are not exact). */
1088 if ((abs_pos_changed || clip_region_changed || recalculate_children) &&
1089 private->window_type != GDK_WINDOW_ROOT)
1091 for (l = private->children; l; l = l->next)
1094 /* Only recalculate clip if the the clip region changed, otherwise
1095 * there is no way the child clip region could change (its has not e.g. moved)
1096 * Except if recalculate_children is set to force child updates
1098 recompute_visible_regions_internal (child,
1099 recalculate_clip && (clip_region_changed || recalculate_children),
1104 if (clip_region_changed &&
1105 should_apply_clip_as_shape (private))
1106 apply_clip_as_shape (private);
1108 if (recalculate_siblings &&
1109 !gdk_window_is_toplevel (private))
1111 /* If we moved a child window in parent or changed the stacking order, then we
1112 * need to recompute the visible area of all the other children in the parent
1114 for (l = private->parent->children; l; l = l->next)
1118 if (child != private)
1119 recompute_visible_regions_internal (child, TRUE, FALSE, FALSE);
1122 /* We also need to recompute the _with_children clip for the parent */
1123 recompute_visible_regions_internal (private->parent, TRUE, FALSE, FALSE);
1126 if (private->cairo_surface && gdk_window_has_impl (private))
1128 GdkWindowImplClass *iface = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1130 private->cairo_surface = iface->resize_cairo_surface (private,
1131 private->cairo_surface,
1135 else if (private->cairo_surface)
1136 gdk_window_drop_cairo_surface (private);
1139 /* Call this when private has changed in one or more of these ways:
1143 * stacking order of window changed
1146 * It will recalculate abs_x/y and the clip regions
1148 * Unless the window didn't change stacking order or size/pos, pass in TRUE
1149 * for recalculate_siblings. (Mostly used internally for the recursion)
1151 * If a child window was removed (and you can't use that child for
1152 * recompute_visible_regions), pass in TRUE for recalculate_children on the parent
1155 recompute_visible_regions (GdkWindow *private,
1156 gboolean recalculate_siblings,
1157 gboolean recalculate_children)
1159 recompute_visible_regions_internal (private,
1161 recalculate_siblings,
1162 recalculate_children);
1166 _gdk_window_update_size (GdkWindow *window)
1168 recompute_visible_regions (window, TRUE, FALSE);
1171 /* Find the native window that would be just above "child"
1172 * in the native stacking order if "child" was a native window
1173 * (it doesn't have to be native). If there is no such native
1174 * window inside this native parent then NULL is returned.
1175 * If child is NULL, find lowest native window in parent.
1178 find_native_sibling_above_helper (GdkWindow *parent,
1186 l = g_list_find (parent->children, child);
1187 g_assert (l != NULL); /* Better be a child of its parent... */
1188 l = l->prev; /* Start looking at the one above the child */
1191 l = g_list_last (parent->children);
1193 for (; l != NULL; l = l->prev)
1197 if (gdk_window_has_impl (w))
1200 g_assert (parent != w);
1201 w = find_native_sibling_above_helper (w, NULL);
1211 find_native_sibling_above (GdkWindow *parent,
1216 w = find_native_sibling_above_helper (parent, child);
1220 if (gdk_window_has_impl (parent))
1223 return find_native_sibling_above (parent->parent, parent);
1227 get_native_device_event_mask (GdkWindow *private,
1230 GdkEventMask event_mask;
1233 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (private->device_events, device));
1235 event_mask = private->event_mask;
1237 if (private->window_type == GDK_WINDOW_ROOT ||
1238 private->window_type == GDK_WINDOW_FOREIGN)
1244 /* Do whatever the app asks to, since the app
1245 * may be asking for weird things for native windows,
1246 * but don't use motion hints as that may affect non-native
1247 * child windows that don't want it. Also, we need to
1248 * set all the app-specified masks since they will be picked
1249 * up by any implicit grabs (i.e. if they were not set as
1250 * native we would not get the events we need). */
1251 mask = private->event_mask & ~GDK_POINTER_MOTION_HINT_MASK;
1253 /* We need thse for all native windows so we can
1254 emulate events on children: */
1257 GDK_VISIBILITY_NOTIFY_MASK |
1258 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK;
1260 /* Additionally we select for pointer and button events
1261 * for toplevels as we need to get these to emulate
1262 * them for non-native subwindows. Even though we don't
1263 * select on them for all native windows we will get them
1264 * as the events are propagated out to the first window
1265 * that select for them.
1266 * Not selecting for button press on all windows is an
1267 * important thing, because in X only one client can do
1268 * so, and we don't want to unexpectedly prevent another
1269 * client from doing it.
1271 * We also need to do the same if the app selects for button presses
1272 * because then we will get implicit grabs for this window, and the
1273 * event mask used for that grab is based on the rest of the mask
1274 * for the window, but we might need more events than this window
1275 * lists due to some non-native child window.
1277 if (gdk_window_is_toplevel (private) ||
1278 mask & GDK_BUTTON_PRESS_MASK)
1281 GDK_POINTER_MOTION_MASK |
1282 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1290 get_native_grab_event_mask (GdkEventMask grab_mask)
1292 /* Similar to the above but for pointer events only */
1294 GDK_POINTER_MOTION_MASK |
1295 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
1296 GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK |
1299 ~GDK_POINTER_MOTION_HINT_MASK);
1303 get_native_event_mask (GdkWindow *private)
1305 return get_native_device_event_mask (private, NULL);
1308 /* Puts the native window in the right order wrt the other native windows
1309 * in the hierarchy, given the position it has in the client side data.
1310 * This is useful if some operation changed the stacking order.
1311 * This calls assumes the native window is now topmost in its native parent.
1314 sync_native_window_stack_position (GdkWindow *window)
1317 GdkWindowImplClass *impl_class;
1318 GList listhead = {0};
1320 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1322 above = find_native_sibling_above (window->parent, window);
1325 listhead.data = window;
1326 impl_class->restack_under (above, &listhead);
1331 * gdk_window_new: (constructor)
1332 * @parent: (allow-none): a #GdkWindow, or %NULL to create the window as a child of
1333 * the default root window for the default display.
1334 * @attributes: attributes of the new window
1335 * @attributes_mask: (type GdkWindowAttributesType): mask indicating which
1336 * fields in @attributes are valid
1338 * Creates a new #GdkWindow using the attributes from
1339 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
1340 * more details. Note: to use this on displays other than the default
1341 * display, @parent must be specified.
1343 * Return value: (transfer full): the new #GdkWindow
1346 gdk_window_new (GdkWindow *parent,
1347 GdkWindowAttr *attributes,
1348 gint attributes_mask)
1352 GdkDisplay *display;
1355 GdkEventMask event_mask;
1356 GdkWindow *real_parent;
1357 GdkDeviceManager *device_manager;
1359 g_return_val_if_fail (attributes != NULL, NULL);
1363 GDK_NOTE (MULTIHEAD,
1364 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
1366 screen = gdk_screen_get_default ();
1367 parent = gdk_screen_get_root_window (screen);
1370 screen = gdk_window_get_screen (parent);
1372 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
1374 if (GDK_WINDOW_DESTROYED (parent))
1376 g_warning ("gdk_window_new(): parent is destroyed\n");
1380 if (attributes_mask & GDK_WA_VISUAL)
1382 g_return_val_if_fail (gdk_visual_get_screen (attributes->visual) == screen, NULL);
1385 display = gdk_screen_get_display (screen);
1387 window = _gdk_display_create_window (display);
1389 /* Windows with a foreign parent are treated as if they are children
1390 * of the root window, except for actual creation.
1392 real_parent = parent;
1393 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
1394 parent = gdk_screen_get_root_window (screen);
1396 window->parent = parent;
1398 window->accept_focus = TRUE;
1399 window->focus_on_map = TRUE;
1401 if (attributes_mask & GDK_WA_X)
1406 if (attributes_mask & GDK_WA_Y)
1413 window->width = (attributes->width > 1) ? (attributes->width) : (1);
1414 window->height = (attributes->height > 1) ? (attributes->height) : (1);
1415 window->alpha = 255;
1417 if (attributes->wclass == GDK_INPUT_ONLY)
1419 /* Backwards compatiblity - we've always ignored
1420 * attributes->window_type for input-only windows
1423 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
1424 window->window_type = GDK_WINDOW_TEMP;
1426 window->window_type = GDK_WINDOW_CHILD;
1429 window->window_type = attributes->window_type;
1432 switch (window->window_type)
1434 case GDK_WINDOW_TOPLEVEL:
1435 case GDK_WINDOW_TEMP:
1436 case GDK_WINDOW_OFFSCREEN:
1437 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
1438 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
1439 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
1440 case GDK_WINDOW_CHILD:
1444 g_warning (G_STRLOC "cannot make windows of type %d", window->window_type);
1448 if (attributes_mask & GDK_WA_VISUAL)
1449 window->visual = attributes->visual;
1451 window->visual = gdk_screen_get_system_visual (screen);
1453 window->event_mask = attributes->event_mask;
1455 if (attributes->wclass == GDK_INPUT_OUTPUT)
1457 window->input_only = FALSE;
1458 window->depth = window->visual->depth;
1460 /* XXX: Cache this somehow? */
1461 window->background = cairo_pattern_create_rgba (0, 0, 0, 0);
1462 window->has_alpha_background = TRUE;
1467 window->input_only = TRUE;
1471 window->parent->children = g_list_prepend (window->parent->children, window);
1473 if (window->parent->window_type == GDK_WINDOW_ROOT)
1475 GdkFrameClock *frame_clock = g_object_new (GDK_TYPE_FRAME_CLOCK_IDLE, NULL);
1476 gdk_window_set_frame_clock (window, frame_clock);
1477 g_object_unref (frame_clock);
1481 if (window->parent->window_type == GDK_WINDOW_ROOT)
1482 native = TRUE; /* Always use native windows for toplevels */
1483 else if (!window->input_only &&
1484 (attributes_mask & GDK_WA_VISUAL &&
1485 attributes->visual != gdk_window_get_visual (window->parent)))
1486 native = TRUE; /* InputOutput window with different visual than parent, needs native window */
1488 if (gdk_window_is_offscreen (window))
1490 _gdk_offscreen_window_new (window, attributes, attributes_mask);
1491 window->impl_window = window;
1495 event_mask = get_native_event_mask (window);
1497 /* Create the impl */
1498 _gdk_display_create_window_impl (display, window, real_parent, screen, event_mask, attributes, attributes_mask);
1499 window->impl_window = window;
1501 /* This will put the native window topmost in the native parent, which may
1502 * be wrong wrt other native windows in the non-native hierarchy, so restack */
1503 if (!_gdk_window_has_impl (real_parent))
1504 sync_native_window_stack_position (window);
1508 window->impl_window = g_object_ref (window->parent->impl_window);
1509 window->impl = g_object_ref (window->impl_window->impl);
1512 recompute_visible_regions (window, TRUE, FALSE);
1514 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
1515 (attributes->cursor) :
1518 device_manager = gdk_display_get_device_manager (gdk_window_get_display (parent));
1519 g_signal_connect (device_manager, "device-removed",
1520 G_CALLBACK (device_removed_cb), window);
1526 is_parent_of (GdkWindow *parent,
1537 w = gdk_window_get_parent (w);
1544 change_impl (GdkWindow *private,
1545 GdkWindow *impl_window,
1550 GdkWindowImpl *old_impl;
1551 GdkWindow *old_impl_window;
1553 old_impl = private->impl;
1554 old_impl_window = private->impl_window;
1555 if (private != impl_window)
1556 private->impl_window = g_object_ref (impl_window);
1558 private->impl_window = private;
1559 private->impl = g_object_ref (new);
1560 if (old_impl_window != private)
1561 g_object_unref (old_impl_window);
1562 g_object_unref (old_impl);
1564 for (l = private->children; l != NULL; l = l->next)
1568 if (child->impl == old_impl)
1569 change_impl (child, impl_window, new);
1574 reparent_to_impl (GdkWindow *private)
1579 GdkWindowImplClass *impl_class;
1581 impl_class = GDK_WINDOW_IMPL_GET_CLASS (private->impl);
1583 /* Enumerate in reverse order so we get the right order for the native
1584 windows (first in childrens list is topmost, and reparent places on top) */
1585 for (l = g_list_last (private->children); l != NULL; l = l->prev)
1589 if (child->impl == private->impl)
1590 reparent_to_impl (child);
1593 show = impl_class->reparent ((GdkWindow *)child,
1594 (GdkWindow *)private,
1595 child->x, child->y);
1597 gdk_window_show_unraised ((GdkWindow *)child);
1604 * gdk_window_reparent:
1605 * @window: a #GdkWindow
1606 * @new_parent: new parent to move @window into
1607 * @x: X location inside the new parent
1608 * @y: Y location inside the new parent
1610 * Reparents @window into the given @new_parent. The window being
1611 * reparented will be unmapped as a side effect.
1615 gdk_window_reparent (GdkWindow *window,
1616 GdkWindow *new_parent,
1620 GdkWindow *old_parent;
1622 gboolean show, was_mapped, applied_clip_as_shape;
1623 gboolean do_reparent_to_impl;
1624 GdkEventMask old_native_event_mask;
1625 GdkWindowImplClass *impl_class;
1627 g_return_if_fail (GDK_IS_WINDOW (window));
1628 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1629 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1631 if (GDK_WINDOW_DESTROYED (window) ||
1632 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1635 screen = gdk_window_get_screen (window);
1637 new_parent = gdk_screen_get_root_window (screen);
1639 /* No input-output children of input-only windows */
1640 if (new_parent->input_only && !window->input_only)
1643 /* Don't create loops in hierarchy */
1644 if (is_parent_of (window, new_parent))
1647 /* This might be wrong in the new parent, e.g. for non-native surfaces.
1648 To make sure we're ok, just wipe it. */
1649 gdk_window_drop_cairo_surface (window);
1651 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1652 old_parent = window->parent;
1654 was_mapped = GDK_WINDOW_IS_MAPPED (window);
1657 /* Reparenting to toplevel. Ensure we have a native window so this can work */
1658 if (new_parent->window_type == GDK_WINDOW_ROOT ||
1659 new_parent->window_type == GDK_WINDOW_FOREIGN)
1660 gdk_window_ensure_native (window);
1662 applied_clip_as_shape = should_apply_clip_as_shape (window);
1664 old_native_event_mask = 0;
1665 do_reparent_to_impl = FALSE;
1666 if (gdk_window_has_impl (window))
1668 old_native_event_mask = get_native_event_mask (window);
1670 show = impl_class->reparent (window, new_parent, x, y);
1674 /* This shouldn't happen, as we created a native in this case, check anyway to see if that ever fails */
1675 g_assert (new_parent->window_type != GDK_WINDOW_ROOT &&
1676 new_parent->window_type != GDK_WINDOW_FOREIGN);
1679 gdk_window_hide (window);
1681 do_reparent_to_impl = TRUE;
1682 change_impl (window,
1683 new_parent->impl_window,
1687 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1690 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1692 new_parent = gdk_screen_get_root_window (screen);
1696 old_parent->children = g_list_remove (old_parent->children, window);
1698 window->parent = new_parent;
1702 new_parent->children = g_list_prepend (new_parent->children, window);
1704 /* Switch the window type as appropriate */
1706 switch (GDK_WINDOW_TYPE (new_parent))
1708 case GDK_WINDOW_ROOT:
1709 case GDK_WINDOW_FOREIGN:
1710 if (window->toplevel_window_type != -1)
1711 GDK_WINDOW_TYPE (window) = window->toplevel_window_type;
1712 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1713 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1715 case GDK_WINDOW_OFFSCREEN:
1716 case GDK_WINDOW_TOPLEVEL:
1717 case GDK_WINDOW_CHILD:
1718 case GDK_WINDOW_TEMP:
1719 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
1720 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1722 /* Save the original window type so we can restore it if the
1723 * window is reparented back to be a toplevel
1725 window->toplevel_window_type = GDK_WINDOW_TYPE (window);
1726 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1730 /* If we changed the window type, we might have to set or
1731 * unset the frame clock on the window
1733 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_ROOT &&
1734 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1736 if (window->frame_clock == NULL)
1738 GdkFrameClock *frame_clock = g_object_new (GDK_TYPE_FRAME_CLOCK_IDLE, NULL);
1739 gdk_window_set_frame_clock (window, frame_clock);
1740 g_object_unref (frame_clock);
1745 if (window->frame_clock != NULL)
1747 g_object_run_dispose (G_OBJECT (window->frame_clock));
1748 gdk_window_set_frame_clock (window, NULL);
1752 /* We might have changed window type for a native windows, so we
1753 need to change the event mask too. */
1754 if (gdk_window_has_impl (window))
1756 GdkEventMask native_event_mask = get_native_event_mask (window);
1758 if (native_event_mask != old_native_event_mask)
1759 impl_class->set_events (window, native_event_mask);
1762 _gdk_window_update_viewable (window);
1764 if (window->background == NULL)
1766 /* parent relative background, update has_alpha_background */
1767 if (window->parent == NULL ||
1768 window->parent->window_type == GDK_WINDOW_ROOT)
1769 window->has_alpha_background = FALSE;
1771 window->has_alpha_background = window->parent->has_alpha_background;
1774 recompute_visible_regions (window, TRUE, FALSE);
1775 if (old_parent && GDK_WINDOW_TYPE (old_parent) != GDK_WINDOW_ROOT)
1776 recompute_visible_regions (old_parent, FALSE, TRUE);
1778 _gdk_window_propagate_has_alpha_background (window);
1780 /* We used to apply the clip as the shape, but no more.
1781 Reset this to the real shape */
1782 if (gdk_window_has_impl (window) &&
1783 applied_clip_as_shape &&
1784 !should_apply_clip_as_shape (window))
1785 apply_shape (window, window->shape);
1787 if (do_reparent_to_impl)
1788 reparent_to_impl (window);
1791 /* The reparent will have put the native window topmost in the native parent,
1792 * which may be wrong wrt other native windows in the non-native hierarchy,
1794 if (!gdk_window_has_impl (new_parent))
1795 sync_native_window_stack_position (window);
1799 gdk_window_show_unraised (window);
1801 _gdk_synthesize_crossing_events_for_geometry_change (window);
1805 * gdk_window_ensure_native:
1806 * @window: a #GdkWindow
1808 * Tries to ensure that there is a window-system native window for this
1809 * GdkWindow. This may fail in some situations, returning %FALSE.
1811 * Offscreen window and children of them can never have native windows.
1813 * Some backends may not support native child windows.
1815 * Returns: %TRUE if the window has a native window, %FALSE otherwise
1820 gdk_window_ensure_native (GdkWindow *window)
1822 GdkWindow *impl_window;
1823 GdkWindowImpl *new_impl, *old_impl;
1824 GdkDisplay *display;
1828 GdkWindowImplClass *impl_class;
1830 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
1832 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_ROOT ||
1833 GDK_WINDOW_DESTROYED (window))
1836 impl_window = gdk_window_get_impl_window (window);
1838 if (gdk_window_is_offscreen (impl_window))
1839 return FALSE; /* native in offscreens not supported */
1841 if (impl_window == window)
1842 /* Already has an impl, and its not offscreen . */
1845 /* Need to create a native window */
1847 gdk_window_drop_cairo_surface (window);
1849 screen = gdk_window_get_screen (window);
1850 display = gdk_screen_get_display (screen);
1852 old_impl = window->impl;
1853 _gdk_display_create_window_impl (display,
1854 window, window->parent,
1856 get_native_event_mask (window),
1858 new_impl = window->impl;
1860 window->impl = old_impl;
1861 change_impl (window, window, new_impl);
1863 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
1865 /* Native window creation will put the native window topmost in the
1866 * native parent, which may be wrong wrt the position of the previous
1867 * non-native window wrt to the other non-native children, so correct this.
1869 above = find_native_sibling_above (window->parent, window);
1872 listhead.data = window;
1873 listhead.prev = NULL;
1874 listhead.next = NULL;
1875 impl_class->restack_under ((GdkWindow *)above, &listhead);
1878 recompute_visible_regions (window, FALSE, FALSE);
1880 /* The shape may not have been set, as the clip region doesn't actually
1881 change, so do it here manually */
1882 if (should_apply_clip_as_shape (window))
1883 apply_clip_as_shape (window);
1885 reparent_to_impl (window);
1887 if (!window->input_only)
1888 impl_class->set_background (window, window->background);
1890 impl_class->input_shape_combine_region (window,
1891 window->input_shape,
1894 if (gdk_window_is_viewable (window))
1895 impl_class->show (window, FALSE);
1901 * _gdk_event_filter_unref:
1902 * @window: (allow-none): A #GdkWindow, or %NULL to be the global window
1903 * @filter: A window filter
1905 * Release a reference to @filter. Note this function may
1906 * mutate the list storage, so you need to handle this
1907 * if iterating over a list of filters.
1910 _gdk_event_filter_unref (GdkWindow *window,
1911 GdkEventFilter *filter)
1917 filters = &_gdk_default_filters;
1919 filters = &window->filters;
1921 tmp_list = *filters;
1924 GdkEventFilter *iter_filter = tmp_list->data;
1928 tmp_list = tmp_list->next;
1930 if (iter_filter != filter)
1933 g_assert (iter_filter->ref_count > 0);
1935 filter->ref_count--;
1936 if (filter->ref_count != 0)
1939 *filters = g_list_remove_link (*filters, node);
1941 g_list_free_1 (node);
1946 window_remove_filters (GdkWindow *window)
1948 while (window->filters)
1949 _gdk_event_filter_unref (window, window->filters->data);
1953 update_pointer_info_foreach (GdkDisplay *display,
1955 GdkPointerWindowInfo *pointer_info,
1958 GdkWindow *window = user_data;
1960 if (pointer_info->toplevel_under_pointer == window)
1962 g_object_unref (pointer_info->toplevel_under_pointer);
1963 pointer_info->toplevel_under_pointer = NULL;
1968 window_remove_from_pointer_info (GdkWindow *window,
1969 GdkDisplay *display)
1971 _gdk_display_pointer_info_foreach (display,
1972 update_pointer_info_foreach,
1977 * _gdk_window_destroy_hierarchy:
1978 * @window: a #GdkWindow
1979 * @recursing: If TRUE, then this is being called because a parent
1981 * @recursing_native: If TRUE, then this is being called because a native parent
1982 * was destroyed. This generally means that the call to the
1983 * windowing system to destroy the window can be omitted, since
1984 * it will be destroyed as a result of the parent being destroyed.
1985 * Unless @foreign_destroy.
1986 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
1987 * external agency. The window has already been destroyed and no
1988 * windowing system calls should be made. (This may never happen
1989 * for some windowing systems.)
1991 * Internal function to destroy a window. Like gdk_window_destroy(),
1992 * but does not drop the reference count created by gdk_window_new().
1995 _gdk_window_destroy_hierarchy (GdkWindow *window,
1997 gboolean recursing_native,
1998 gboolean foreign_destroy)
2000 GdkWindowImplClass *impl_class;
2001 GdkWindow *temp_window;
2003 GdkDisplay *display;
2007 g_return_if_fail (GDK_IS_WINDOW (window));
2009 if (GDK_WINDOW_DESTROYED (window))
2012 display = gdk_window_get_display (window);
2013 screen = gdk_window_get_screen (window);
2014 temp_window = g_object_get_qdata (G_OBJECT (screen), quark_pointer_window);
2015 if (temp_window == window)
2016 g_object_set_qdata (G_OBJECT (screen), quark_pointer_window, NULL);
2019 switch (window->window_type)
2021 case GDK_WINDOW_ROOT:
2022 if (!screen->closed)
2024 g_error ("attempted to destroy root window");
2027 /* else fall thru */
2028 case GDK_WINDOW_TOPLEVEL:
2029 case GDK_WINDOW_CHILD:
2030 case GDK_WINDOW_TEMP:
2031 case GDK_WINDOW_FOREIGN:
2032 case GDK_WINDOW_OFFSCREEN:
2033 if (window->window_type == GDK_WINDOW_FOREIGN && !foreign_destroy)
2035 /* Logically, it probably makes more sense to send
2036 * a "destroy yourself" message to the foreign window
2037 * whether or not it's in our hierarchy; but for historical
2038 * reasons, we only send "destroy yourself" messages to
2039 * foreign windows in our hierarchy.
2043 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
2045 if (gdk_window_has_impl (window))
2046 impl_class->destroy_foreign (window);
2049 /* Also for historical reasons, we remove any filters
2050 * on a foreign window when it or a parent is destroyed;
2051 * this likely causes problems if two separate portions
2052 * of code are maintaining filter lists on a foreign window.
2054 window_remove_filters (window);
2060 if (window->parent->children)
2061 window->parent->children = g_list_remove (window->parent->children, window);
2064 GDK_WINDOW_IS_MAPPED (window))
2066 recompute_visible_regions (window, TRUE, FALSE);
2067 gdk_window_invalidate_in_parent (window);
2071 if (window->frame_clock)
2073 g_object_run_dispose (G_OBJECT (window->frame_clock));
2074 gdk_window_set_frame_clock (window, NULL);
2077 gdk_window_free_paint_stack (window);
2079 if (window->background)
2081 cairo_pattern_destroy (window->background);
2082 window->background = NULL;
2085 if (window->window_type == GDK_WINDOW_FOREIGN)
2086 g_assert (window->children == NULL);
2089 children = tmp = window->children;
2090 window->children = NULL;
2094 temp_window = tmp->data;
2098 _gdk_window_destroy_hierarchy (temp_window,
2100 recursing_native || gdk_window_has_impl (window),
2104 g_list_free (children);
2107 _gdk_window_clear_update_area (window);
2109 gdk_window_drop_cairo_surface (window);
2111 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
2113 if (gdk_window_has_impl (window))
2114 impl_class->destroy (window, recursing_native,
2118 /* hide to make sure we repaint and break grabs */
2119 gdk_window_hide (window);
2122 window->state |= GDK_WINDOW_STATE_WITHDRAWN;
2123 window->parent = NULL;
2124 window->destroyed = TRUE;
2126 window_remove_filters (window);
2128 window_remove_from_pointer_info (window, display);
2130 if (window->clip_region)
2132 cairo_region_destroy (window->clip_region);
2133 window->clip_region = NULL;
2136 if (window->clip_region_with_children)
2138 cairo_region_destroy (window->clip_region_with_children);
2139 window->clip_region_with_children = NULL;
2142 g_list_free_full (window->outstanding_moves, (GDestroyNotify) gdk_window_region_move_free);
2143 window->outstanding_moves = NULL;
2150 * _gdk_window_destroy:
2151 * @window: a #GdkWindow
2152 * @foreign_destroy: If TRUE, the window or a parent was destroyed by some
2153 * external agency. The window has already been destroyed and no
2154 * windowing system calls should be made. (This may never happen
2155 * for some windowing systems.)
2157 * Internal function to destroy a window. Like gdk_window_destroy(),
2158 * but does not drop the reference count created by gdk_window_new().
2161 _gdk_window_destroy (GdkWindow *window,
2162 gboolean foreign_destroy)
2164 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, foreign_destroy);
2168 * gdk_window_destroy:
2169 * @window: a #GdkWindow
2171 * Destroys the window system resources associated with @window and decrements @window's
2172 * reference count. The window system resources for all children of @window are also
2173 * destroyed, but the children's reference counts are not decremented.
2175 * Note that a window will not be destroyed automatically when its reference count
2176 * reaches zero. You must call this function yourself before that happens.
2180 gdk_window_destroy (GdkWindow *window)
2182 _gdk_window_destroy_hierarchy (window, FALSE, FALSE, FALSE);
2183 g_object_unref (window);
2187 * gdk_window_set_user_data:
2188 * @window: a #GdkWindow
2189 * @user_data: (allow-none) (type GObject.Object): user data
2191 * For most purposes this function is deprecated in favor of
2192 * g_object_set_data(). However, for historical reasons GTK+ stores
2193 * the #GtkWidget that owns a #GdkWindow as user data on the
2194 * #GdkWindow. So, custom widget implementations should use
2195 * this function for that. If GTK+ receives an event for a #GdkWindow,
2196 * and the user data for the window is non-%NULL, GTK+ will assume the
2197 * user data is a #GtkWidget, and forward the event to that widget.
2201 gdk_window_set_user_data (GdkWindow *window,
2204 g_return_if_fail (GDK_IS_WINDOW (window));
2206 window->user_data = user_data;
2210 * gdk_window_get_user_data:
2211 * @window: a #GdkWindow
2212 * @data: (out): return location for user data
2214 * Retrieves the user data for @window, which is normally the widget
2215 * that @window belongs to. See gdk_window_set_user_data().
2219 gdk_window_get_user_data (GdkWindow *window,
2222 g_return_if_fail (GDK_IS_WINDOW (window));
2224 *data = window->user_data;
2228 * gdk_window_get_window_type:
2229 * @window: a #GdkWindow
2231 * Gets the type of the window. See #GdkWindowType.
2233 * Return value: type of window
2236 gdk_window_get_window_type (GdkWindow *window)
2238 g_return_val_if_fail (GDK_IS_WINDOW (window), (GdkWindowType) -1);
2240 return GDK_WINDOW_TYPE (window);
2244 * gdk_window_get_visual:
2245 * @window: a #GdkWindow
2247 * Gets the #GdkVisual describing the pixel format of @window.
2249 * Return value: (transfer none): a #GdkVisual
2254 gdk_window_get_visual (GdkWindow *window)
2256 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2258 return window->visual;
2262 * gdk_window_get_screen:
2263 * @window: a #GdkWindow
2265 * Gets the #GdkScreen associated with a #GdkWindow.
2267 * Return value: (transfer none): the #GdkScreen associated with @window
2272 gdk_window_get_screen (GdkWindow *window)
2274 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2276 return gdk_visual_get_screen (window->visual);
2280 * gdk_window_get_display:
2281 * @window: a #GdkWindow
2283 * Gets the #GdkDisplay associated with a #GdkWindow.
2285 * Return value: (transfer none): the #GdkDisplay associated with @window
2290 gdk_window_get_display (GdkWindow *window)
2292 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2294 return gdk_screen_get_display (gdk_visual_get_screen (window->visual));
2297 * gdk_window_is_destroyed:
2298 * @window: a #GdkWindow
2300 * Check to see if a window is destroyed..
2302 * Return value: %TRUE if the window is destroyed
2307 gdk_window_is_destroyed (GdkWindow *window)
2309 return GDK_WINDOW_DESTROYED (window);
2313 to_embedder (GdkWindow *window,
2314 gdouble offscreen_x,
2315 gdouble offscreen_y,
2316 gdouble *embedder_x,
2317 gdouble *embedder_y)
2319 g_signal_emit (window, signals[TO_EMBEDDER], 0,
2320 offscreen_x, offscreen_y,
2321 embedder_x, embedder_y);
2325 from_embedder (GdkWindow *window,
2328 gdouble *offscreen_x,
2329 gdouble *offscreen_y)
2331 g_signal_emit (window, signals[FROM_EMBEDDER], 0,
2332 embedder_x, embedder_y,
2333 offscreen_x, offscreen_y);
2337 * gdk_window_has_native:
2338 * @window: a #GdkWindow
2340 * Checks whether the window has a native window or not. Note that
2341 * you can use gdk_window_ensure_native() if a native window is needed.
2343 * Returns: %TRUE if the %window has a native window, %FALSE otherwise.
2348 gdk_window_has_native (GdkWindow *window)
2350 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2352 return window->parent == NULL || window->parent->impl != window->impl;
2356 * gdk_window_get_position:
2357 * @window: a #GdkWindow
2358 * @x: (out) (allow-none): X coordinate of window
2359 * @y: (out) (allow-none): Y coordinate of window
2361 * Obtains the position of the window as reported in the
2362 * most-recently-processed #GdkEventConfigure. Contrast with
2363 * gdk_window_get_geometry() which queries the X server for the
2364 * current window position, regardless of which events have been
2365 * received or processed.
2367 * The position coordinates are relative to the window's parent window.
2371 gdk_window_get_position (GdkWindow *window,
2375 g_return_if_fail (GDK_IS_WINDOW (window));
2384 * gdk_window_get_parent:
2385 * @window: a #GdkWindow
2387 * Obtains the parent of @window, as known to GDK. Does not query the
2388 * X server; thus this returns the parent as passed to gdk_window_new(),
2389 * not the actual parent. This should never matter unless you're using
2390 * Xlib calls mixed with GDK calls on the X11 platform. It may also
2391 * matter for toplevel windows, because the window manager may choose
2394 * Note that you should use gdk_window_get_effective_parent() when
2395 * writing generic code that walks up a window hierarchy, because
2396 * gdk_window_get_parent() will most likely not do what you expect if
2397 * there are offscreen windows in the hierarchy.
2399 * Return value: (transfer none): parent of @window
2402 gdk_window_get_parent (GdkWindow *window)
2404 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2406 return window->parent;
2410 * gdk_window_get_effective_parent:
2411 * @window: a #GdkWindow
2413 * Obtains the parent of @window, as known to GDK. Works like
2414 * gdk_window_get_parent() for normal windows, but returns the
2415 * window's embedder for offscreen windows.
2417 * See also: gdk_offscreen_window_get_embedder()
2419 * Return value: (transfer none): effective parent of @window
2424 gdk_window_get_effective_parent (GdkWindow *window)
2426 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2428 if (gdk_window_is_offscreen (window))
2429 return gdk_offscreen_window_get_embedder (window);
2431 return window->parent;
2435 * gdk_window_get_toplevel:
2436 * @window: a #GdkWindow
2438 * Gets the toplevel window that's an ancestor of @window.
2440 * Any window type but %GDK_WINDOW_CHILD is considered a
2441 * toplevel window, as is a %GDK_WINDOW_CHILD window that
2442 * has a root window as parent.
2444 * Note that you should use gdk_window_get_effective_toplevel() when
2445 * you want to get to a window's toplevel as seen on screen, because
2446 * gdk_window_get_toplevel() will most likely not do what you expect
2447 * if there are offscreen windows in the hierarchy.
2449 * Return value: (transfer none): the toplevel window containing @window
2452 gdk_window_get_toplevel (GdkWindow *window)
2454 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2456 while (window->window_type == GDK_WINDOW_CHILD)
2458 if (gdk_window_is_toplevel (window))
2460 window = window->parent;
2467 * gdk_window_get_effective_toplevel:
2468 * @window: a #GdkWindow
2470 * Gets the toplevel window that's an ancestor of @window.
2472 * Works like gdk_window_get_toplevel(), but treats an offscreen window's
2473 * embedder as its parent, using gdk_window_get_effective_parent().
2475 * See also: gdk_offscreen_window_get_embedder()
2477 * Return value: (transfer none): the effective toplevel window containing @window
2482 gdk_window_get_effective_toplevel (GdkWindow *window)
2486 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2488 while ((parent = gdk_window_get_effective_parent (window)) != NULL &&
2489 (gdk_window_get_window_type (parent) != GDK_WINDOW_ROOT))
2496 * gdk_window_get_children:
2497 * @window: a #GdkWindow
2499 * Gets the list of children of @window known to GDK.
2500 * This function only returns children created via GDK,
2501 * so for example it's useless when used with the root window;
2502 * it only returns windows an application created itself.
2504 * The returned list must be freed, but the elements in the
2507 * Return value: (transfer container) (element-type GdkWindow):
2508 * list of child windows inside @window
2511 gdk_window_get_children (GdkWindow *window)
2513 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2515 if (GDK_WINDOW_DESTROYED (window))
2518 return g_list_copy (window->children);
2522 * gdk_window_peek_children:
2523 * @window: a #GdkWindow
2525 * Like gdk_window_get_children(), but does not copy the list of
2526 * children, so the list does not need to be freed.
2528 * Return value: (transfer none) (element-type GdkWindow):
2529 * a reference to the list of child windows in @window
2532 gdk_window_peek_children (GdkWindow *window)
2534 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2536 if (GDK_WINDOW_DESTROYED (window))
2539 return window->children;
2543 * gdk_window_add_filter: (skip)
2544 * @window: (allow-none): a #GdkWindow
2545 * @function: filter callback
2546 * @data: data to pass to filter callback
2548 * Adds an event filter to @window, allowing you to intercept events
2549 * before they reach GDK. This is a low-level operation and makes it
2550 * easy to break GDK and/or GTK+, so you have to know what you're
2551 * doing. Pass %NULL for @window to get all events for all windows,
2552 * instead of events for a specific window.
2554 * If you are interested in X GenericEvents, bear in mind that
2555 * XGetEventData() has been already called on the event, and
2556 * XFreeEventData() must not be called within @function.
2559 gdk_window_add_filter (GdkWindow *window,
2560 GdkFilterFunc function,
2564 GdkEventFilter *filter;
2566 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2568 if (window && GDK_WINDOW_DESTROYED (window))
2571 /* Filters are for the native events on the native window, so
2572 ensure there is a native window. */
2574 gdk_window_ensure_native (window);
2577 tmp_list = window->filters;
2579 tmp_list = _gdk_default_filters;
2583 filter = (GdkEventFilter *)tmp_list->data;
2584 if ((filter->function == function) && (filter->data == data))
2586 filter->ref_count++;
2589 tmp_list = tmp_list->next;
2592 filter = g_new (GdkEventFilter, 1);
2593 filter->function = function;
2594 filter->data = data;
2595 filter->ref_count = 1;
2599 window->filters = g_list_append (window->filters, filter);
2601 _gdk_default_filters = g_list_append (_gdk_default_filters, filter);
2605 * gdk_window_remove_filter: (skip)
2606 * @window: a #GdkWindow
2607 * @function: previously-added filter function
2608 * @data: user data for previously-added filter function
2610 * Remove a filter previously added with gdk_window_add_filter().
2613 gdk_window_remove_filter (GdkWindow *window,
2614 GdkFilterFunc function,
2618 GdkEventFilter *filter;
2620 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2623 tmp_list = window->filters;
2625 tmp_list = _gdk_default_filters;
2629 filter = (GdkEventFilter *)tmp_list->data;
2630 tmp_list = tmp_list->next;
2632 if ((filter->function == function) && (filter->data == data))
2634 filter->flags |= GDK_EVENT_FILTER_REMOVED;
2636 _gdk_event_filter_unref (window, filter);
2644 * gdk_screen_get_toplevel_windows:
2645 * @screen: The #GdkScreen where the toplevels are located.
2647 * Obtains a list of all toplevel windows known to GDK on the screen @screen.
2648 * A toplevel window is a child of the root window (see
2649 * gdk_get_default_root_window()).
2651 * The returned list should be freed with g_list_free(), but
2652 * its elements need not be freed.
2654 * Return value: (transfer container) (element-type GdkWindow):
2655 * list of toplevel windows, free with g_list_free()
2660 gdk_screen_get_toplevel_windows (GdkScreen *screen)
2662 GdkWindow * root_window;
2663 GList *new_list = NULL;
2666 g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
2668 root_window = gdk_screen_get_root_window (screen);
2670 tmp_list = root_window->children;
2673 GdkWindow *w = tmp_list->data;
2675 if (w->window_type != GDK_WINDOW_FOREIGN)
2676 new_list = g_list_prepend (new_list, w);
2677 tmp_list = tmp_list->next;
2684 * gdk_window_is_visible:
2685 * @window: a #GdkWindow
2687 * Checks whether the window has been mapped (with gdk_window_show() or
2688 * gdk_window_show_unraised()).
2690 * Return value: %TRUE if the window is mapped
2693 gdk_window_is_visible (GdkWindow *window)
2695 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2697 return GDK_WINDOW_IS_MAPPED (window);
2701 * gdk_window_is_viewable:
2702 * @window: a #GdkWindow
2704 * Check if the window and all ancestors of the window are
2705 * mapped. (This is not necessarily "viewable" in the X sense, since
2706 * we only check as far as we have GDK window parents, not to the root
2709 * Return value: %TRUE if the window is viewable
2712 gdk_window_is_viewable (GdkWindow *window)
2714 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2716 if (window->destroyed)
2719 return window->viewable;
2723 * gdk_window_get_state:
2724 * @window: a #GdkWindow
2726 * Gets the bitwise OR of the currently active window state flags,
2727 * from the #GdkWindowState enumeration.
2729 * Return value: window state bitfield
2732 gdk_window_get_state (GdkWindow *window)
2734 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2736 return window->state;
2739 static cairo_content_t
2740 gdk_window_get_content (GdkWindow *window)
2742 cairo_surface_t *surface;
2743 cairo_content_t content;
2745 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2747 surface = gdk_window_ref_impl_surface (window);
2748 content = cairo_surface_get_content (surface);
2749 cairo_surface_destroy (surface);
2754 /* This creates an empty "implicit" paint region for the impl window.
2755 * By itself this does nothing, but real paints to this window
2756 * or children of it can use this surface as backing to avoid allocating
2757 * multiple surfaces for subwindow rendering. When doing so they
2758 * add to the region of the implicit paint region, which will be
2759 * pushed to the window when the implicit paint region is ended.
2760 * Such paints should not copy anything to the window on paint end, but
2761 * should rely on the implicit paint end.
2762 * The implicit paint will be automatically ended if someone draws
2763 * directly to the window or a child window.
2766 gdk_window_begin_implicit_paint (GdkWindow *window, GdkRectangle *rect,
2767 gboolean with_alpha, guint8 alpha)
2769 GdkWindowPaint *paint;
2771 g_assert (gdk_window_has_impl (window));
2773 if (GDK_IS_PAINTABLE (window->impl))
2774 return FALSE; /* Implementation does double buffering */
2776 if (window->paint_stack != NULL)
2777 return FALSE; /* Don't stack implicit paints */
2779 /* Never do implicit paints for foreign windows, they don't need
2780 * double buffer combination since they have no client side children,
2781 * and creating surfaces for them is risky since they could disappear
2784 if (window->window_type == GDK_WINDOW_FOREIGN)
2787 paint = g_new (GdkWindowPaint, 1);
2788 paint->region = cairo_region_create (); /* Empty */
2789 paint->uses_implicit = FALSE;
2790 paint->flushed = NULL;
2791 paint->alpha = alpha;
2792 paint->surface = gdk_window_create_similar_surface (window,
2793 with_alpha ? CAIRO_CONTENT_COLOR_ALPHA : gdk_window_get_content (window),
2794 MAX (rect->width, 1),
2795 MAX (rect->height, 1));
2796 cairo_surface_set_device_offset (paint->surface, -rect->x, -rect->y);
2798 window->implicit_paint = g_slist_prepend (window->implicit_paint, paint);
2803 static cairo_surface_t *
2804 gdk_window_ref_impl_surface (GdkWindow *window)
2806 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->ref_cairo_surface (gdk_window_get_impl_window (window));
2810 gdk_cairo_create_for_impl (GdkWindow *window)
2812 cairo_surface_t *surface;
2815 surface = gdk_window_ref_impl_surface (window);
2816 cr = cairo_create (surface);
2818 cairo_surface_destroy (surface);
2823 /* This is called whenever something is drawing directly to the
2824 * window, bypassing the double buffering. When this happens we
2825 * need to mark any the currently drawn data in the double buffer
2826 * as invalid to avoid later drawing it back over the directly
2827 * rendered pixels. We also need to mark this region as "flushed"
2828 * so that if we later try to paint on it double-buffered we need
2829 * to read back the on-window pixels rather than relying on what
2830 * is in the current double-buffer pixmap.
2832 * Note that this doesn't correctly handle the case where the
2833 * non-double buffered drawing uses transparency and relies on
2834 * what the windows below it draws. A fix for that would require
2835 * drawing the existing double-buffered background to the window,
2836 * but that causes ugly flashes. Non-double buffered drawing is
2837 * typically only used in old code or when the drawed widget
2838 * already has a double-buffering layer, and in these cases the
2839 * pixels are opaque anyway. If you need transparency, don't
2840 * disable double buffering.
2843 gdk_window_flush_implicit_paint (GdkWindow *window)
2845 GdkWindow *impl_window;
2846 GdkWindowPaint *paint;
2847 cairo_region_t *region;
2850 impl_window = gdk_window_get_impl_window (window);
2851 if (impl_window->implicit_paint == NULL)
2854 /* There is no proper way to flush any non-toplevel implicit
2855 paint, because direct rendering is not compatible with
2856 opacity rendering, as it requires an opacity group.
2858 We warn and flush just the outermost paint in this case.
2860 l = g_slist_last (impl_window->implicit_paint);
2861 if (l != impl_window->implicit_paint)
2862 g_warning ("Non double buffered drawing not supported inside transparent windows");
2866 region = cairo_region_copy (window->clip_region_with_children);
2867 cairo_region_translate (region, window->abs_x, window->abs_y);
2869 /* Anything in the whole flushed window that was drawn is now
2870 considered unpainted, so that we don't push it back at the
2871 end of the implicit paint overwriting the directly rendered
2873 cairo_region_subtract (paint->region, region);
2875 /* Save flushed area so we can read it back if we draw over it later */
2876 if (paint->flushed == NULL)
2877 paint->flushed = region;
2880 cairo_region_union (paint->flushed, region);
2881 cairo_region_destroy (region);
2885 /* Ends an implicit paint, paired with gdk_window_begin_implicit_paint returning TRUE */
2887 gdk_window_end_implicit_paint (GdkWindow *window)
2889 GdkWindowPaint *paint;
2891 g_assert (gdk_window_has_impl (window));
2893 g_assert (window->implicit_paint != NULL);
2895 paint = window->implicit_paint->data;
2897 window->implicit_paint = g_slist_delete_link (window->implicit_paint,
2898 window->implicit_paint);
2900 if (!GDK_WINDOW_DESTROYED (window) && !cairo_region_is_empty (paint->region) && paint->alpha > 0)
2902 GdkWindowPaint *parent_paint = NULL;
2905 /* Some regions are valid, push these to window now */
2906 if (window->implicit_paint)
2908 parent_paint = window->implicit_paint->data;
2910 /* If the toplevel implicit paint was flushed, restore it now
2911 before we blend over it. */
2912 if (parent_paint->flushed != NULL &&
2913 !cairo_region_is_empty (parent_paint->flushed))
2915 cairo_surface_t *source_surface = gdk_window_ref_impl_surface (window);
2916 cairo_region_t *flushed = cairo_region_copy (parent_paint->flushed);
2918 cr = cairo_create (parent_paint->surface);
2919 cairo_set_source_surface (cr, source_surface, 0, 0);
2920 cairo_surface_destroy (source_surface);
2922 cairo_region_intersect (flushed, paint->region);
2923 gdk_cairo_region (cr, flushed);
2926 cairo_region_subtract (parent_paint->flushed, flushed);
2927 cairo_region_destroy (flushed);
2933 cr = cairo_create (parent_paint->surface);
2936 cr = gdk_cairo_create_for_impl (window);
2938 gdk_cairo_region (cr, paint->region);
2940 cairo_set_source_surface (cr, paint->surface, 0, 0);
2941 if (paint->alpha == 255)
2943 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
2948 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
2949 cairo_paint_with_alpha (cr, paint->alpha / 255.0);
2955 cairo_region_union (parent_paint->region, paint->region);
2958 cairo_region_destroy (paint->region);
2960 cairo_region_destroy (paint->flushed);
2961 cairo_surface_destroy (paint->surface);
2966 * gdk_window_begin_paint_rect:
2967 * @window: a #GdkWindow
2968 * @rectangle: rectangle you intend to draw to
2970 * A convenience wrapper around gdk_window_begin_paint_region() which
2971 * creates a rectangular region for you. See
2972 * gdk_window_begin_paint_region() for details.
2976 gdk_window_begin_paint_rect (GdkWindow *window,
2977 const GdkRectangle *rectangle)
2979 cairo_region_t *region;
2981 g_return_if_fail (GDK_IS_WINDOW (window));
2983 region = cairo_region_create_rectangle (rectangle);
2984 gdk_window_begin_paint_region (window, region);
2985 cairo_region_destroy (region);
2989 * gdk_window_begin_paint_region:
2990 * @window: a #GdkWindow
2991 * @region: region you intend to draw to
2993 * Indicates that you are beginning the process of redrawing @region.
2994 * A backing store (offscreen buffer) large enough to contain @region
2995 * will be created. The backing store will be initialized with the
2996 * background color or background surface for @window. Then, all
2997 * drawing operations performed on @window will be diverted to the
2998 * backing store. When you call gdk_window_end_paint(), the backing
2999 * store will be copied to @window, making it visible onscreen. Only
3000 * the part of @window contained in @region will be modified; that is,
3001 * drawing operations are clipped to @region.
3003 * The net result of all this is to remove flicker, because the user
3004 * sees the finished product appear all at once when you call
3005 * gdk_window_end_paint(). If you draw to @window directly without
3006 * calling gdk_window_begin_paint_region(), the user may see flicker
3007 * as individual drawing operations are performed in sequence. The
3008 * clipping and background-initializing features of
3009 * gdk_window_begin_paint_region() are conveniences for the
3010 * programmer, so you can avoid doing that work yourself.
3012 * When using GTK+, the widget system automatically places calls to
3013 * gdk_window_begin_paint_region() and gdk_window_end_paint() around
3014 * emissions of the expose_event signal. That is, if you're writing an
3015 * expose event handler, you can assume that the exposed area in
3016 * #GdkEventExpose has already been cleared to the window background,
3017 * is already set as the clip region, and already has a backing store.
3018 * Therefore in most cases, application code need not call
3019 * gdk_window_begin_paint_region(). (You can disable the automatic
3020 * calls around expose events on a widget-by-widget basis by calling
3021 * gtk_widget_set_double_buffered().)
3023 * If you call this function multiple times before calling the
3024 * matching gdk_window_end_paint(), the backing stores are pushed onto
3025 * a stack. gdk_window_end_paint() copies the topmost backing store
3026 * onscreen, subtracts the topmost region from all other regions in
3027 * the stack, and pops the stack. All drawing operations affect only
3028 * the topmost backing store in the stack. One matching call to
3029 * gdk_window_end_paint() is required for each call to
3030 * gdk_window_begin_paint_region().
3034 gdk_window_begin_paint_region (GdkWindow *window,
3035 const cairo_region_t *region)
3037 #ifdef USE_BACKING_STORE
3038 GdkRectangle clip_box;
3039 GdkWindowPaint *paint, *implicit_paint;
3040 GdkWindow *impl_window;
3043 g_return_if_fail (GDK_IS_WINDOW (window));
3045 if (GDK_WINDOW_DESTROYED (window))
3048 if (GDK_IS_PAINTABLE (window->impl))
3050 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
3052 if (iface->begin_paint_region)
3053 iface->begin_paint_region ((GdkPaintable*)window->impl, window, region);
3058 impl_window = gdk_window_get_impl_window (window);
3059 implicit_paint = impl_window->implicit_paint != NULL ? impl_window->implicit_paint->data : NULL;
3061 paint = g_new (GdkWindowPaint, 1);
3062 paint->region = cairo_region_copy (region);
3064 cairo_region_intersect (paint->region, window->clip_region_with_children);
3065 cairo_region_get_extents (paint->region, &clip_box);
3067 cairo_region_translate (paint->region, window->abs_x, window->abs_y);
3069 /* Mark the region as valid on the implicit paint */
3072 cairo_region_union (implicit_paint->region, paint->region);
3074 /* Convert back to normal coords */
3075 cairo_region_translate (paint->region, -window->abs_x, -window->abs_y);
3079 paint->uses_implicit = TRUE;
3080 paint->surface = cairo_surface_create_for_rectangle (implicit_paint->surface,
3081 window->abs_x + clip_box.x,
3082 window->abs_y + clip_box.y,
3083 MAX (clip_box.width, 1),
3084 MAX (clip_box.height, 1));
3088 paint->uses_implicit = FALSE;
3089 paint->surface = gdk_window_create_similar_surface (window,
3090 gdk_window_get_content (window),
3091 MAX (clip_box.width, 1),
3092 MAX (clip_box.height, 1));
3095 /* Normally alpha backgrounded client side windows are composited on the implicit paint
3096 by being drawn in back to front order. However, if implicit paints are not used, for
3097 instance if it was flushed due to a non-double-buffered paint in the middle of the
3098 expose we need to copy in the existing data here. */
3099 if (gdk_window_has_alpha (window) &&
3101 (implicit_paint && implicit_paint->flushed != NULL && !cairo_region_is_empty (implicit_paint->flushed))))
3103 cairo_t *cr = cairo_create (paint->surface);
3104 /* We can't use gdk_cairo_set_source_window here, as that might
3105 flush the implicit paint at an unfortunate time, since this
3106 would be detected as a draw during non-expose time */
3107 cairo_surface_t *source_surface = gdk_window_ref_impl_surface (impl_window);
3108 cairo_set_source_surface (cr, source_surface,
3109 - (window->abs_x + clip_box.x),
3110 - (window->abs_y + clip_box.y));
3111 cairo_surface_destroy (source_surface);
3113 /* Only read back the flushed area if any */
3116 cairo_region_t *flushed = cairo_region_copy (implicit_paint->flushed);
3117 /* Convert from impl coords */
3118 cairo_region_translate (flushed, -window->abs_x, -window->abs_y);
3119 cairo_region_intersect (flushed, paint->region);
3120 gdk_cairo_region (cr, flushed);
3123 /* Convert to impl coords */
3124 cairo_region_translate (flushed, window->abs_x, window->abs_y);
3125 cairo_region_subtract (implicit_paint->flushed, flushed);
3126 cairo_region_destroy (flushed);
3132 cairo_surface_set_device_offset (paint->surface, -clip_box.x, -clip_box.y);
3134 for (list = window->paint_stack; list != NULL; list = list->next)
3136 GdkWindowPaint *tmp_paint = list->data;
3138 cairo_region_subtract (tmp_paint->region, paint->region);
3141 window->paint_stack = g_slist_prepend (window->paint_stack, paint);
3143 if (!cairo_region_is_empty (paint->region))
3145 gdk_window_clear_backing_region (window,
3149 #endif /* USE_BACKING_STORE */
3153 * gdk_window_end_paint:
3154 * @window: a #GdkWindow
3156 * Indicates that the backing store created by the most recent call to
3157 * gdk_window_begin_paint_region() should be copied onscreen and
3158 * deleted, leaving the next-most-recent backing store or no backing
3159 * store at all as the active paint region. See
3160 * gdk_window_begin_paint_region() for full details. It is an error to
3161 * call this function without a matching
3162 * gdk_window_begin_paint_region() first.
3166 gdk_window_end_paint (GdkWindow *window)
3168 #ifdef USE_BACKING_STORE
3169 GdkWindow *composited;
3170 GdkWindowPaint *paint;
3171 GdkRectangle clip_box;
3172 cairo_region_t *full_clip;
3174 g_return_if_fail (GDK_IS_WINDOW (window));
3176 if (GDK_WINDOW_DESTROYED (window))
3179 if (GDK_IS_PAINTABLE (window->impl))
3181 GdkPaintableIface *iface = GDK_PAINTABLE_GET_IFACE (window->impl);
3183 if (iface->end_paint)
3184 iface->end_paint ((GdkPaintable*)window->impl);
3188 if (window->paint_stack == NULL)
3190 g_warning (G_STRLOC": no preceding call to gdk_window_begin_paint_region(), see documentation");
3194 paint = window->paint_stack->data;
3196 window->paint_stack = g_slist_delete_link (window->paint_stack,
3197 window->paint_stack);
3199 cairo_region_get_extents (paint->region, &clip_box);
3201 if (!paint->uses_implicit)
3205 gdk_window_flush_outstanding_moves (window);
3207 full_clip = cairo_region_copy (window->clip_region_with_children);
3208 cairo_region_intersect (full_clip, paint->region);
3210 cr = gdk_cairo_create (window);
3211 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
3212 cairo_set_source_surface (cr, paint->surface, 0, 0);
3213 gdk_cairo_region (cr, full_clip);
3217 cairo_region_destroy (full_clip);
3220 cairo_surface_destroy (paint->surface);
3221 cairo_region_destroy (paint->region);
3224 /* find a composited window in our hierarchy to signal its
3225 * parent to redraw, calculating the clip box as we go...
3227 * stop if parent becomes NULL since then we'd have nowhere
3228 * to draw (ie: 'composited' will always be non-NULL here).
3230 for (composited = window;
3232 composited = composited->parent)
3234 clip_box.x += composited->x;
3235 clip_box.y += composited->y;
3236 clip_box.width = MIN (clip_box.width, composited->parent->width - clip_box.x);
3237 clip_box.height = MIN (clip_box.height, composited->parent->height - clip_box.y);
3239 if (composited->composited)
3241 gdk_window_invalidate_rect (GDK_WINDOW (composited->parent),
3246 #endif /* USE_BACKING_STORE */
3250 gdk_window_free_paint_stack (GdkWindow *window)
3252 if (window->paint_stack)
3254 GSList *tmp_list = window->paint_stack;
3258 GdkWindowPaint *paint = tmp_list->data;
3260 if (tmp_list == window->paint_stack)
3261 cairo_surface_destroy (paint->surface);
3263 cairo_region_destroy (paint->region);
3266 tmp_list = tmp_list->next;
3269 g_slist_free (window->paint_stack);
3270 window->paint_stack = NULL;
3275 do_move_region_bits_on_impl (GdkWindow *impl_window,
3276 cairo_region_t *dest_region, /* In impl window coords */
3279 GdkWindowImplClass *impl_class;
3281 impl_class = GDK_WINDOW_IMPL_GET_CLASS (impl_window->impl);
3283 impl_class->translate (impl_window, dest_region, dx, dy);
3286 static GdkWindowRegionMove *
3287 gdk_window_region_move_new (cairo_region_t *region,
3290 GdkWindowRegionMove *move;
3292 move = g_slice_new (GdkWindowRegionMove);
3293 move->dest_region = cairo_region_copy (region);
3301 gdk_window_region_move_free (GdkWindowRegionMove *move)
3303 cairo_region_destroy (move->dest_region);
3304 g_slice_free (GdkWindowRegionMove, move);
3308 append_move_region (GdkWindow *impl_window,
3309 cairo_region_t *new_dest_region,
3312 GdkWindowRegionMove *move, *old_move;
3313 cairo_region_t *new_total_region, *old_total_region;
3314 cairo_region_t *source_overlaps_destination;
3315 cairo_region_t *non_overwritten;
3316 gboolean added_move;
3319 if (cairo_region_is_empty (new_dest_region))
3322 /* In principle this could just append the move to the list of outstanding
3323 moves that will be replayed before drawing anything when we're handling
3324 exposes. However, we'd like to do a bit better since its commonly the case
3325 that we get multiple copies where A is copied to B and then B is copied
3326 to C, and we'd like to express this as a simple copy A to C operation. */
3328 /* We approach this by taking the new move and pushing it ahead of moves
3329 starting at the end of the list and stopping when its not safe to do so.
3330 It's not safe to push past a move if either the source of the new move
3331 is in the destination of the old move, or if the destination of the new
3332 move is in the source of the new move, or if the destination of the new
3333 move overlaps the destination of the old move. We simplify this by
3334 just comparing the total regions (src + dest) */
3335 new_total_region = cairo_region_copy (new_dest_region);
3336 cairo_region_translate (new_total_region, -dx, -dy);
3337 cairo_region_union (new_total_region, new_dest_region);
3340 for (l = g_list_last (impl_window->outstanding_moves); l != NULL; l = prev)
3345 old_total_region = cairo_region_copy (old_move->dest_region);
3346 cairo_region_translate (old_total_region, -old_move->dx, -old_move->dy);
3347 cairo_region_union (old_total_region, old_move->dest_region);
3349 cairo_region_intersect (old_total_region, new_total_region);
3350 /* If these regions intersect then its not safe to push the
3351 new region before the old one */
3352 if (!cairo_region_is_empty (old_total_region))
3354 /* The area where the new moves source overlaps the old ones
3356 source_overlaps_destination = cairo_region_copy (new_dest_region);
3357 cairo_region_translate (source_overlaps_destination, -dx, -dy);
3358 cairo_region_intersect (source_overlaps_destination, old_move->dest_region);
3359 cairo_region_translate (source_overlaps_destination, dx, dy);
3361 /* We can do all sort of optimizations here, but to do things safely it becomes
3362 quite complicated. However, a very common case is that you copy something first,
3363 then copy all that or a subset of it to a new location (i.e. if you scroll twice
3364 in the same direction). We'd like to detect this case and optimize it to one
3366 if (cairo_region_equal (source_overlaps_destination, new_dest_region))
3368 /* This means we might be able to replace the old move and the new one
3369 with the new one read from the old ones source, and a second copy of
3370 the non-overwritten parts of the old move. However, such a split
3371 is only valid if the source in the old move isn't overwritten
3372 by the destination of the new one */
3374 /* the new destination of old move if split is ok: */
3375 non_overwritten = cairo_region_copy (old_move->dest_region);
3376 cairo_region_subtract (non_overwritten, new_dest_region);
3377 /* move to source region */
3378 cairo_region_translate (non_overwritten, -old_move->dx, -old_move->dy);
3380 cairo_region_intersect (non_overwritten, new_dest_region);
3381 if (cairo_region_is_empty (non_overwritten))
3384 move = gdk_window_region_move_new (new_dest_region,
3388 impl_window->outstanding_moves =
3389 g_list_insert_before (impl_window->outstanding_moves,
3391 cairo_region_subtract (old_move->dest_region, new_dest_region);
3393 cairo_region_destroy (non_overwritten);
3396 cairo_region_destroy (source_overlaps_destination);
3397 cairo_region_destroy (old_total_region);
3400 cairo_region_destroy (old_total_region);
3403 cairo_region_destroy (new_total_region);
3407 move = gdk_window_region_move_new (new_dest_region, dx, dy);
3410 impl_window->outstanding_moves =
3411 g_list_prepend (impl_window->outstanding_moves,
3414 impl_window->outstanding_moves =
3415 g_list_insert_before (impl_window->outstanding_moves,
3420 /* Moves bits and update area by dx/dy in impl window.
3421 Takes ownership of region to avoid copy (because we may change it) */
3423 move_region_on_impl (GdkWindow *impl_window,
3424 cairo_region_t *region, /* In impl window coords */
3429 if ((dx == 0 && dy == 0) ||
3430 cairo_region_is_empty (region))
3432 cairo_region_destroy (region);
3436 g_assert (impl_window == gdk_window_get_impl_window (impl_window));
3438 /* Move any old invalid regions in the copy source area by dx/dy */
3439 if (impl_window->update_area)
3441 cairo_region_t *update_area;
3443 update_area = cairo_region_copy (region);
3445 /* Convert from target to source */
3446 cairo_region_translate (update_area, -dx, -dy);
3447 cairo_region_intersect (update_area, impl_window->update_area);
3448 /* We only copy the area, so keep the old update area invalid.
3449 It would be safe to remove it too, as code that uses
3450 move_region_on_impl generally also invalidate the source
3451 area. However, it would just use waste cycles. */
3454 cairo_region_translate (update_area, dx, dy);
3455 cairo_region_union (impl_window->update_area, update_area);
3457 /* This area of the destination is now invalid,
3458 so no need to copy to it. */
3459 cairo_region_subtract (region, update_area);
3461 cairo_region_destroy (update_area);
3464 /* If we're currently exposing this window, don't copy to this
3465 destination, as it will be overdrawn when the expose is done,
3466 instead invalidate it and repaint later. */
3467 for (l = impl_window->implicit_paint; l != NULL; l = l->next)
3469 GdkWindowPaint *implicit_paint = l->data;
3470 cairo_region_t *exposing;
3472 exposing = cairo_region_copy (implicit_paint->region);
3473 cairo_region_intersect (exposing, region);
3474 cairo_region_subtract (region, exposing);
3476 impl_window_add_update_area (impl_window, exposing);
3477 cairo_region_destroy (exposing);
3480 append_move_region (impl_window, region, dx, dy);
3482 cairo_region_destroy (region);
3485 /* Flushes all outstanding changes to the window, call this
3486 * before drawing directly to the window (i.e. outside a begin/end_paint pair).
3489 gdk_window_flush_outstanding_moves (GdkWindow *window)
3491 GdkWindow *impl_window;
3492 GList *l, *outstanding;
3493 GdkWindowRegionMove *move;
3495 impl_window = gdk_window_get_impl_window (window);
3496 outstanding = impl_window->outstanding_moves;
3497 impl_window->outstanding_moves = NULL;
3499 for (l = outstanding; l != NULL; l = l->next)
3503 do_move_region_bits_on_impl (impl_window,
3504 move->dest_region, move->dx, move->dy);
3506 gdk_window_region_move_free (move);
3509 g_list_free (outstanding);
3514 * @window: a #GdkWindow
3516 * Flush all outstanding cached operations on a window, leaving the
3517 * window in a state which reflects all that has been drawn before.
3519 * Gdk uses multiple kinds of caching to get better performance and
3520 * nicer drawing. For instance, during exposes all paints to a window
3521 * using double buffered rendering are keep on a surface until the last
3522 * window has been exposed. It also delays window moves/scrolls until
3523 * as long as possible until next update to avoid tearing when moving
3526 * Normally this should be completely invisible to applications, as
3527 * we automatically flush the windows when required, but this might
3528 * be needed if you for instance mix direct native drawing with
3529 * gdk drawing. For Gtk widgets that don't use double buffering this
3530 * will be called automatically before sending the expose event.
3535 gdk_window_flush (GdkWindow *window)
3537 gdk_window_flush_outstanding_moves (window);
3538 gdk_window_flush_implicit_paint (window);
3542 gdk_window_flush_recursive_helper (GdkWindow *window,
3543 GdkWindowImpl *impl)
3548 for (l = window->children; l != NULL; l = l->next)
3552 if (child->impl == impl)
3553 /* Same impl, ignore */
3554 gdk_window_flush_recursive_helper (child, impl);
3556 gdk_window_flush_recursive (child);
3561 gdk_window_flush_recursive (GdkWindow *window)
3563 gdk_window_flush (window);
3564 gdk_window_flush_recursive_helper (window, window->impl);
3568 * gdk_window_get_clip_region:
3569 * @window: a #GdkWindow
3571 * Computes the region of a window that potentially can be written
3572 * to by drawing primitives. This region may not take into account
3573 * other factors such as if the window is obscured by other windows,
3574 * but no area outside of this region will be affected by drawing
3577 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3578 * when you are done.
3581 gdk_window_get_clip_region (GdkWindow *window)
3583 cairo_region_t *result;
3585 g_return_val_if_fail (GDK_WINDOW (window), NULL);
3587 result = cairo_region_copy (window->clip_region);
3589 if (window->paint_stack)
3591 cairo_region_t *paint_region = cairo_region_create ();
3592 GSList *tmp_list = window->paint_stack;
3596 GdkWindowPaint *paint = tmp_list->data;
3598 cairo_region_union (paint_region, paint->region);
3600 tmp_list = tmp_list->next;
3603 cairo_region_intersect (result, paint_region);
3604 cairo_region_destroy (paint_region);
3611 * gdk_window_get_visible_region:
3612 * @window: a #GdkWindow
3614 * Computes the region of the @window that is potentially visible.
3615 * This does not necessarily take into account if the window is
3616 * obscured by other windows, but no area outside of this region
3619 * Returns: a #cairo_region_t. This must be freed with cairo_region_destroy()
3620 * when you are done.
3623 gdk_window_get_visible_region (GdkWindow *window)
3625 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3627 return cairo_region_copy (window->clip_region);
3631 setup_backing_rect (GdkWindow *window, GdkWindowPaint *paint)
3633 GdkWindow *bg_window;
3634 cairo_pattern_t *pattern = NULL;
3635 int x_offset = 0, y_offset = 0;
3638 cr = cairo_create (paint->surface);
3640 for (bg_window = window; bg_window; bg_window = bg_window->parent)
3642 pattern = gdk_window_get_background_pattern (bg_window);
3646 x_offset += bg_window->x;
3647 y_offset += bg_window->y;
3652 cairo_translate (cr, -x_offset, -y_offset);
3653 cairo_set_source (cr, pattern);
3654 cairo_translate (cr, x_offset, y_offset);
3657 cairo_set_source_rgb (cr, 0, 0, 0);
3663 gdk_window_clear_backing_region (GdkWindow *window,
3664 cairo_region_t *region)
3666 GdkWindowPaint *paint = window->paint_stack->data;
3667 cairo_region_t *clip;
3670 if (GDK_WINDOW_DESTROYED (window))
3673 cr = setup_backing_rect (window, paint);
3675 clip = cairo_region_copy (paint->region);
3676 cairo_region_intersect (clip, region);
3678 gdk_cairo_region (cr, clip);
3683 cairo_region_destroy (clip);
3687 gdk_window_drop_cairo_surface (GdkWindow *window)
3689 if (window->cairo_surface)
3691 cairo_surface_finish (window->cairo_surface);
3692 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3694 window->cairo_surface = NULL;
3699 gdk_window_cairo_surface_destroy (void *data)
3701 GdkWindow *window = data;
3703 window->cairo_surface = NULL;
3706 static cairo_surface_t *
3707 gdk_window_create_cairo_surface (GdkWindow *window,
3711 cairo_surface_t *surface, *subsurface;
3713 surface = gdk_window_ref_impl_surface (window);
3714 if (gdk_window_has_impl (window))
3717 subsurface = cairo_surface_create_for_rectangle (surface,
3722 cairo_surface_destroy (surface);
3728 _gdk_window_ref_cairo_surface (GdkWindow *window)
3730 cairo_surface_t *surface;
3732 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3734 if (window->paint_stack)
3736 GdkWindowPaint *paint = window->paint_stack->data;
3738 surface = paint->surface;
3739 cairo_surface_reference (surface);
3744 /* This will be drawing directly to the window, so flush implicit paint */
3745 gdk_window_flush (window);
3747 if (!window->cairo_surface)
3749 window->cairo_surface = gdk_window_create_cairo_surface (window,
3753 if (window->cairo_surface)
3755 cairo_surface_set_user_data (window->cairo_surface, &gdk_window_cairo_key,
3756 window, gdk_window_cairo_surface_destroy);
3760 cairo_surface_reference (window->cairo_surface);
3762 surface = window->cairo_surface;
3770 * @window: a #GdkWindow
3772 * Creates a Cairo context for drawing to @window.
3775 * Note that calling cairo_reset_clip() on the resulting #cairo_t will
3776 * produce undefined results, so avoid it at all costs.
3779 * Return value: A newly created Cairo context. Free with
3780 * cairo_destroy() when you are done drawing.
3785 gdk_cairo_create (GdkWindow *window)
3787 cairo_surface_t *surface;
3790 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3792 surface = _gdk_window_ref_cairo_surface (window);
3793 cr = cairo_create (surface);
3795 if (!window->paint_stack)
3797 gdk_cairo_region (cr, window->clip_region_with_children);
3802 GdkWindowPaint *paint = window->paint_stack->data;
3804 /* Only needs to clip to region if piggybacking
3805 on an implicit paint */
3806 if (paint->uses_implicit)
3808 gdk_cairo_region (cr, paint->region);
3813 cairo_surface_destroy (surface);
3818 /* Code for dirty-region queueing
3820 static GSList *update_windows = NULL;
3821 static gboolean debug_updates = FALSE;
3823 static inline gboolean
3824 gdk_window_is_ancestor (GdkWindow *window,
3825 GdkWindow *ancestor)
3829 GdkWindow *parent = window->parent;
3831 if (parent == ancestor)
3841 gdk_window_add_update_window (GdkWindow *window)
3844 GSList *prev = NULL;
3845 gboolean has_ancestor_in_list = FALSE;
3847 for (tmp = update_windows; tmp; tmp = tmp->next)
3849 GdkWindow *parent = window->parent;
3851 /* check if tmp is an ancestor of "window"; if it is, set a
3852 * flag indicating that all following windows are either
3853 * children of "window" or from a differen hierarchy
3855 if (!has_ancestor_in_list && gdk_window_is_ancestor (window, tmp->data))
3856 has_ancestor_in_list = TRUE;
3858 /* insert in reverse stacking order when adding around siblings,
3859 * so processing updates properly paints over lower stacked windows
3861 if (parent == GDK_WINDOW (tmp->data)->parent)
3863 gint index = g_list_index (parent->children, window);
3864 for (; tmp && parent == GDK_WINDOW (tmp->data)->parent; tmp = tmp->next)
3866 gint sibling_index = g_list_index (parent->children, tmp->data);
3867 if (index > sibling_index)
3871 /* here, tmp got advanced past all lower stacked siblings */
3872 tmp = g_slist_prepend (tmp, window);
3876 update_windows = tmp;
3880 /* if "window" has an ancestor in the list and tmp is one of
3881 * "window's" children, insert "window" before tmp
3883 if (has_ancestor_in_list && gdk_window_is_ancestor (tmp->data, window))
3885 tmp = g_slist_prepend (tmp, window);
3890 update_windows = tmp;
3894 /* if we're at the end of the list and had an ancestor it it,
3895 * append to the list
3897 if (! tmp->next && has_ancestor_in_list)
3899 tmp = g_slist_append (tmp, window);
3906 /* if all above checks failed ("window" is from a different
3907 * hierarchy than what is already in the list) or the list is
3910 update_windows = g_slist_prepend (update_windows, window);
3914 gdk_window_remove_update_window (GdkWindow *window)
3916 update_windows = g_slist_remove (update_windows, window);
3920 gdk_window_is_toplevel_frozen (GdkWindow *window)
3922 GdkWindow *toplevel;
3924 toplevel = gdk_window_get_toplevel (window);
3926 return toplevel->update_and_descendants_freeze_count > 0;
3930 gdk_window_schedule_update (GdkWindow *window)
3932 GdkFrameClock *frame_clock;
3935 (window->update_freeze_count ||
3936 gdk_window_is_toplevel_frozen (window)))
3939 /* If there's no frame clock (a foreign window), then the invalid
3940 * region will just stick around unless gdk_window_process_updates()
3942 frame_clock = gdk_window_get_frame_clock (window);
3944 gdk_frame_clock_request_phase (gdk_window_get_frame_clock (window),
3945 GDK_FRAME_CLOCK_PHASE_PAINT);
3949 _gdk_window_process_updates_recurse (GdkWindow *window,
3950 cairo_region_t *expose_region)
3953 cairo_region_t *clipped_expose_region;
3954 GdkRectangle clip_box;
3955 GList *l, *children;
3956 gboolean end_implicit;
3958 if (cairo_region_is_empty (expose_region))
3961 if (gdk_window_is_offscreen (window->impl_window) &&
3962 gdk_window_has_impl (window))
3963 _gdk_window_add_damage ((GdkWindow *) window->impl_window, expose_region);
3965 end_implicit = FALSE;
3966 if (window->alpha != 255 && !gdk_window_has_impl (window))
3968 if (window->alpha == 0)
3971 cairo_region_get_extents (expose_region, &clip_box);
3972 clip_box.x += window->abs_x;
3973 clip_box.y += window->abs_y;
3974 end_implicit = gdk_window_begin_implicit_paint (window->impl_window, &clip_box, TRUE, window->alpha);
3977 /* Paint the window before the children, clipped to the window region
3978 with visible child windows removed */
3979 clipped_expose_region = cairo_region_copy (expose_region);
3980 cairo_region_intersect (clipped_expose_region, window->clip_region_with_children);
3982 if (!cairo_region_is_empty (clipped_expose_region) &&
3985 if (window->event_mask & GDK_EXPOSURE_MASK)
3989 event.expose.type = GDK_EXPOSE;
3990 event.expose.window = g_object_ref (window);
3991 event.expose.send_event = FALSE;
3992 event.expose.count = 0;
3993 event.expose.region = clipped_expose_region;
3994 cairo_region_get_extents (clipped_expose_region, &event.expose.area);
3996 _gdk_event_emit (&event);
3998 g_object_unref (window);
4000 else if (window->window_type != GDK_WINDOW_FOREIGN)
4002 /* No exposure mask set, so nothing will be drawn, the
4003 * app relies on the background being what it specified
4004 * for the window. So, we need to clear this manually.
4006 * For foreign windows if expose is not set that generally
4007 * means some other client paints them, so don't clear
4010 * We use begin/end_paint around the clear so that we can
4011 * piggyback on the implicit paint */
4013 gdk_window_begin_paint_region (window, clipped_expose_region);
4014 /* The actual clear happens in begin_paint_region */
4015 gdk_window_end_paint (window);
4018 cairo_region_destroy (clipped_expose_region);
4020 /* Make this reentrancy safe for expose handlers freeing windows */
4021 children = g_list_copy (window->children);
4022 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4024 /* Iterate over children, starting at bottommost */
4025 for (l = g_list_last (children); l != NULL; l = l->prev)
4029 if (child->destroyed || !GDK_WINDOW_IS_MAPPED (child) || child->input_only || child->composited)
4032 /* Ignore offscreen children, as they don't draw in their parent and
4033 * don't take part in the clipping */
4034 if (gdk_window_is_offscreen (child))
4037 /* Client side child, expose */
4038 if (child->impl == window->impl)
4040 cairo_region_translate (expose_region, -child->x, -child->y);
4041 _gdk_window_process_updates_recurse ((GdkWindow *)child, expose_region);
4042 cairo_region_translate (expose_region, child->x, child->y);
4046 g_list_free_full (children, g_object_unref);
4049 gdk_window_end_implicit_paint (window->impl_window);
4052 /* Process and remove any invalid area on the native window by creating
4053 * expose events for the window and all non-native descendants.
4054 * Also processes any outstanding moves on the window before doing
4055 * any drawing. Note that its possible to have outstanding moves without
4056 * any invalid area as we use the update idle mechanism to coalesce
4057 * multiple moves as well as multiple invalidations.
4060 gdk_window_process_updates_internal (GdkWindow *window)
4062 GdkWindowImplClass *impl_class;
4063 gboolean save_region = FALSE;
4064 GdkRectangle clip_box;
4066 /* Ensure the window lives while updating it */
4067 g_object_ref (window);
4069 /* If an update got queued during update processing, we can get a
4070 * window in the update queue that has an empty update_area.
4073 if (window->update_area)
4075 cairo_region_t *update_area = window->update_area;
4076 window->update_area = NULL;
4078 if (gdk_window_is_viewable (window))
4080 cairo_region_t *expose_region;
4081 gboolean end_implicit;
4083 /* Clip to part visible in toplevel */
4084 cairo_region_intersect (update_area, window->clip_region);
4088 /* Make sure we see the red invalid area before redrawing. */
4089 gdk_display_sync (gdk_window_get_display (window));
4093 /* At this point we will be completely redrawing all of update_area.
4094 * If we have any outstanding moves that end up moving stuff inside
4095 * this area we don't actually need to move that as that part would
4096 * be overdrawn by the expose anyway. So, in order to copy less data
4097 * we remove these areas from the outstanding moves.
4099 if (window->outstanding_moves)
4101 GdkWindowRegionMove *move;
4102 cairo_region_t *remove;
4105 remove = cairo_region_copy (update_area);
4106 /* We iterate backwards, starting from the state that would be
4107 if we had applied all the moves. */
4108 for (l = g_list_last (window->outstanding_moves); l != NULL; l = prev)
4113 /* Don't need this area */
4114 cairo_region_subtract (move->dest_region, remove);
4116 /* However if any of the destination we do need has a source
4117 in the updated region we do need that as a destination for
4118 the earlier moves */
4119 cairo_region_translate (move->dest_region, -move->dx, -move->dy);
4120 cairo_region_subtract (remove, move->dest_region);
4122 if (cairo_region_is_empty (move->dest_region))
4124 gdk_window_region_move_free (move);
4125 window->outstanding_moves =
4126 g_list_delete_link (window->outstanding_moves, l);
4128 else /* move back */
4129 cairo_region_translate (move->dest_region, move->dx, move->dy);
4131 cairo_region_destroy (remove);
4134 /* By now we a set of window moves that should be applied, and then
4135 * an update region that should be repainted. A trivial implementation
4136 * would just do that in order, however in order to get nicer drawing
4137 * we do some tricks:
4139 * First of all, each subwindow expose may be double buffered by
4140 * itself (depending on widget setting) via
4141 * gdk_window_begin/end_paint(). But we also do an "implicit" paint,
4142 * creating a single surface the size of the invalid area on the
4143 * native window which all the individual normal paints will draw
4144 * into. This way in the normal case there will be only one surface
4145 * allocated and only once surface draw done for all the windows
4146 * in this native window.
4147 * There are a couple of reasons this may fail, for instance, some
4148 * backends (like quartz) do its own double buffering, so we disable
4149 * gdk double buffering there. Secondly, some subwindow could be
4150 * non-double buffered and draw directly to the window outside a
4151 * begin/end_paint pair. That will be lead to a gdk_window_flush
4152 * which immediately executes all outstanding moves and paints+removes
4153 * the implicit paint (further paints will allocate their own surfaces).
4155 * Secondly, in the case of implicit double buffering we expose all
4156 * the child windows into the implicit surface before we execute
4157 * the outstanding moves. This way we minimize the time between
4158 * doing the moves and rendering the new update area, thus minimizing
4159 * flashing. Of course, if any subwindow is non-double buffered we
4160 * well flush earlier than that.
4162 * Thirdly, after having done the outstanding moves we queue an
4163 * "antiexpose" on the area that will be drawn by the expose, which
4164 * means that any invalid region on the native window side before
4165 * the first expose drawing operation will be discarded, as it
4166 * has by then been overdrawn with valid data. This means we can
4167 * avoid doing the unnecessary repaint any outstanding expose events.
4170 cairo_region_get_extents (update_area, &clip_box);
4171 end_implicit = gdk_window_begin_implicit_paint (window, &clip_box, FALSE, 255);
4172 expose_region = cairo_region_copy (update_area);
4173 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
4176 /* Rendering is not double buffered by gdk, do outstanding
4177 * moves and queue antiexposure immediately. No need to do
4179 gdk_window_flush_outstanding_moves (window);
4180 save_region = impl_class->queue_antiexpose (window, update_area);
4182 /* Render the invalid areas to the implicit paint, by sending exposes.
4183 * May flush if non-double buffered widget draw. */
4184 impl_class->process_updates_recurse (window, expose_region);
4188 /* Do moves right before exposes are rendered to the window */
4189 gdk_window_flush_outstanding_moves (window);
4191 /* By this time we know that any outstanding expose for this
4192 * area is invalid and we can avoid it, so queue an antiexpose.
4193 * we have already started drawing to the window, so it would
4194 * be to late to anti-expose now. Since this is merely an
4195 * optimization we just avoid doing it at all in that case.
4197 if (window->implicit_paint != NULL && !((GdkWindowPaint *)window->implicit_paint->data)->flushed)
4198 save_region = impl_class->queue_antiexpose (window, update_area);
4200 gdk_window_end_implicit_paint (window);
4202 cairo_region_destroy (expose_region);
4205 cairo_region_destroy (update_area);
4208 if (window->outstanding_moves)
4210 /* Flush any outstanding moves, may happen if we moved a window but got
4211 no actual invalid area */
4212 gdk_window_flush_outstanding_moves (window);
4215 g_object_unref (window);
4219 flush_all_displays (void)
4221 GSList *displays, *l;
4223 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4224 for (l = displays; l; l = l->next)
4225 gdk_display_flush (l->data);
4227 g_slist_free (displays);
4231 before_process_all_updates (void)
4233 GSList *displays, *l;
4234 GdkDisplayClass *display_class;
4236 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4237 display_class = GDK_DISPLAY_GET_CLASS (displays->data);
4238 for (l = displays; l; l = l->next)
4239 display_class->before_process_all_updates (l->data);
4241 g_slist_free (displays);
4245 after_process_all_updates (void)
4247 GSList *displays, *l;
4248 GdkDisplayClass *display_class;
4250 displays = gdk_display_manager_list_displays (gdk_display_manager_get ());
4251 display_class = GDK_DISPLAY_GET_CLASS (displays->data);
4252 for (l = displays; l; l = l->next)
4253 display_class->after_process_all_updates (l->data);
4255 g_slist_free (displays);
4258 /* Currently it is not possible to override
4259 * gdk_window_process_all_updates in the same manner as
4260 * gdk_window_process_updates and gdk_window_invalidate_maybe_recurse
4261 * by implementing the GdkPaintable interface. If in the future a
4262 * backend would need this, the right solution would be to add a
4263 * method to GdkDisplay that can be optionally
4264 * NULL. gdk_window_process_all_updates can then walk the list of open
4265 * displays and call the mehod.
4269 * gdk_window_process_all_updates:
4271 * Calls gdk_window_process_updates() for all windows (see #GdkWindow)
4272 * in the application.
4276 gdk_window_process_all_updates (void)
4278 GSList *old_update_windows = update_windows;
4279 GSList *tmp_list = update_windows;
4280 static gboolean in_process_all_updates = FALSE;
4281 static gboolean got_recursive_update = FALSE;
4283 if (in_process_all_updates)
4285 /* We can't do this now since that would recurse, so
4286 delay it until after the recursion is done. */
4287 got_recursive_update = TRUE;
4291 in_process_all_updates = TRUE;
4292 got_recursive_update = FALSE;
4294 update_windows = NULL;
4296 before_process_all_updates ();
4298 g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
4302 GdkWindow *window = tmp_list->data;
4304 if (!GDK_WINDOW_DESTROYED (window))
4306 if (window->update_freeze_count ||
4307 gdk_window_is_toplevel_frozen (window))
4308 gdk_window_add_update_window (window);
4310 gdk_window_process_updates_internal (window);
4313 g_object_unref (window);
4314 tmp_list = tmp_list->next;
4317 g_slist_free (old_update_windows);
4319 flush_all_displays ();
4321 after_process_all_updates ();
4323 in_process_all_updates = FALSE;
4325 /* If we ignored a recursive call, schedule a
4326 redraw now so that it eventually happens,
4327 otherwise we could miss an update if nothing
4328 else schedules an update. */
4329 if (got_recursive_update)
4330 gdk_window_schedule_update (NULL);
4335 PROCESS_UPDATES_NO_RECURSE,
4336 PROCESS_UPDATES_WITH_ALL_CHILDREN,
4337 PROCESS_UPDATES_WITH_SAME_CLOCK_CHILDREN
4341 gdk_window_process_updates_with_mode (GdkWindow *window,
4344 GdkWindow *impl_window;
4346 g_return_if_fail (GDK_IS_WINDOW (window));
4348 if (GDK_WINDOW_DESTROYED (window))
4351 /* Make sure the window lives during the expose callouts */
4352 g_object_ref (window);
4354 impl_window = gdk_window_get_impl_window (window);
4355 if ((impl_window->update_area ||
4356 impl_window->outstanding_moves) &&
4357 !impl_window->update_freeze_count &&
4358 !gdk_window_is_toplevel_frozen (window) &&
4360 /* Don't recurse into process_updates_internal, we'll
4361 * do the update later when idle instead. */
4362 impl_window->implicit_paint == NULL)
4364 gdk_window_process_updates_internal ((GdkWindow *)impl_window);
4365 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4368 if (recurse_mode != PROCESS_UPDATES_NO_RECURSE)
4370 /* process updates in reverse stacking order so composition or
4371 * painting over achieves the desired effect for offscreen windows
4373 GList *node, *children;
4375 children = g_list_copy (window->children);
4376 g_list_foreach (children, (GFunc)g_object_ref, NULL);
4378 for (node = g_list_last (children); node; node = node->prev)
4380 GdkWindow *child = node->data;
4381 if (recurse_mode == PROCESS_UPDATES_WITH_ALL_CHILDREN ||
4382 (recurse_mode == PROCESS_UPDATES_WITH_SAME_CLOCK_CHILDREN &&
4383 child->frame_clock == NULL))
4385 gdk_window_process_updates (child, TRUE);
4387 g_object_unref (child);
4390 g_list_free (children);
4393 g_object_unref (window);
4397 * gdk_window_process_updates:
4398 * @window: a #GdkWindow
4399 * @update_children: whether to also process updates for child windows
4401 * Sends one or more expose events to @window. The areas in each
4402 * expose event will cover the entire update area for the window (see
4403 * gdk_window_invalidate_region() for details). Normally GDK calls
4404 * gdk_window_process_all_updates() on your behalf, so there's no
4405 * need to call this function unless you want to force expose events
4406 * to be delivered immediately and synchronously (vs. the usual
4407 * case, where GDK delivers them in an idle handler). Occasionally
4408 * this is useful to produce nicer scrolling behavior, for example.
4412 gdk_window_process_updates (GdkWindow *window,
4413 gboolean update_children)
4415 g_return_if_fail (GDK_IS_WINDOW (window));
4417 return gdk_window_process_updates_with_mode (window,
4419 PROCESS_UPDATES_WITH_ALL_CHILDREN :
4420 PROCESS_UPDATES_NO_RECURSE);
4424 gdk_window_invalidate_rect_full (GdkWindow *window,
4425 const GdkRectangle *rect,
4426 gboolean invalidate_children,
4429 GdkRectangle window_rect;
4430 cairo_region_t *region;
4432 g_return_if_fail (GDK_IS_WINDOW (window));
4434 if (GDK_WINDOW_DESTROYED (window))
4437 if (window->input_only || !window->viewable)
4444 window_rect.width = window->width;
4445 window_rect.height = window->height;
4446 rect = &window_rect;
4449 region = cairo_region_create_rectangle (rect);
4450 gdk_window_invalidate_region_full (window, region, invalidate_children, clear_bg);
4451 cairo_region_destroy (region);
4455 * gdk_window_invalidate_rect:
4456 * @window: a #GdkWindow
4457 * @rect: (allow-none): rectangle to invalidate or %NULL to invalidate the whole
4459 * @invalidate_children: whether to also invalidate child windows
4461 * A convenience wrapper around gdk_window_invalidate_region() which
4462 * invalidates a rectangular region. See
4463 * gdk_window_invalidate_region() for details.
4466 gdk_window_invalidate_rect (GdkWindow *window,
4467 const GdkRectangle *rect,
4468 gboolean invalidate_children)
4470 gdk_window_invalidate_rect_full (window, rect, invalidate_children, CLEAR_BG_NONE);
4474 draw_ugly_color (GdkWindow *window,
4475 const cairo_region_t *region)
4479 cr = gdk_cairo_create (window);
4480 /* Draw ugly color all over the newly-invalid region */
4481 cairo_set_source_rgb (cr, 50000/65535., 10000/65535., 10000/65535.);
4482 gdk_cairo_region (cr, region);
4489 impl_window_add_update_area (GdkWindow *impl_window,
4490 cairo_region_t *region)
4492 if (impl_window->update_area)
4493 cairo_region_union (impl_window->update_area, region);
4496 gdk_window_add_update_window (impl_window);
4497 impl_window->update_area = cairo_region_copy (region);
4498 gdk_window_schedule_update (impl_window);
4502 /* clear_bg controls if the region will be cleared to
4503 * the background pattern if the exposure mask is not
4504 * set for the window, whereas this might not otherwise be
4505 * done (unless necessary to emulate background settings).
4506 * Set this to CLEAR_BG_WINCLEARED or CLEAR_BG_ALL if you
4507 * need to clear the background, such as when exposing the area beneath a
4508 * hidden or moved window, but not when an app requests repaint or when the
4509 * windowing system exposes a newly visible area (because then the windowing
4510 * system has already cleared the area).
4513 gdk_window_invalidate_maybe_recurse_full (GdkWindow *window,
4514 const cairo_region_t *region,
4516 GdkWindowChildFunc child_func,
4519 GdkWindow *impl_window;
4520 cairo_region_t *visible_region;
4523 g_return_if_fail (GDK_IS_WINDOW (window));
4525 if (GDK_WINDOW_DESTROYED (window))
4528 if (window->input_only ||
4529 !window->viewable ||
4530 cairo_region_is_empty (region) ||
4531 window->window_type == GDK_WINDOW_ROOT)
4534 visible_region = gdk_window_get_visible_region (window);
4535 cairo_region_intersect (visible_region, region);
4537 tmp_list = window->children;
4540 GdkWindow *child = tmp_list->data;
4542 if (!child->input_only)
4544 cairo_region_t *child_region;
4545 GdkRectangle child_rect;
4547 child_rect.x = child->x;
4548 child_rect.y = child->y;
4549 child_rect.width = child->width;
4550 child_rect.height = child->height;
4551 child_region = cairo_region_create_rectangle (&child_rect);
4553 /* remove child area from the invalid area of the parent */
4554 if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped &&
4555 !child->composited &&
4556 !gdk_window_is_offscreen (child))
4557 cairo_region_subtract (visible_region, child_region);
4559 if (child_func && (*child_func) ((GdkWindow *)child, user_data))
4561 cairo_region_t *tmp = cairo_region_copy (region);
4563 cairo_region_translate (tmp, - child_rect.x, - child_rect.y);
4564 cairo_region_translate (child_region, - child_rect.x, - child_rect.y);
4565 cairo_region_intersect (child_region, tmp);
4567 gdk_window_invalidate_maybe_recurse_full ((GdkWindow *)child,
4568 child_region, clear_bg, child_func, user_data);
4570 cairo_region_destroy (tmp);
4573 cairo_region_destroy (child_region);
4576 tmp_list = tmp_list->next;
4579 impl_window = gdk_window_get_impl_window (window);
4581 if (!cairo_region_is_empty (visible_region) ||
4582 /* Even if we're not exposing anything, make sure we process
4583 idles for windows with outstanding moves */
4584 (impl_window->outstanding_moves != NULL &&
4585 impl_window->update_area == NULL))
4588 draw_ugly_color (window, region);
4590 /* Convert to impl coords */
4591 cairo_region_translate (visible_region, window->abs_x, window->abs_y);
4593 /* Only invalidate area if app requested expose events or if
4594 we need to clear the area (by request or to emulate background
4595 clearing for non-native windows or native windows with no support
4596 for window backgrounds */
4597 if (window->event_mask & GDK_EXPOSURE_MASK ||
4598 clear_bg == CLEAR_BG_ALL ||
4599 clear_bg == CLEAR_BG_WINCLEARED)
4600 impl_window_add_update_area (impl_window, visible_region);
4603 cairo_region_destroy (visible_region);
4607 * gdk_window_invalidate_maybe_recurse:
4608 * @window: a #GdkWindow
4609 * @region: a #cairo_region_t
4610 * @child_func: (scope call) (allow-none): function to use to decide if to
4611 * recurse to a child, %NULL means never recurse.
4612 * @user_data: data passed to @child_func
4614 * Adds @region to the update area for @window. The update area is the
4615 * region that needs to be redrawn, or "dirty region." The call
4616 * gdk_window_process_updates() sends one or more expose events to the
4617 * window, which together cover the entire update area. An
4618 * application would normally redraw the contents of @window in
4619 * response to those expose events.
4621 * GDK will call gdk_window_process_all_updates() on your behalf
4622 * whenever your program returns to the main loop and becomes idle, so
4623 * normally there's no need to do that manually, you just need to
4624 * invalidate regions that you know should be redrawn.
4626 * The @child_func parameter controls whether the region of
4627 * each child window that intersects @region will also be invalidated.
4628 * Only children for which @child_func returns TRUE will have the area
4632 gdk_window_invalidate_maybe_recurse (GdkWindow *window,
4633 const cairo_region_t *region,
4634 GdkWindowChildFunc child_func,
4637 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_NONE,
4638 child_func, user_data);
4642 true_predicate (GdkWindow *window,
4649 gdk_window_invalidate_region_full (GdkWindow *window,
4650 const cairo_region_t *region,
4651 gboolean invalidate_children,
4654 gdk_window_invalidate_maybe_recurse_full (window, region, clear_bg,
4655 invalidate_children ?
4656 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4661 * gdk_window_invalidate_region:
4662 * @window: a #GdkWindow
4663 * @region: a #cairo_region_t
4664 * @invalidate_children: %TRUE to also invalidate child windows
4666 * Adds @region to the update area for @window. The update area is the
4667 * region that needs to be redrawn, or "dirty region." The call
4668 * gdk_window_process_updates() sends one or more expose events to the
4669 * window, which together cover the entire update area. An
4670 * application would normally redraw the contents of @window in
4671 * response to those expose events.
4673 * GDK will call gdk_window_process_all_updates() on your behalf
4674 * whenever your program returns to the main loop and becomes idle, so
4675 * normally there's no need to do that manually, you just need to
4676 * invalidate regions that you know should be redrawn.
4678 * The @invalidate_children parameter controls whether the region of
4679 * each child window that intersects @region will also be invalidated.
4680 * If %FALSE, then the update area for child windows will remain
4681 * unaffected. See gdk_window_invalidate_maybe_recurse if you need
4682 * fine grained control over which children are invalidated.
4685 gdk_window_invalidate_region (GdkWindow *window,
4686 const cairo_region_t *region,
4687 gboolean invalidate_children)
4689 gdk_window_invalidate_maybe_recurse (window, region,
4690 invalidate_children ?
4691 true_predicate : (gboolean (*) (GdkWindow *, gpointer))NULL,
4696 * _gdk_window_invalidate_for_expose:
4697 * @window: a #GdkWindow
4698 * @region: a #cairo_region_t
4700 * Adds @region to the update area for @window. The update area is the
4701 * region that needs to be redrawn, or "dirty region." The call
4702 * gdk_window_process_updates() sends one or more expose events to the
4703 * window, which together cover the entire update area. An
4704 * application would normally redraw the contents of @window in
4705 * response to those expose events.
4707 * GDK will call gdk_window_process_all_updates() on your behalf
4708 * whenever your program returns to the main loop and becomes idle, so
4709 * normally there's no need to do that manually, you just need to
4710 * invalidate regions that you know should be redrawn.
4712 * This version of invalidation is used when you recieve expose events
4713 * from the native window system. It exposes the native window, plus
4714 * any non-native child windows (but not native child windows, as those would
4715 * have gotten their own expose events).
4718 _gdk_window_invalidate_for_expose (GdkWindow *window,
4719 cairo_region_t *region)
4721 GdkWindowRegionMove *move;
4722 cairo_region_t *move_region;
4725 /* Any invalidations comming from the windowing system will
4726 be in areas that may be moved by outstanding moves,
4727 so we need to modify the expose region correspondingly,
4728 otherwise we would expose in the wrong place, as the
4729 outstanding moves will be copied before we draw the
4731 for (l = window->outstanding_moves; l != NULL; l = l->next)
4735 /* covert to move source region */
4736 move_region = cairo_region_copy (move->dest_region);
4737 cairo_region_translate (move_region, -move->dx, -move->dy);
4739 /* Move area of region that intersects with move source
4740 by dx, dy of the move*/
4741 cairo_region_intersect (move_region, region);
4742 cairo_region_subtract (region, move_region);
4743 cairo_region_translate (move_region, move->dx, move->dy);
4744 cairo_region_union (region, move_region);
4746 cairo_region_destroy (move_region);
4749 gdk_window_invalidate_maybe_recurse_full (window, region, CLEAR_BG_WINCLEARED,
4750 (gboolean (*) (GdkWindow *, gpointer))gdk_window_has_no_impl,
4756 * gdk_window_get_update_area:
4757 * @window: a #GdkWindow
4759 * Transfers ownership of the update area from @window to the caller
4760 * of the function. That is, after calling this function, @window will
4761 * no longer have an invalid/dirty region; the update area is removed
4762 * from @window and handed to you. If a window has no update area,
4763 * gdk_window_get_update_area() returns %NULL. You are responsible for
4764 * calling cairo_region_destroy() on the returned region if it's non-%NULL.
4766 * Return value: the update area for @window
4769 gdk_window_get_update_area (GdkWindow *window)
4771 GdkWindow *impl_window;
4772 cairo_region_t *tmp_region, *to_remove;
4774 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4776 impl_window = gdk_window_get_impl_window (window);
4778 if (impl_window->update_area)
4780 tmp_region = cairo_region_copy (window->clip_region_with_children);
4781 /* Convert to impl coords */
4782 cairo_region_translate (tmp_region, window->abs_x, window->abs_y);
4783 cairo_region_intersect (tmp_region, impl_window->update_area);
4785 if (cairo_region_is_empty (tmp_region))
4787 cairo_region_destroy (tmp_region);
4792 /* Convert from impl coords */
4793 cairo_region_translate (tmp_region, -window->abs_x, -window->abs_y);
4795 /* Don't remove any update area that is overlapped by non-opaque windows
4796 (children or siblings) with alpha, as these really need to be repainted
4797 independently of this window. */
4798 to_remove = cairo_region_copy (tmp_region);
4799 cairo_region_subtract (to_remove, window->parent->layered_region);
4800 remove_layered_child_area (window, to_remove);
4802 /* Remove from update_area */
4803 cairo_region_translate (to_remove, window->abs_x, window->abs_y);
4804 cairo_region_subtract (impl_window->update_area, to_remove);
4806 cairo_region_destroy (to_remove);
4808 if (cairo_region_is_empty (impl_window->update_area) &&
4809 impl_window->outstanding_moves == NULL)
4811 cairo_region_destroy (impl_window->update_area);
4812 impl_window->update_area = NULL;
4814 gdk_window_remove_update_window ((GdkWindow *)impl_window);
4825 * _gdk_window_clear_update_area:
4826 * @window: a #GdkWindow.
4828 * Internal function to clear the update area for a window. This
4829 * is called when the window is hidden or destroyed.
4832 _gdk_window_clear_update_area (GdkWindow *window)
4834 g_return_if_fail (GDK_IS_WINDOW (window));
4836 if (window->update_area)
4838 gdk_window_remove_update_window (window);
4840 cairo_region_destroy (window->update_area);
4841 window->update_area = NULL;
4846 * gdk_window_freeze_updates:
4847 * @window: a #GdkWindow
4849 * Temporarily freezes a window such that it won't receive expose
4850 * events. The window will begin receiving expose events again when
4851 * gdk_window_thaw_updates() is called. If gdk_window_freeze_updates()
4852 * has been called more than once, gdk_window_thaw_updates() must be called
4853 * an equal number of times to begin processing exposes.
4856 gdk_window_freeze_updates (GdkWindow *window)
4858 GdkWindow *impl_window;
4860 g_return_if_fail (GDK_IS_WINDOW (window));
4862 impl_window = gdk_window_get_impl_window (window);
4863 impl_window->update_freeze_count++;
4867 * gdk_window_thaw_updates:
4868 * @window: a #GdkWindow
4870 * Thaws a window frozen with gdk_window_freeze_updates().
4873 gdk_window_thaw_updates (GdkWindow *window)
4875 GdkWindow *impl_window;
4877 g_return_if_fail (GDK_IS_WINDOW (window));
4879 impl_window = gdk_window_get_impl_window (window);
4881 g_return_if_fail (impl_window->update_freeze_count > 0);
4883 if (--impl_window->update_freeze_count == 0)
4884 gdk_window_schedule_update (GDK_WINDOW (impl_window));
4888 * gdk_window_freeze_toplevel_updates_libgtk_only:
4889 * @window: a #GdkWindow
4891 * Temporarily freezes a window and all its descendants such that it won't
4892 * receive expose events. The window will begin receiving expose events
4893 * again when gdk_window_thaw_toplevel_updates_libgtk_only() is called. If
4894 * gdk_window_freeze_toplevel_updates_libgtk_only()
4895 * has been called more than once,
4896 * gdk_window_thaw_toplevel_updates_libgtk_only() must be called
4897 * an equal number of times to begin processing exposes.
4899 * This function is not part of the GDK public API and is only
4903 gdk_window_freeze_toplevel_updates_libgtk_only (GdkWindow *window)
4905 g_return_if_fail (GDK_IS_WINDOW (window));
4906 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4908 window->update_and_descendants_freeze_count++;
4909 _gdk_frame_clock_freeze (gdk_window_get_frame_clock (window));
4913 * gdk_window_thaw_toplevel_updates_libgtk_only:
4914 * @window: a #GdkWindow
4916 * Thaws a window frozen with
4917 * gdk_window_freeze_toplevel_updates_libgtk_only().
4919 * This function is not part of the GDK public API and is only
4923 gdk_window_thaw_toplevel_updates_libgtk_only (GdkWindow *window)
4925 g_return_if_fail (GDK_IS_WINDOW (window));
4926 g_return_if_fail (window->window_type != GDK_WINDOW_CHILD);
4927 g_return_if_fail (window->update_and_descendants_freeze_count > 0);
4929 window->update_and_descendants_freeze_count--;
4930 _gdk_frame_clock_thaw (gdk_window_get_frame_clock (window));
4932 gdk_window_schedule_update (window);
4936 * gdk_window_set_debug_updates:
4937 * @setting: %TRUE to turn on update debugging
4939 * With update debugging enabled, calls to
4940 * gdk_window_invalidate_region() clear the invalidated region of the
4941 * screen to a noticeable color, and GDK pauses for a short time
4942 * before sending exposes to windows during
4943 * gdk_window_process_updates(). The net effect is that you can see
4944 * the invalid region for each window and watch redraws as they
4945 * occur. This allows you to diagnose inefficiencies in your application.
4947 * In essence, because the GDK rendering model prevents all flicker,
4948 * if you are redrawing the same region 400 times you may never
4949 * notice, aside from noticing a speed problem. Enabling update
4950 * debugging causes GTK to flicker slowly and noticeably, so you can
4951 * see exactly what's being redrawn when, in what order.
4953 * The --gtk-debug=updates command line option passed to GTK+ programs
4954 * enables this debug option at application startup time. That's
4955 * usually more useful than calling gdk_window_set_debug_updates()
4956 * yourself, though you might want to use this function to enable
4957 * updates sometime after application startup time.
4961 gdk_window_set_debug_updates (gboolean setting)
4963 debug_updates = setting;
4967 * gdk_window_constrain_size:
4968 * @geometry: a #GdkGeometry structure
4969 * @flags: a mask indicating what portions of @geometry are set
4970 * @width: desired width of window
4971 * @height: desired height of the window
4972 * @new_width: (out): location to store resulting width
4973 * @new_height: (out): location to store resulting height
4975 * Constrains a desired width and height according to a
4976 * set of geometry hints (such as minimum and maximum size).
4979 gdk_window_constrain_size (GdkGeometry *geometry,
4986 /* This routine is partially borrowed from fvwm.
4988 * Copyright 1993, Robert Nation
4989 * You may use this code for any purpose, as long as the original
4990 * copyright remains in the source code and all documentation
4992 * which in turn borrows parts of the algorithm from uwm
4995 gint min_height = 0;
4996 gint base_width = 0;
4997 gint base_height = 0;
5000 gint max_width = G_MAXINT;
5001 gint max_height = G_MAXINT;
5003 #define FLOOR(value, base) ( ((gint) ((value) / (base))) * (base) )
5005 if ((flags & GDK_HINT_BASE_SIZE) && (flags & GDK_HINT_MIN_SIZE))
5007 base_width = geometry->base_width;
5008 base_height = geometry->base_height;
5009 min_width = geometry->min_width;
5010 min_height = geometry->min_height;
5012 else if (flags & GDK_HINT_BASE_SIZE)
5014 base_width = geometry->base_width;
5015 base_height = geometry->base_height;
5016 min_width = geometry->base_width;
5017 min_height = geometry->base_height;
5019 else if (flags & GDK_HINT_MIN_SIZE)
5021 base_width = geometry->min_width;
5022 base_height = geometry->min_height;
5023 min_width = geometry->min_width;
5024 min_height = geometry->min_height;
5027 if (flags & GDK_HINT_MAX_SIZE)
5029 max_width = geometry->max_width ;
5030 max_height = geometry->max_height;
5033 if (flags & GDK_HINT_RESIZE_INC)
5035 xinc = MAX (xinc, geometry->width_inc);
5036 yinc = MAX (yinc, geometry->height_inc);
5039 /* clamp width and height to min and max values
5041 width = CLAMP (width, min_width, max_width);
5042 height = CLAMP (height, min_height, max_height);
5044 /* shrink to base + N * inc
5046 width = base_width + FLOOR (width - base_width, xinc);
5047 height = base_height + FLOOR (height - base_height, yinc);
5049 /* constrain aspect ratio, according to:
5052 * min_aspect <= -------- <= max_aspect
5056 if (flags & GDK_HINT_ASPECT &&
5057 geometry->min_aspect > 0 &&
5058 geometry->max_aspect > 0)
5062 if (geometry->min_aspect * height > width)
5064 delta = FLOOR (height - width / geometry->min_aspect, yinc);
5065 if (height - delta >= min_height)
5069 delta = FLOOR (height * geometry->min_aspect - width, xinc);
5070 if (width + delta <= max_width)
5075 if (geometry->max_aspect * height < width)
5077 delta = FLOOR (width - height * geometry->max_aspect, xinc);
5078 if (width - delta >= min_width)
5082 delta = FLOOR (width / geometry->max_aspect - height, yinc);
5083 if (height + delta <= max_height)
5092 *new_height = height;
5096 * gdk_window_get_pointer:
5097 * @window: a #GdkWindow
5098 * @x: (out) (allow-none): return location for X coordinate of pointer or %NULL to not
5099 * return the X coordinate
5100 * @y: (out) (allow-none): return location for Y coordinate of pointer or %NULL to not
5101 * return the Y coordinate
5102 * @mask: (out) (allow-none): return location for modifier mask or %NULL to not return the
5105 * Obtains the current pointer position and modifier state.
5106 * The position is given in coordinates relative to the upper left
5107 * corner of @window.
5109 * Return value: (transfer none): the window containing the pointer (as with
5110 * gdk_window_at_pointer()), or %NULL if the window containing the
5111 * pointer isn't known to GDK
5113 * Deprecated: 3.0: Use gdk_window_get_device_position() instead.
5116 gdk_window_get_pointer (GdkWindow *window,
5119 GdkModifierType *mask)
5121 GdkDisplay *display;
5123 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5125 display = gdk_window_get_display (window);
5127 return gdk_window_get_device_position (window, display->core_pointer, x, y, mask);
5131 * gdk_window_get_device_position:
5132 * @window: a #GdkWindow.
5133 * @device: pointer #GdkDevice to query to.
5134 * @x: (out) (allow-none): return location for the X coordinate of @device, or %NULL.
5135 * @y: (out) (allow-none): return location for the Y coordinate of @device, or %NULL.
5136 * @mask: (out) (allow-none): return location for the modifier mask, or %NULL.
5138 * Obtains the current device position and modifier state.
5139 * The position is given in coordinates relative to the upper left
5140 * corner of @window.
5142 * Return value: (transfer none): The window underneath @device (as with
5143 * gdk_device_get_window_at_position()), or %NULL if the window is not known to GDK.
5148 gdk_window_get_device_position (GdkWindow *window,
5152 GdkModifierType *mask)
5155 GdkModifierType tmp_mask;
5156 gboolean normal_child;
5158 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
5159 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
5160 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
5162 normal_child = GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_device_state (window,
5166 /* We got the coords on the impl, convert to the window */
5167 tmp_x -= window->abs_x;
5168 tmp_y -= window->abs_y;
5177 _gdk_display_enable_motion_hints (gdk_window_get_display (window), device);
5180 return _gdk_window_find_child_at (window, tmp_x, tmp_y);
5185 * gdk_get_default_root_window:
5187 * Obtains the root window (parent all other windows are inside)
5188 * for the default display and screen.
5190 * Return value: (transfer none): the default root window
5193 gdk_get_default_root_window (void)
5195 return gdk_screen_get_root_window (gdk_screen_get_default ());
5199 get_all_native_children (GdkWindow *window,
5205 for (l = window->children; l != NULL; l = l->next)
5209 if (gdk_window_has_impl (child))
5210 *native = g_list_prepend (*native, child);
5212 get_all_native_children (child, native);
5218 gdk_window_raise_internal (GdkWindow *window)
5220 GdkWindow *parent = window->parent;
5222 GList *native_children;
5224 GdkWindowImplClass *impl_class;
5228 parent->children = g_list_remove (parent->children, window);
5229 parent->children = g_list_prepend (parent->children, window);
5232 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5233 /* Just do native raise for toplevels */
5234 if (gdk_window_is_toplevel (window) ||
5235 /* The restack_under codepath should work correctly even if the parent
5236 is native, but it relies on the order of ->children to be correct,
5237 and some apps like SWT reorder the x windows without gdks knowledge,
5238 so we use raise directly in order to make these behave as before
5239 when using native windows */
5240 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5242 impl_class->raise (window);
5244 else if (gdk_window_has_impl (window))
5246 above = find_native_sibling_above (parent, window);
5249 listhead.data = window;
5250 listhead.next = NULL;
5251 listhead.prev = NULL;
5252 impl_class->restack_under ((GdkWindow *)above,
5256 impl_class->raise (window);
5260 native_children = NULL;
5261 get_all_native_children (window, &native_children);
5262 if (native_children != NULL)
5264 above = find_native_sibling_above (parent, window);
5267 impl_class->restack_under (above, native_children);
5270 /* Right order, since native_children is bottom-topmost first */
5271 for (l = native_children; l != NULL; l = l->next)
5272 impl_class->raise (l->data);
5275 g_list_free (native_children);
5281 /* Returns TRUE If the native window was mapped or unmapped */
5283 set_viewable (GdkWindow *w,
5287 GdkWindowImplClass *impl_class;
5290 if (w->viewable == val)
5296 recompute_visible_regions (w, FALSE, FALSE);
5298 for (l = w->children; l != NULL; l = l->next)
5302 if (GDK_WINDOW_IS_MAPPED (child) &&
5303 child->window_type != GDK_WINDOW_FOREIGN)
5304 set_viewable (child, val);
5307 if (gdk_window_has_impl (w) &&
5308 w->window_type != GDK_WINDOW_FOREIGN &&
5309 !gdk_window_is_toplevel (w))
5311 /* For most native windows we show/hide them not when they are
5312 * mapped/unmapped, because that may not produce the correct results.
5313 * For instance, if a native window have a non-native parent which is
5314 * hidden, but its native parent is viewable then showing the window
5315 * would make it viewable to X but its not viewable wrt the non-native
5316 * hierarchy. In order to handle this we track the gdk side viewability
5317 * and only map really viewable windows.
5319 * There are two exceptions though:
5321 * For foreign windows we don't want ever change the mapped state
5322 * except when explicitly done via gdk_window_show/hide, as this may
5323 * cause problems for client owning the foreign window when its window
5324 * is suddenly mapped or unmapped.
5326 * For toplevel windows embedded in a foreign window (e.g. a plug)
5327 * we sometimes synthesize a map of a window, but the native
5328 * window is really shown by the embedder, so we don't want to
5329 * do the show ourselves. We can't really tell this case from the normal
5330 * toplevel show as such toplevels are seen by gdk as parents of the
5331 * root window, so we make an exception for all toplevels.
5334 impl_class = GDK_WINDOW_IMPL_GET_CLASS (w->impl);
5336 impl_class->show ((GdkWindow *)w, FALSE);
5338 impl_class->hide ((GdkWindow *)w);
5346 /* Returns TRUE If the native window was mapped or unmapped */
5348 _gdk_window_update_viewable (GdkWindow *window)
5352 if (window->window_type == GDK_WINDOW_FOREIGN ||
5353 window->window_type == GDK_WINDOW_ROOT)
5355 else if (gdk_window_is_toplevel (window) ||
5356 window->parent->viewable)
5357 viewable = GDK_WINDOW_IS_MAPPED (window);
5361 return set_viewable (window, viewable);
5365 gdk_window_show_internal (GdkWindow *window, gboolean raise)
5367 GdkWindowImplClass *impl_class;
5368 gboolean was_mapped, was_viewable;
5371 g_return_if_fail (GDK_IS_WINDOW (window));
5373 if (window->destroyed)
5376 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5377 was_viewable = window->viewable;
5380 /* Keep children in (reverse) stacking order */
5381 gdk_window_raise_internal (window);
5383 if (gdk_window_has_impl (window))
5386 gdk_synthesize_window_state (window,
5387 GDK_WINDOW_STATE_WITHDRAWN,
5388 GDK_WINDOW_STATE_FOCUSED);
5395 did_show = _gdk_window_update_viewable (window);
5397 /* If it was already viewable the backend show op won't be called, call it
5398 again to ensure things happen right if the mapped tracking was not right
5399 for e.g. a foreign window.
5400 Dunno if this is strictly needed but its what happened pre-csw.
5401 Also show if not done by gdk_window_update_viewable. */
5402 if (gdk_window_has_impl (window) && (was_viewable || !did_show))
5404 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5405 impl_class->show (window, !did_show ? was_mapped : TRUE);
5408 if (!was_mapped && !gdk_window_has_impl (window))
5410 if (window->event_mask & GDK_STRUCTURE_MASK)
5411 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5413 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5414 _gdk_make_event (window, GDK_MAP, NULL, FALSE);
5417 if (!was_mapped || raise)
5419 recompute_visible_regions (window, TRUE, FALSE);
5421 /* If any decendants became visible we need to send visibility notify */
5422 gdk_window_update_visibility_recursively (window, NULL);
5424 if (gdk_window_is_viewable (window))
5426 _gdk_synthesize_crossing_events_for_geometry_change (window);
5427 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
5433 * gdk_window_show_unraised:
5434 * @window: a #GdkWindow
5436 * Shows a #GdkWindow onscreen, but does not modify its stacking
5437 * order. In contrast, gdk_window_show() will raise the window
5438 * to the top of the window stack.
5440 * On the X11 platform, in Xlib terms, this function calls
5441 * XMapWindow() (it also updates some internal GDK state, which means
5442 * that you can't really use XMapWindow() directly on a GDK window).
5445 gdk_window_show_unraised (GdkWindow *window)
5447 gdk_window_show_internal (window, FALSE);
5452 * @window: a #GdkWindow
5454 * Raises @window to the top of the Z-order (stacking order), so that
5455 * other windows with the same parent window appear below @window.
5456 * This is true whether or not the windows are visible.
5458 * If @window is a toplevel, the window manager may choose to deny the
5459 * request to move the window in the Z-order, gdk_window_raise() only
5460 * requests the restack, does not guarantee it.
5463 gdk_window_raise (GdkWindow *window)
5465 g_return_if_fail (GDK_IS_WINDOW (window));
5467 if (window->destroyed)
5470 /* Keep children in (reverse) stacking order */
5471 gdk_window_raise_internal (window);
5473 recompute_visible_regions (window, TRUE, FALSE);
5475 if (gdk_window_is_viewable (window) &&
5476 !window->input_only)
5477 gdk_window_invalidate_region_full (window, window->clip_region, TRUE, CLEAR_BG_ALL);
5481 gdk_window_lower_internal (GdkWindow *window)
5483 GdkWindow *parent = window->parent;
5484 GdkWindowImplClass *impl_class;
5486 GList *native_children;
5491 parent->children = g_list_remove (parent->children, window);
5492 parent->children = g_list_append (parent->children, window);
5495 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5496 /* Just do native lower for toplevels */
5497 if (gdk_window_is_toplevel (window) ||
5498 /* The restack_under codepath should work correctly even if the parent
5499 is native, but it relies on the order of ->children to be correct,
5500 and some apps like SWT reorder the x windows without gdks knowledge,
5501 so we use lower directly in order to make these behave as before
5502 when using native windows */
5503 (gdk_window_has_impl (window) && gdk_window_has_impl (parent)))
5505 impl_class->lower (window);
5507 else if (gdk_window_has_impl (window))
5509 above = find_native_sibling_above (parent, window);
5512 listhead.data = window;
5513 listhead.next = NULL;
5514 listhead.prev = NULL;
5515 impl_class->restack_under ((GdkWindow *)above, &listhead);
5518 impl_class->raise (window);
5522 native_children = NULL;
5523 get_all_native_children (window, &native_children);
5524 if (native_children != NULL)
5526 above = find_native_sibling_above (parent, window);
5529 impl_class->restack_under ((GdkWindow *)above,
5533 /* Right order, since native_children is bottom-topmost first */
5534 for (l = native_children; l != NULL; l = l->next)
5535 impl_class->raise (l->data);
5538 g_list_free (native_children);
5545 gdk_window_invalidate_in_parent (GdkWindow *private)
5547 GdkRectangle r, child;
5549 if (gdk_window_is_toplevel (private))
5552 /* get the visible rectangle of the parent */
5554 r.width = private->parent->width;
5555 r.height = private->parent->height;
5557 child.x = private->x;
5558 child.y = private->y;
5559 child.width = private->width;
5560 child.height = private->height;
5561 gdk_rectangle_intersect (&r, &child, &r);
5563 gdk_window_invalidate_rect_full (private->parent, &r, TRUE, CLEAR_BG_ALL);
5569 * @window: a #GdkWindow
5571 * Lowers @window to the bottom of the Z-order (stacking order), so that
5572 * other windows with the same parent window appear above @window.
5573 * This is true whether or not the other windows are visible.
5575 * If @window is a toplevel, the window manager may choose to deny the
5576 * request to move the window in the Z-order, gdk_window_lower() only
5577 * requests the restack, does not guarantee it.
5579 * Note that gdk_window_show() raises the window again, so don't call this
5580 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
5583 gdk_window_lower (GdkWindow *window)
5585 g_return_if_fail (GDK_IS_WINDOW (window));
5587 if (window->destroyed)
5590 /* Keep children in (reverse) stacking order */
5591 gdk_window_lower_internal (window);
5593 recompute_visible_regions (window, TRUE, FALSE);
5595 _gdk_synthesize_crossing_events_for_geometry_change (window);
5596 gdk_window_invalidate_in_parent (window);
5600 * gdk_window_restack:
5601 * @window: a #GdkWindow
5602 * @sibling: (allow-none): a #GdkWindow that is a sibling of @window, or %NULL
5605 * Changes the position of @window in the Z-order (stacking order), so that
5606 * it is above @sibling (if @above is %TRUE) or below @sibling (if @above is
5609 * If @sibling is %NULL, then this either raises (if @above is %TRUE) or
5610 * lowers the window.
5612 * If @window is a toplevel, the window manager may choose to deny the
5613 * request to move the window in the Z-order, gdk_window_restack() only
5614 * requests the restack, does not guarantee it.
5619 gdk_window_restack (GdkWindow *window,
5623 GdkWindowImplClass *impl_class;
5625 GdkWindow *above_native;
5626 GList *sibling_link;
5627 GList *native_children;
5630 g_return_if_fail (GDK_IS_WINDOW (window));
5631 g_return_if_fail (sibling == NULL || GDK_IS_WINDOW (sibling));
5633 if (window->destroyed)
5636 if (sibling == NULL)
5639 gdk_window_raise (window);
5641 gdk_window_lower (window);
5645 if (gdk_window_is_toplevel (window))
5647 g_return_if_fail (gdk_window_is_toplevel (sibling));
5648 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5649 impl_class->restack_toplevel (window, sibling, above);
5653 parent = window->parent;
5656 sibling_link = g_list_find (parent->children, sibling);
5657 g_return_if_fail (sibling_link != NULL);
5658 if (sibling_link == NULL)
5661 parent->children = g_list_remove (parent->children, window);
5663 parent->children = g_list_insert_before (parent->children,
5667 parent->children = g_list_insert_before (parent->children,
5671 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5672 if (gdk_window_has_impl (window))
5674 above_native = find_native_sibling_above (parent, window);
5677 listhead.data = window;
5678 listhead.next = NULL;
5679 listhead.prev = NULL;
5680 impl_class->restack_under (above_native, &listhead);
5683 impl_class->raise (window);
5687 native_children = NULL;
5688 get_all_native_children (window, &native_children);
5689 if (native_children != NULL)
5691 above_native = find_native_sibling_above (parent, window);
5693 impl_class->restack_under (above_native,
5697 /* Right order, since native_children is bottom-topmost first */
5698 for (l = native_children; l != NULL; l = l->next)
5699 impl_class->raise (l->data);
5702 g_list_free (native_children);
5707 recompute_visible_regions (window, TRUE, FALSE);
5709 _gdk_synthesize_crossing_events_for_geometry_change (window);
5710 gdk_window_invalidate_in_parent (window);
5716 * @window: a #GdkWindow
5718 * Like gdk_window_show_unraised(), but also raises the window to the
5719 * top of the window stack (moves the window to the front of the
5722 * This function maps a window so it's visible onscreen. Its opposite
5723 * is gdk_window_hide().
5725 * When implementing a #GtkWidget, you should call this function on the widget's
5726 * #GdkWindow as part of the "map" method.
5729 gdk_window_show (GdkWindow *window)
5731 gdk_window_show_internal (window, TRUE);
5736 * @window: a #GdkWindow
5738 * For toplevel windows, withdraws them, so they will no longer be
5739 * known to the window manager; for all windows, unmaps them, so
5740 * they won't be displayed. Normally done automatically as
5741 * part of gtk_widget_hide().
5744 gdk_window_hide (GdkWindow *window)
5746 GdkWindowImplClass *impl_class;
5747 gboolean was_mapped, did_hide;
5749 g_return_if_fail (GDK_IS_WINDOW (window));
5751 if (window->destroyed)
5754 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5756 if (gdk_window_has_impl (window))
5759 if (GDK_WINDOW_IS_MAPPED (window))
5760 gdk_synthesize_window_state (window,
5762 GDK_WINDOW_STATE_WITHDRAWN);
5764 else if (was_mapped)
5766 GdkDisplay *display;
5767 GdkDeviceManager *device_manager;
5770 /* May need to break grabs on children */
5771 display = gdk_window_get_display (window);
5772 device_manager = gdk_display_get_device_manager (display);
5774 /* Get all devices */
5775 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5776 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5777 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5779 for (d = devices; d; d = d->next)
5781 GdkDevice *device = d->data;
5783 if (_gdk_display_end_device_grab (display,
5785 _gdk_display_get_next_serial (display),
5788 gdk_device_ungrab (device, GDK_CURRENT_TIME);
5791 window->state = GDK_WINDOW_STATE_WITHDRAWN;
5792 g_list_free (devices);
5795 did_hide = _gdk_window_update_viewable (window);
5797 /* Hide foreign window as those are not handled by update_viewable. */
5798 if (gdk_window_has_impl (window) && (!did_hide))
5800 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5801 impl_class->hide (window);
5804 recompute_visible_regions (window, TRUE, FALSE);
5806 /* all decendants became non-visible, we need to send visibility notify */
5807 gdk_window_update_visibility_recursively (window, NULL);
5809 if (was_mapped && !gdk_window_has_impl (window))
5811 if (window->event_mask & GDK_STRUCTURE_MASK)
5812 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5814 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5815 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5817 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5820 /* Invalidate the rect */
5822 gdk_window_invalidate_in_parent (window);
5826 * gdk_window_withdraw:
5827 * @window: a toplevel #GdkWindow
5829 * Withdraws a window (unmaps it and asks the window manager to forget about it).
5830 * This function is not really useful as gdk_window_hide() automatically
5831 * withdraws toplevel windows before hiding them.
5834 gdk_window_withdraw (GdkWindow *window)
5836 GdkWindowImplClass *impl_class;
5837 gboolean was_mapped;
5839 g_return_if_fail (GDK_IS_WINDOW (window));
5841 if (window->destroyed)
5844 was_mapped = GDK_WINDOW_IS_MAPPED (window);
5846 if (gdk_window_has_impl (window))
5848 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5849 impl_class->withdraw (window);
5853 if (window->event_mask & GDK_STRUCTURE_MASK)
5854 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5856 if (window->parent && window->parent->event_mask & GDK_SUBSTRUCTURE_MASK)
5857 _gdk_make_event (window, GDK_UNMAP, NULL, FALSE);
5859 _gdk_synthesize_crossing_events_for_geometry_change (window->parent);
5862 recompute_visible_regions (window, TRUE, FALSE);
5867 * gdk_window_set_events:
5868 * @window: a #GdkWindow
5869 * @event_mask: event mask for @window
5871 * The event mask for a window determines which events will be reported
5872 * for that window from all master input devices. For example, an event mask
5873 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5874 * press events. The event mask is the bitwise OR of values from the
5875 * #GdkEventMask enumeration.
5878 gdk_window_set_events (GdkWindow *window,
5879 GdkEventMask event_mask)
5881 GdkWindowImplClass *impl_class;
5882 GdkDisplay *display;
5884 g_return_if_fail (GDK_IS_WINDOW (window));
5886 if (window->destroyed)
5889 /* If motion hint is disabled, enable motion events again */
5890 display = gdk_window_get_display (window);
5891 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5892 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5894 GList *devices = window->devices_inside;
5898 _gdk_display_enable_motion_hints (display, (GdkDevice *) devices->data);
5899 devices = devices->next;
5903 window->event_mask = event_mask;
5905 if (gdk_window_has_impl (window))
5907 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
5908 impl_class->set_events (window,
5909 get_native_event_mask (window));
5915 * gdk_window_get_events:
5916 * @window: a #GdkWindow
5918 * Gets the event mask for @window for all master input devices. See
5919 * gdk_window_set_events().
5921 * Return value: event mask for @window
5924 gdk_window_get_events (GdkWindow *window)
5926 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5928 if (window->destroyed)
5931 return window->event_mask;
5935 * gdk_window_set_device_events:
5936 * @window: a #GdkWindow
5937 * @device: #GdkDevice to enable events for.
5938 * @event_mask: event mask for @window
5940 * Sets the event mask for a given device (Normally a floating device, not
5941 * attached to any visible pointer) to @window. For example, an event mask
5942 * including #GDK_BUTTON_PRESS_MASK means the window should report button
5943 * press events. The event mask is the bitwise OR of values from the
5944 * #GdkEventMask enumeration.
5949 gdk_window_set_device_events (GdkWindow *window,
5951 GdkEventMask event_mask)
5953 GdkEventMask device_mask;
5954 GdkDisplay *display;
5957 g_return_if_fail (GDK_IS_WINDOW (window));
5958 g_return_if_fail (GDK_IS_DEVICE (device));
5960 if (GDK_WINDOW_DESTROYED (window))
5963 /* If motion hint is disabled, enable motion events again */
5964 display = gdk_window_get_display (window);
5965 if ((window->event_mask & GDK_POINTER_MOTION_HINT_MASK) &&
5966 !(event_mask & GDK_POINTER_MOTION_HINT_MASK))
5967 _gdk_display_enable_motion_hints (display, device);
5969 if (G_UNLIKELY (!window->device_events))
5970 window->device_events = g_hash_table_new (NULL, NULL);
5972 if (event_mask == 0)
5974 /* FIXME: unsetting events on a master device
5975 * would restore window->event_mask
5977 g_hash_table_remove (window->device_events, device);
5980 g_hash_table_insert (window->device_events, device,
5981 GINT_TO_POINTER (event_mask));
5983 native = gdk_window_get_toplevel (window);
5985 while (gdk_window_is_offscreen (native))
5987 native = gdk_offscreen_window_get_embedder (native);
5989 if (native == NULL ||
5990 (!_gdk_window_has_impl (native) &&
5991 !gdk_window_is_viewable (native)))
5994 native = gdk_window_get_toplevel (native);
5997 device_mask = get_native_device_event_mask (window, device);
5998 GDK_DEVICE_GET_CLASS (device)->select_window_events (device, native, device_mask);
6002 * gdk_window_get_device_events:
6003 * @window: a #GdkWindow.
6004 * @device: a #GdkDevice.
6006 * Returns the event mask for @window corresponding to an specific device.
6008 * Returns: device event mask for @window
6013 gdk_window_get_device_events (GdkWindow *window,
6018 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
6019 g_return_val_if_fail (GDK_IS_DEVICE (device), 0);
6021 if (GDK_WINDOW_DESTROYED (window))
6024 if (!window->device_events)
6027 mask = GPOINTER_TO_INT (g_hash_table_lookup (window->device_events, device));
6029 /* FIXME: device could be controlled by window->event_mask */
6035 gdk_window_move_resize_toplevel (GdkWindow *window,
6042 cairo_region_t *old_region, *new_region;
6043 GdkWindowImplClass *impl_class;
6050 is_resize = (width != -1) || (height != -1);
6052 if (gdk_window_is_viewable (window) &&
6053 !window->input_only)
6056 old_region = cairo_region_copy (window->clip_region);
6059 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6060 impl_class->move_resize (window, with_move, x, y, width, height);
6062 /* Avoid recomputing for pure toplevel moves, for performance reasons */
6064 recompute_visible_regions (window, TRUE, FALSE);
6068 new_region = cairo_region_copy (window->clip_region);
6070 /* This is the newly exposed area (due to any resize),
6071 * X will expose it, but lets do that without the roundtrip
6073 cairo_region_subtract (new_region, old_region);
6074 gdk_window_invalidate_region_full (window, new_region, TRUE, CLEAR_BG_WINCLEARED);
6076 cairo_region_destroy (old_region);
6077 cairo_region_destroy (new_region);
6080 _gdk_synthesize_crossing_events_for_geometry_change (window);
6085 move_native_children (GdkWindow *private)
6089 GdkWindowImplClass *impl_class;
6091 for (l = private->children; l; l = l->next)
6095 if (child->impl != private->impl)
6097 impl_class = GDK_WINDOW_IMPL_GET_CLASS (child->impl);
6098 impl_class->move_resize (child, TRUE,
6100 child->width, child->height);
6103 move_native_children (child);
6108 collect_native_child_region_helper (GdkWindow *window,
6109 GdkWindowImpl *impl,
6110 cairo_region_t **region,
6115 cairo_region_t *tmp;
6118 for (l = window->children; l != NULL; l = l->next)
6122 if (!GDK_WINDOW_IS_MAPPED (child) || child->input_only)
6125 if (child->impl != impl)
6127 tmp = cairo_region_copy (child->clip_region);
6128 cairo_region_translate (tmp,
6129 x_offset + child->x,
6130 y_offset + child->y);
6131 if (*region == NULL)
6135 cairo_region_union (*region, tmp);
6136 cairo_region_destroy (tmp);
6140 collect_native_child_region_helper (child, impl, region,
6141 x_offset + child->x,
6142 y_offset + child->y);
6148 static cairo_region_t *
6149 collect_native_child_region (GdkWindow *window,
6150 gboolean include_this)
6152 cairo_region_t *region;
6154 if (include_this && gdk_window_has_impl (window) && window->viewable)
6155 return cairo_region_copy (window->clip_region);
6159 collect_native_child_region_helper (window, window->impl, ®ion, 0, 0);
6166 gdk_window_move_resize_internal (GdkWindow *window,
6173 cairo_region_t *old_region, *old_layered, *new_region, *copy_area;
6174 cairo_region_t *old_native_child_region, *new_native_child_region;
6175 GdkWindow *impl_window;
6176 GdkWindowImplClass *impl_class;
6178 int old_x, old_y, old_abs_x, old_abs_y;
6181 g_return_if_fail (GDK_IS_WINDOW (window));
6183 if (window->destroyed)
6186 if (gdk_window_is_toplevel (window))
6188 gdk_window_move_resize_toplevel (window, with_move, x, y, width, height);
6192 /* Bail early if no change */
6193 if (window->width == width &&
6194 window->height == height &&
6200 /* Handle child windows */
6206 impl_window = gdk_window_get_impl_window (window);
6211 old_native_child_region = NULL;
6212 if (gdk_window_is_viewable (window) &&
6213 !window->input_only)
6217 old_region = cairo_region_copy (window->clip_region);
6218 old_layered = cairo_region_copy (window->layered_region);
6219 /* Adjust regions to parent window coords */
6220 cairo_region_translate (old_region, window->x, window->y);
6221 cairo_region_translate (old_layered, window->x, window->y);
6223 old_native_child_region = collect_native_child_region (window, TRUE);
6224 if (old_native_child_region)
6226 /* Adjust region to parent window coords */
6227 cairo_region_translate (old_native_child_region, window->x, window->y);
6229 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6230 * source or destination for a delayed GdkWindowRegionMove. So, we need
6231 * to flush those here for the parent window and all overlapped subwindows
6232 * of it. And we need to do this before setting the new clips as those will be
6235 gdk_window_flush_recursive (window->parent);
6239 /* Set the new position and size */
6245 if (!(width < 0 && height < 0))
6249 window->width = width;
6252 window->height = height;
6255 dx = window->x - old_x;
6256 dy = window->y - old_y;
6258 old_abs_x = window->abs_x;
6259 old_abs_y = window->abs_y;
6261 recompute_visible_regions (window, TRUE, FALSE);
6263 new_native_child_region = NULL;
6264 if (old_native_child_region)
6266 new_native_child_region = collect_native_child_region (window, TRUE);
6267 /* Adjust region to parent window coords */
6268 cairo_region_translate (new_native_child_region, window->x, window->y);
6271 if (gdk_window_has_impl (window))
6273 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6275 /* Do the actual move after recomputing things, as this will have set the shape to
6276 the now correct one, thus avoiding copying regions that should not be copied. */
6277 impl_class->move_resize (window, TRUE,
6278 window->x, window->y,
6279 window->width, window->height);
6281 else if (old_abs_x != window->abs_x ||
6282 old_abs_y != window->abs_y)
6283 move_native_children (window);
6287 new_region = cairo_region_copy (window->clip_region);
6288 /* Adjust region to parent window coords */
6289 cairo_region_translate (new_region, window->x, window->y);
6292 * Part of the data at the new location can be copied from the
6293 * old location, this area is the intersection of the old region
6294 * moved as the copy will move it and then intersected with
6298 * Everything in the old and new regions that is not copied must be
6299 * invalidated (including children) as this is newly exposed
6301 if (gdk_window_has_alpha (window))
6302 copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
6304 copy_area = cairo_region_copy (new_region);
6306 /* Don't copy from a previously layered region */
6307 cairo_region_translate (old_layered, dx, dy);
6308 cairo_region_subtract (copy_area, old_layered);
6310 /* Don't copy into a layered region */
6311 cairo_region_translate (copy_area, -window->x, -window->y);
6312 cairo_region_subtract (copy_area, window->layered_region);
6313 cairo_region_translate (copy_area, window->x, window->y);
6315 cairo_region_union (new_region, old_region);
6317 if (old_native_child_region)
6319 /* Don't copy from inside native children, as this is copied by
6320 * the native window move.
6322 cairo_region_subtract (old_region, old_native_child_region);
6324 cairo_region_translate (old_region, dx, dy);
6326 cairo_region_intersect (copy_area, old_region);
6328 if (new_native_child_region)
6330 /* Don't copy any bits that would cause a read from the moved
6331 native windows, as we can't read that data */
6332 cairo_region_translate (new_native_child_region, dx, dy);
6333 cairo_region_subtract (copy_area, new_native_child_region);
6334 cairo_region_translate (new_native_child_region, -dx, -dy);
6337 cairo_region_subtract (new_region, copy_area);
6339 /* Convert old region to impl coords */
6340 cairo_region_translate (old_region, -dx + window->abs_x - window->x, -dy + window->abs_y - window->y);
6342 /* convert from parent coords to impl */
6343 cairo_region_translate (copy_area, window->abs_x - window->x, window->abs_y - window->y);
6345 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6347 /* Invalidate affected part in the parent window
6348 * (no higher window should be affected)
6349 * We also invalidate any children in that area, which could include
6350 * this window if it still overlaps that area.
6352 if (old_native_child_region)
6354 /* No need to expose the region that the native window move copies */
6355 cairo_region_translate (old_native_child_region, dx, dy);
6356 cairo_region_intersect (old_native_child_region, new_native_child_region);
6357 cairo_region_subtract (new_region, old_native_child_region);
6359 gdk_window_invalidate_region_full (window->parent, new_region, TRUE, CLEAR_BG_ALL);
6361 cairo_region_destroy (old_region);
6362 cairo_region_destroy (old_layered);
6363 cairo_region_destroy (new_region);
6366 if (old_native_child_region)
6368 cairo_region_destroy (old_native_child_region);
6369 cairo_region_destroy (new_native_child_region);
6372 _gdk_synthesize_crossing_events_for_geometry_change (window);
6379 * @window: a #GdkWindow
6380 * @x: X coordinate relative to window's parent
6381 * @y: Y coordinate relative to window's parent
6383 * Repositions a window relative to its parent window.
6384 * For toplevel windows, window managers may ignore or modify the move;
6385 * you should probably use gtk_window_move() on a #GtkWindow widget
6386 * anyway, instead of using GDK functions. For child windows,
6387 * the move will reliably succeed.
6389 * If you're also planning to resize the window, use gdk_window_move_resize()
6390 * to both move and resize simultaneously, for a nicer visual effect.
6393 gdk_window_move (GdkWindow *window,
6397 gdk_window_move_resize_internal (window, TRUE, x, y, -1, -1);
6401 * gdk_window_resize:
6402 * @window: a #GdkWindow
6403 * @width: new width of the window
6404 * @height: new height of the window
6406 * Resizes @window; for toplevel windows, asks the window manager to resize
6407 * the window. The window manager may not allow the resize. When using GTK+,
6408 * use gtk_window_resize() instead of this low-level GDK function.
6410 * Windows may not be resized below 1x1.
6412 * If you're also planning to move the window, use gdk_window_move_resize()
6413 * to both move and resize simultaneously, for a nicer visual effect.
6416 gdk_window_resize (GdkWindow *window,
6420 gdk_window_move_resize_internal (window, FALSE, 0, 0, width, height);
6425 * gdk_window_move_resize:
6426 * @window: a #GdkWindow
6427 * @x: new X position relative to window's parent
6428 * @y: new Y position relative to window's parent
6430 * @height: new height
6432 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
6433 * except that both operations are performed at once, avoiding strange
6434 * visual effects. (i.e. the user may be able to see the window first
6435 * move, then resize, if you don't use gdk_window_move_resize().)
6438 gdk_window_move_resize (GdkWindow *window,
6444 gdk_window_move_resize_internal (window, TRUE, x, y, width, height);
6449 * gdk_window_scroll:
6450 * @window: a #GdkWindow
6451 * @dx: Amount to scroll in the X direction
6452 * @dy: Amount to scroll in the Y direction
6454 * Scroll the contents of @window, both pixels and children, by the
6455 * given amount. @window itself does not move. Portions of the window
6456 * that the scroll operation brings in from offscreen areas are
6457 * invalidated. The invalidated region may be bigger than what would
6458 * strictly be necessary.
6460 * For X11, a minimum area will be invalidated if the window has no
6461 * subwindows, or if the edges of the window's parent do not extend
6462 * beyond the edges of the window. In other cases, a multi-step process
6463 * is used to scroll the window which may produce temporary visual
6464 * artifacts and unnecessary invalidations.
6467 gdk_window_scroll (GdkWindow *window,
6471 GdkWindow *impl_window;
6472 cairo_region_t *copy_area, *noncopy_area, *old_layered_area;
6473 cairo_region_t *old_native_child_region, *new_native_child_region;
6476 g_return_if_fail (GDK_IS_WINDOW (window));
6478 if (dx == 0 && dy == 0)
6481 if (window->destroyed)
6484 old_layered_area = cairo_region_copy (window->layered_region);
6485 old_native_child_region = collect_native_child_region (window, FALSE);
6486 if (old_native_child_region)
6488 /* Any native window move will immediately copy stuff to the destination, which may overwrite a
6489 * source or destination for a delayed GdkWindowRegionMove. So, we need
6490 * to flush those here for the window and all overlapped subwindows
6491 * of it. And we need to do this before setting the new clips as those will be
6494 gdk_window_flush_recursive (window);
6498 /* First move all child windows, without causing invalidation */
6500 tmp_list = window->children;
6503 GdkWindow *child = GDK_WINDOW (tmp_list->data);
6505 /* Just update the positions, the bits will move with the copy */
6509 tmp_list = tmp_list->next;
6512 recompute_visible_regions (window, FALSE, TRUE);
6514 new_native_child_region = NULL;
6515 if (old_native_child_region)
6516 new_native_child_region = collect_native_child_region (window, FALSE);
6518 move_native_children (window);
6520 /* Then copy the actual bits of the window w/ child windows */
6522 impl_window = gdk_window_get_impl_window (window);
6524 /* Calculate the area that can be gotten by copying the old area */
6525 if (gdk_window_has_alpha (window))
6526 copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
6528 copy_area = cairo_region_copy (window->clip_region);
6529 cairo_region_subtract (copy_area, old_layered_area);
6530 if (old_native_child_region)
6532 /* Don't copy from inside native children, as this is copied by
6533 * the native window move.
6535 cairo_region_subtract (copy_area, old_native_child_region);
6537 /* Don't copy any bits that would cause a read from the moved
6538 native windows, as we can't read that data */
6539 cairo_region_subtract (copy_area, new_native_child_region);
6541 cairo_region_translate (copy_area, dx, dy);
6542 cairo_region_intersect (copy_area, window->clip_region);
6543 cairo_region_subtract (copy_area, window->layered_region);
6545 /* And the rest need to be invalidated */
6546 noncopy_area = cairo_region_copy (window->clip_region);
6547 cairo_region_subtract (noncopy_area, copy_area);
6549 /* convert from window coords to impl */
6550 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6552 move_region_on_impl (impl_window, copy_area, dx, dy); /* takes ownership of copy_area */
6554 /* Invalidate not copied regions */
6555 if (old_native_child_region)
6557 /* No need to expose the region that the native window move copies */
6558 cairo_region_translate (old_native_child_region, dx, dy);
6559 cairo_region_intersect (old_native_child_region, new_native_child_region);
6560 cairo_region_subtract (noncopy_area, old_native_child_region);
6562 gdk_window_invalidate_region_full (window, noncopy_area, TRUE, CLEAR_BG_ALL);
6564 cairo_region_destroy (noncopy_area);
6565 cairo_region_destroy (old_layered_area);
6567 if (old_native_child_region)
6569 cairo_region_destroy (old_native_child_region);
6570 cairo_region_destroy (new_native_child_region);
6573 _gdk_synthesize_crossing_events_for_geometry_change (window);
6577 * gdk_window_move_region:
6578 * @window: a #GdkWindow
6579 * @region: The #cairo_region_t to move
6580 * @dx: Amount to move in the X direction
6581 * @dy: Amount to move in the Y direction
6583 * Move the part of @window indicated by @region by @dy pixels in the Y
6584 * direction and @dx pixels in the X direction. The portions of @region
6585 * that not covered by the new position of @region are invalidated.
6587 * Child windows are not moved.
6592 gdk_window_move_region (GdkWindow *window,
6593 const cairo_region_t *region,
6597 GdkWindow *impl_window;
6598 cairo_region_t *nocopy_area;
6599 cairo_region_t *copy_area;
6601 g_return_if_fail (GDK_IS_WINDOW (window));
6602 g_return_if_fail (region != NULL);
6604 if (dx == 0 && dy == 0)
6607 if (window->destroyed)
6610 impl_window = gdk_window_get_impl_window (window);
6612 /* compute source regions */
6613 if (gdk_window_has_alpha (window))
6614 copy_area = cairo_region_create (); /* Copy nothing for alpha windows */
6616 copy_area = cairo_region_copy (region);
6617 cairo_region_intersect (copy_area, window->clip_region_with_children);
6618 cairo_region_subtract (copy_area, window->layered_region);
6619 remove_layered_child_area (window, copy_area);
6621 /* compute destination regions */
6622 cairo_region_translate (copy_area, dx, dy);
6623 cairo_region_intersect (copy_area, window->clip_region_with_children);
6624 cairo_region_subtract (copy_area, window->layered_region);
6625 remove_layered_child_area (window, copy_area);
6627 /* Invalidate parts of the region (source and dest) not covered
6629 nocopy_area = cairo_region_copy (region);
6630 cairo_region_translate (nocopy_area, dx, dy);
6631 cairo_region_union (nocopy_area, region);
6632 cairo_region_subtract (nocopy_area, copy_area);
6634 /* convert from window coords to impl */
6635 cairo_region_translate (copy_area, window->abs_x, window->abs_y);
6636 move_region_on_impl (impl_window, copy_area, dx, dy); /* Takes ownership of copy_area */
6638 gdk_window_invalidate_region_full (window, nocopy_area, FALSE, CLEAR_BG_ALL);
6639 cairo_region_destroy (nocopy_area);
6643 * gdk_window_set_background:
6644 * @window: a #GdkWindow
6645 * @color: a #GdkColor
6647 * Sets the background color of @window. (However, when using GTK+,
6648 * set the background of a widget with gtk_widget_modify_bg() - if
6649 * you're an application - or gtk_style_set_background() - if you're
6650 * implementing a custom widget.)
6652 * See also gdk_window_set_background_pattern().
6654 * Deprecated: 3.4: Use gdk_window_set_background_rgba() instead.
6657 gdk_window_set_background (GdkWindow *window,
6658 const GdkColor *color)
6660 cairo_pattern_t *pattern;
6662 g_return_if_fail (GDK_IS_WINDOW (window));
6664 pattern = cairo_pattern_create_rgb (color->red / 65535.,
6665 color->green / 65535.,
6666 color->blue / 65535.);
6668 gdk_window_set_background_pattern (window, pattern);
6670 cairo_pattern_destroy (pattern);
6674 * gdk_window_set_background_rgba:
6675 * @window: a #GdkWindow
6676 * @rgba: a #GdkRGBA color
6678 * Sets the background color of @window.
6680 * See also gdk_window_set_background_pattern().
6683 gdk_window_set_background_rgba (GdkWindow *window,
6684 const GdkRGBA *rgba)
6686 cairo_pattern_t *pattern;
6688 g_return_if_fail (GDK_IS_WINDOW (window));
6689 g_return_if_fail (rgba != NULL);
6691 pattern = cairo_pattern_create_rgba (rgba->red, rgba->green,
6692 rgba->blue, rgba->alpha);
6694 gdk_window_set_background_pattern (window, pattern);
6696 cairo_pattern_destroy (pattern);
6700 /* Updates has_alpha_background recursively for all child windows
6701 that have parent-relative alpha */
6703 _gdk_window_propagate_has_alpha_background (GdkWindow *window)
6708 for (l = window->children; l; l = l->next)
6712 if (child->background == NULL &&
6713 child->has_alpha_background != window->has_alpha_background)
6715 child->has_alpha_background = window->has_alpha_background;
6716 recompute_visible_regions (child, TRUE, FALSE);
6717 _gdk_window_propagate_has_alpha_background (child);
6723 * gdk_window_set_background_pattern:
6724 * @window: a #GdkWindow
6725 * @pattern: (allow-none): a pattern to use, or %NULL
6727 * Sets the background of @window.
6729 * A background of %NULL means that the window will inherit its
6730 * background form its parent window.
6732 * The windowing system will normally fill a window with its background
6733 * when the window is obscured then exposed.
6736 gdk_window_set_background_pattern (GdkWindow *window,
6737 cairo_pattern_t *pattern)
6740 cairo_pattern_type_t type;
6742 g_return_if_fail (GDK_IS_WINDOW (window));
6744 if (window->input_only)
6748 cairo_pattern_reference (pattern);
6749 if (window->background)
6750 cairo_pattern_destroy (window->background);
6751 window->background = pattern;
6755 if (pattern == NULL)
6757 /* parent-relative, copy has_alpha from parent */
6758 if (window->parent == NULL ||
6759 window->parent->window_type == GDK_WINDOW_ROOT)
6762 has_alpha = window->parent->has_alpha_background;
6766 type = cairo_pattern_get_type (pattern);
6768 if (type == CAIRO_PATTERN_TYPE_SOLID)
6771 cairo_pattern_get_rgba (pattern, NULL, NULL, NULL, &alpha);
6775 else if (type == CAIRO_PATTERN_TYPE_LINEAR ||
6776 type == CAIRO_PATTERN_TYPE_RADIAL)
6782 cairo_pattern_get_color_stop_count (pattern, &n);
6784 for (i = 0; i < n; i++)
6786 cairo_pattern_get_color_stop_rgba (pattern, i, NULL,
6787 NULL, NULL, NULL, &alpha);
6795 else if (type == CAIRO_PATTERN_TYPE_SURFACE)
6797 cairo_surface_t *surface;
6798 cairo_content_t content;
6800 cairo_pattern_get_surface (pattern, &surface);
6801 content = cairo_surface_get_content (surface);
6803 (content == CAIRO_CONTENT_ALPHA) ||
6804 (content == CAIRO_CONTENT_COLOR_ALPHA);
6808 if (has_alpha != window->has_alpha_background)
6810 window->has_alpha_background = has_alpha;
6811 recompute_visible_regions (window, TRUE, FALSE);
6813 _gdk_window_propagate_has_alpha_background (window);
6816 if (gdk_window_has_impl (window))
6818 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
6819 impl_class->set_background (window, pattern);
6822 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
6826 * gdk_window_get_background_pattern:
6829 * Gets the pattern used to clear the background on @window. If @window
6830 * does not have its own background and reuses the parent's, %NULL is
6831 * returned and you'll have to query it yourself.
6833 * Returns: (transfer none): The pattern to use for the background or
6834 * %NULL to use the parent's background.
6839 gdk_window_get_background_pattern (GdkWindow *window)
6841 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6843 return window->background;
6847 gdk_window_set_cursor_internal (GdkWindow *window,
6851 if (GDK_WINDOW_DESTROYED (window))
6854 if (window->window_type == GDK_WINDOW_ROOT ||
6855 window->window_type == GDK_WINDOW_FOREIGN)
6856 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_device_cursor (window, device, cursor);
6859 GdkPointerWindowInfo *pointer_info;
6860 GdkDisplay *display;
6862 display = gdk_window_get_display (window);
6863 pointer_info = _gdk_display_get_pointer_info (display, device);
6865 if (_gdk_window_event_parent_of (window, pointer_info->window_under_pointer))
6866 update_cursor (display, device);
6871 * gdk_window_get_cursor:
6872 * @window: a #GdkWindow
6874 * Retrieves a #GdkCursor pointer for the cursor currently set on the
6875 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6876 * there is no custom cursor set on the specified window, and it is
6877 * using the cursor for its parent window.
6879 * Return value: (transfer none): a #GdkCursor, or %NULL. The returned
6880 * object is owned by the #GdkWindow and should not be unreferenced
6881 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6887 gdk_window_get_cursor (GdkWindow *window)
6889 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6891 return window->cursor;
6895 * gdk_window_set_cursor:
6896 * @window: a #GdkWindow
6897 * @cursor: (allow-none): a cursor
6899 * Sets the default mouse pointer for a #GdkWindow. Use gdk_cursor_new_for_display()
6900 * or gdk_cursor_new_from_pixbuf() to create the cursor. To make the cursor
6901 * invisible, use %GDK_BLANK_CURSOR. Passing %NULL for the @cursor argument
6902 * to gdk_window_set_cursor() means that @window will use the cursor of its
6903 * parent window. Most windows should use this default.
6906 gdk_window_set_cursor (GdkWindow *window,
6909 GdkDisplay *display;
6911 g_return_if_fail (GDK_IS_WINDOW (window));
6913 display = gdk_window_get_display (window);
6917 g_object_unref (window->cursor);
6918 window->cursor = NULL;
6921 if (!GDK_WINDOW_DESTROYED (window))
6923 GdkDeviceManager *device_manager;
6927 window->cursor = g_object_ref (cursor);
6929 device_manager = gdk_display_get_device_manager (display);
6930 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6932 for (d = devices; d; d = d->next)
6938 if (gdk_device_get_source (device) == GDK_SOURCE_KEYBOARD)
6941 gdk_window_set_cursor_internal (window, device, window->cursor);
6944 g_list_free (devices);
6945 g_object_notify (G_OBJECT (window), "cursor");
6950 * gdk_window_get_device_cursor:
6951 * @window: a #GdkWindow.
6952 * @device: a master, pointer #GdkDevice.
6954 * Retrieves a #GdkCursor pointer for the @device currently set on the
6955 * specified #GdkWindow, or %NULL. If the return value is %NULL then
6956 * there is no custom cursor set on the specified window, and it is
6957 * using the cursor for its parent window.
6959 * Returns: (transfer none): a #GdkCursor, or %NULL. The returned
6960 * object is owned by the #GdkWindow and should not be unreferenced
6961 * directly. Use gdk_window_set_cursor() to unset the cursor of the
6967 gdk_window_get_device_cursor (GdkWindow *window,
6970 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
6971 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
6972 g_return_val_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD, NULL);
6973 g_return_val_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER, NULL);
6975 return g_hash_table_lookup (window->device_cursor, device);
6979 * gdk_window_set_device_cursor:
6980 * @window: a #Gdkwindow
6981 * @device: a master, pointer #GdkDevice
6982 * @cursor: a #GdkCursor
6984 * Sets a specific #GdkCursor for a given device when it gets inside @window.
6985 * Use gdk_cursor_new_for_display() or gdk_cursor_new_from_pixbuf() to create
6986 * the cursor. To make the cursor invisible, use %GDK_BLANK_CURSOR. Passing
6987 * %NULL for the @cursor argument to gdk_window_set_cursor() means that
6988 * @window will use the cursor of its parent window. Most windows should
6994 gdk_window_set_device_cursor (GdkWindow *window,
6998 g_return_if_fail (GDK_IS_WINDOW (window));
6999 g_return_if_fail (GDK_IS_DEVICE (device));
7000 g_return_if_fail (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD);
7001 g_return_if_fail (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER);
7004 g_hash_table_remove (window->device_cursor, device);
7006 g_hash_table_replace (window->device_cursor, device, g_object_ref (cursor));
7008 gdk_window_set_cursor_internal (window, device, cursor);
7012 * gdk_window_get_geometry:
7013 * @window: a #GdkWindow
7014 * @x: (out) (allow-none): return location for X coordinate of window (relative to its parent)
7015 * @y: (out) (allow-none): return location for Y coordinate of window (relative to its parent)
7016 * @width: (out) (allow-none): return location for width of window
7017 * @height: (out) (allow-none): return location for height of window
7019 * Any of the return location arguments to this function may be %NULL,
7020 * if you aren't interested in getting the value of that field.
7022 * The X and Y coordinates returned are relative to the parent window
7023 * of @window, which for toplevels usually means relative to the
7024 * window decorations (titlebar, etc.) rather than relative to the
7025 * root window (screen-size background window).
7027 * On the X11 platform, the geometry is obtained from the X server,
7028 * so reflects the latest position of @window; this may be out-of-sync
7029 * with the position of @window delivered in the most-recently-processed
7030 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
7031 * position from the most recent configure event.
7034 * If @window is not a toplevel, it is <emphasis>much</emphasis> better
7035 * to call gdk_window_get_position(), gdk_window_get_width() and
7036 * gdk_window_get_height() instead, because it avoids the roundtrip to
7037 * the X server and because these functions support the full 32-bit
7038 * coordinate space, whereas gdk_window_get_geometry() is restricted to
7039 * the 16-bit coordinates of X11.
7043 gdk_window_get_geometry (GdkWindow *window,
7050 GdkWindowImplClass *impl_class;
7054 GDK_NOTE (MULTIHEAD,
7055 g_message ("gdk_window_get_geometry(): Window needs "
7056 "to be non-NULL to be multi head safe"));
7057 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
7060 g_return_if_fail (GDK_IS_WINDOW (window));
7062 if (!GDK_WINDOW_DESTROYED (window))
7064 if (gdk_window_has_impl (window))
7066 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7067 impl_class->get_geometry (window, x, y,
7069 /* This reports the position wrt to the native parent, we need to convert
7070 it to be relative to the client side parent */
7071 parent = window->parent;
7072 if (parent && !gdk_window_has_impl (parent))
7075 *x -= parent->abs_x;
7077 *y -= parent->abs_y;
7087 *width = window->width;
7089 *height = window->height;
7095 * gdk_window_get_width:
7096 * @window: a #GdkWindow
7098 * Returns the width of the given @window.
7100 * On the X11 platform the returned size is the size reported in the
7101 * most-recently-processed configure event, rather than the current
7102 * size on the X server.
7104 * Returns: The width of @window
7109 gdk_window_get_width (GdkWindow *window)
7111 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7113 return window->width;
7117 * gdk_window_get_height:
7118 * @window: a #GdkWindow
7120 * Returns the height of the given @window.
7122 * On the X11 platform the returned size is the size reported in the
7123 * most-recently-processed configure event, rather than the current
7124 * size on the X server.
7126 * Returns: The height of @window
7131 gdk_window_get_height (GdkWindow *window)
7133 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7135 return window->height;
7139 * gdk_window_get_origin:
7140 * @window: a #GdkWindow
7141 * @x: (out) (allow-none): return location for X coordinate
7142 * @y: (out) (allow-none): return location for Y coordinate
7144 * Obtains the position of a window in root window coordinates.
7145 * (Compare with gdk_window_get_position() and
7146 * gdk_window_get_geometry() which return the position of a window
7147 * relative to its parent window.)
7149 * Return value: not meaningful, ignore
7152 gdk_window_get_origin (GdkWindow *window,
7156 GdkWindowImplClass *impl_class;
7158 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
7160 if (GDK_WINDOW_DESTROYED (window))
7169 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7170 impl_class->get_root_coords (window,
7179 * gdk_window_get_root_coords:
7180 * @window: a #GdkWindow
7181 * @x: X coordinate in window
7182 * @y: Y coordinate in window
7183 * @root_x: (out): return location for X coordinate
7184 * @root_y: (out): return location for Y coordinate
7186 * Obtains the position of a window position in root
7187 * window coordinates. This is similar to
7188 * gdk_window_get_origin() but allows you go pass
7189 * in any position in the window, not just the origin.
7194 gdk_window_get_root_coords (GdkWindow *window,
7200 GdkWindowImplClass *impl_class;
7202 g_return_if_fail (GDK_IS_WINDOW (window));
7204 if (GDK_WINDOW_DESTROYED (window))
7211 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7212 impl_class->get_root_coords (window,
7219 * gdk_window_coords_to_parent:
7220 * @window: a child window
7221 * @x: X coordinate in child's coordinate system
7222 * @y: Y coordinate in child's coordinate system
7223 * @parent_x: (out) (allow-none): return location for X coordinate
7224 * in parent's coordinate system, or %NULL
7225 * @parent_y: (out) (allow-none): return location for Y coordinate
7226 * in parent's coordinate system, or %NULL
7228 * Transforms window coordinates from a child window to its parent
7229 * window, where the parent window is the normal parent as returned by
7230 * gdk_window_get_parent() for normal windows, and the window's
7231 * embedder as returned by gdk_offscreen_window_get_embedder() for
7232 * offscreen windows.
7234 * For normal windows, calling this function is equivalent to adding
7235 * the return values of gdk_window_get_position() to the child coordinates.
7236 * For offscreen windows however (which can be arbitrarily transformed),
7237 * this function calls the GdkWindow::to-embedder: signal to translate
7240 * You should always use this function when writing generic code that
7241 * walks up a window hierarchy.
7243 * See also: gdk_window_coords_from_parent()
7248 gdk_window_coords_to_parent (GdkWindow *window,
7254 g_return_if_fail (GDK_IS_WINDOW (window));
7256 if (gdk_window_is_offscreen (window))
7260 to_embedder (window, x, y, &px, &py);
7271 *parent_x = x + window->x;
7274 *parent_y = y + window->y;
7279 * gdk_window_coords_from_parent:
7280 * @window: a child window
7281 * @parent_x: X coordinate in parent's coordinate system
7282 * @parent_y: Y coordinate in parent's coordinate system
7283 * @x: (out) (allow-none): return location for X coordinate in child's coordinate system
7284 * @y: (out) (allow-none): return location for Y coordinate in child's coordinate system
7286 * Transforms window coordinates from a parent window to a child
7287 * window, where the parent window is the normal parent as returned by
7288 * gdk_window_get_parent() for normal windows, and the window's
7289 * embedder as returned by gdk_offscreen_window_get_embedder() for
7290 * offscreen windows.
7292 * For normal windows, calling this function is equivalent to subtracting
7293 * the return values of gdk_window_get_position() from the parent coordinates.
7294 * For offscreen windows however (which can be arbitrarily transformed),
7295 * this function calls the GdkWindow::from-embedder: signal to translate
7298 * You should always use this function when writing generic code that
7299 * walks down a window hierarchy.
7301 * See also: gdk_window_coords_to_parent()
7306 gdk_window_coords_from_parent (GdkWindow *window,
7312 g_return_if_fail (GDK_IS_WINDOW (window));
7314 if (gdk_window_is_offscreen (window))
7318 from_embedder (window, parent_x, parent_y, &cx, &cy);
7329 *x = parent_x - window->x;
7332 *y = parent_y - window->y;
7337 * gdk_window_shape_combine_region:
7338 * @window: a #GdkWindow
7339 * @shape_region: (allow-none): region of window to be non-transparent
7340 * @offset_x: X position of @shape_region in @window coordinates
7341 * @offset_y: Y position of @shape_region in @window coordinates
7343 * Makes pixels in @window outside @shape_region be transparent,
7344 * so that the window may be nonrectangular.
7346 * If @shape_region is %NULL, the shape will be unset, so the whole
7347 * window will be opaque again. @offset_x and @offset_y are ignored
7348 * if @shape_region is %NULL.
7350 * On the X11 platform, this uses an X server extension which is
7351 * widely available on most common platforms, but not available on
7352 * very old X servers, and occasionally the implementation will be
7353 * buggy. On servers without the shape extension, this function
7356 * This function works on both toplevel and child windows.
7359 gdk_window_shape_combine_region (GdkWindow *window,
7360 const cairo_region_t *shape_region,
7364 cairo_region_t *old_region, *new_region, *diff;
7366 g_return_if_fail (GDK_IS_WINDOW (window));
7368 if (GDK_WINDOW_DESTROYED (window))
7371 if (!window->shape && shape_region == NULL)
7374 window->shaped = (shape_region != NULL);
7377 cairo_region_destroy (window->shape);
7380 if (GDK_WINDOW_IS_MAPPED (window))
7381 old_region = cairo_region_copy (window->clip_region);
7385 window->shape = cairo_region_copy (shape_region);
7386 cairo_region_translate (window->shape, offset_x, offset_y);
7389 window->shape = NULL;
7391 recompute_visible_regions (window, TRUE, FALSE);
7393 if (gdk_window_has_impl (window) &&
7394 !should_apply_clip_as_shape (window))
7395 apply_shape (window, window->shape);
7399 new_region = cairo_region_copy (window->clip_region);
7401 /* New area in the window, needs invalidation */
7402 diff = cairo_region_copy (new_region);
7403 cairo_region_subtract (diff, old_region);
7405 gdk_window_invalidate_region_full (window, diff, TRUE, CLEAR_BG_ALL);
7407 cairo_region_destroy (diff);
7409 if (!gdk_window_is_toplevel (window))
7411 /* New area in the non-root parent window, needs invalidation */
7412 diff = cairo_region_copy (old_region);
7413 cairo_region_subtract (diff, new_region);
7415 /* Adjust region to parent window coords */
7416 cairo_region_translate (diff, window->x, window->y);
7418 gdk_window_invalidate_region_full (window->parent, diff, TRUE, CLEAR_BG_ALL);
7420 cairo_region_destroy (diff);
7423 cairo_region_destroy (new_region);
7424 cairo_region_destroy (old_region);
7429 do_child_shapes (GdkWindow *window,
7433 cairo_region_t *region;
7437 r.width = window->width;
7438 r.height = window->height;
7440 region = cairo_region_create_rectangle (&r);
7441 remove_child_area (window, NULL, FALSE, region, NULL);
7443 if (merge && window->shape)
7444 cairo_region_subtract (region, window->shape);
7446 gdk_window_shape_combine_region (window, region, 0, 0);
7450 * gdk_window_set_child_shapes:
7451 * @window: a #GdkWindow
7453 * Sets the shape mask of @window to the union of shape masks
7454 * for all children of @window, ignoring the shape mask of @window
7455 * itself. Contrast with gdk_window_merge_child_shapes() which includes
7456 * the shape mask of @window in the masks to be merged.
7459 gdk_window_set_child_shapes (GdkWindow *window)
7461 g_return_if_fail (GDK_IS_WINDOW (window));
7463 do_child_shapes (window, FALSE);
7467 * gdk_window_merge_child_shapes:
7468 * @window: a #GdkWindow
7470 * Merges the shape masks for any child windows into the
7471 * shape mask for @window. i.e. the union of all masks
7472 * for @window and its children will become the new mask
7473 * for @window. See gdk_window_shape_combine_region().
7475 * This function is distinct from gdk_window_set_child_shapes()
7476 * because it includes @window's shape mask in the set of shapes to
7480 gdk_window_merge_child_shapes (GdkWindow *window)
7482 g_return_if_fail (GDK_IS_WINDOW (window));
7484 do_child_shapes (window, TRUE);
7488 * gdk_window_input_shape_combine_region:
7489 * @window: a #GdkWindow
7490 * @shape_region: region of window to be non-transparent
7491 * @offset_x: X position of @shape_region in @window coordinates
7492 * @offset_y: Y position of @shape_region in @window coordinates
7494 * Like gdk_window_shape_combine_region(), but the shape applies
7495 * only to event handling. Mouse events which happen while
7496 * the pointer position corresponds to an unset bit in the
7497 * mask will be passed on the window below @window.
7499 * An input shape is typically used with RGBA windows.
7500 * The alpha channel of the window defines which pixels are
7501 * invisible and allows for nicely antialiased borders,
7502 * and the input shape controls where the window is
7505 * On the X11 platform, this requires version 1.1 of the
7508 * On the Win32 platform, this functionality is not present and the
7509 * function does nothing.
7514 gdk_window_input_shape_combine_region (GdkWindow *window,
7515 const cairo_region_t *shape_region,
7519 GdkWindowImplClass *impl_class;
7521 g_return_if_fail (GDK_IS_WINDOW (window));
7523 if (GDK_WINDOW_DESTROYED (window))
7526 if (window->input_shape)
7527 cairo_region_destroy (window->input_shape);
7531 window->input_shape = cairo_region_copy (shape_region);
7532 cairo_region_translate (window->input_shape, offset_x, offset_y);
7535 window->input_shape = NULL;
7537 if (gdk_window_has_impl (window))
7539 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7540 impl_class->input_shape_combine_region (window, window->input_shape, 0, 0);
7543 /* Pointer may have e.g. moved outside window due to the input mask change */
7544 _gdk_synthesize_crossing_events_for_geometry_change (window);
7548 do_child_input_shapes (GdkWindow *window,
7552 cairo_region_t *region;
7556 r.width = window->width;
7557 r.height = window->height;
7559 region = cairo_region_create_rectangle (&r);
7560 remove_child_area (window, NULL, TRUE, region, NULL);
7562 if (merge && window->shape)
7563 cairo_region_subtract (region, window->shape);
7564 if (merge && window->input_shape)
7565 cairo_region_subtract (region, window->input_shape);
7567 gdk_window_input_shape_combine_region (window, region, 0, 0);
7572 * gdk_window_set_child_input_shapes:
7573 * @window: a #GdkWindow
7575 * Sets the input shape mask of @window to the union of input shape masks
7576 * for all children of @window, ignoring the input shape mask of @window
7577 * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
7578 * the input shape mask of @window in the masks to be merged.
7583 gdk_window_set_child_input_shapes (GdkWindow *window)
7585 g_return_if_fail (GDK_IS_WINDOW (window));
7587 do_child_input_shapes (window, FALSE);
7591 * gdk_window_merge_child_input_shapes:
7592 * @window: a #GdkWindow
7594 * Merges the input shape masks for any child windows into the
7595 * input shape mask for @window. i.e. the union of all input masks
7596 * for @window and its children will become the new input mask
7597 * for @window. See gdk_window_input_shape_combine_region().
7599 * This function is distinct from gdk_window_set_child_input_shapes()
7600 * because it includes @window's input shape mask in the set of
7601 * shapes to be merged.
7606 gdk_window_merge_child_input_shapes (GdkWindow *window)
7608 g_return_if_fail (GDK_IS_WINDOW (window));
7610 do_child_input_shapes (window, TRUE);
7615 * gdk_window_set_static_gravities:
7616 * @window: a #GdkWindow
7617 * @use_static: %TRUE to turn on static gravity
7619 * Set the bit gravity of the given window to static, and flag it so
7620 * all children get static subwindow gravity. This is used if you are
7621 * implementing scary features that involve deep knowledge of the
7622 * windowing system. Don't worry about it unless you have to.
7624 * Return value: %TRUE if the server supports static gravity
7627 gdk_window_set_static_gravities (GdkWindow *window,
7628 gboolean use_static)
7630 GdkWindowImplClass *impl_class;
7632 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7634 if (gdk_window_has_impl (window))
7636 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7637 return impl_class->set_static_gravities (window, use_static);
7644 * gdk_window_get_composited:
7645 * @window: a #GdkWindow
7647 * Determines whether @window is composited.
7649 * See gdk_window_set_composited().
7651 * Returns: %TRUE if the window is composited.
7656 gdk_window_get_composited (GdkWindow *window)
7658 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7660 return window->composited;
7664 * gdk_window_set_composited:
7665 * @window: a #GdkWindow
7666 * @composited: %TRUE to set the window as composited
7668 * Sets a #GdkWindow as composited, or unsets it. Composited
7669 * windows do not automatically have their contents drawn to
7670 * the screen. Drawing is redirected to an offscreen buffer
7671 * and an expose event is emitted on the parent of the composited
7672 * window. It is the responsibility of the parent's expose handler
7673 * to manually merge the off-screen content onto the screen in
7674 * whatever way it sees fit. See <xref linkend="composited-window-example"/>
7677 * It only makes sense for child windows to be composited; see
7678 * gdk_window_set_opacity() if you need translucent toplevel
7681 * An additional effect of this call is that the area of this
7682 * window is no longer clipped from regions marked for
7683 * invalidation on its parent. Draws done on the parent
7684 * window are also no longer clipped by the child.
7686 * This call is only supported on some systems (currently,
7687 * only X11 with new enough Xcomposite and Xdamage extensions).
7688 * You must call gdk_display_supports_composite() to check if
7689 * setting a window as composited is supported before
7690 * attempting to do so.
7695 gdk_window_set_composited (GdkWindow *window,
7696 gboolean composited)
7698 GdkDisplay *display;
7699 GdkWindowImplClass *impl_class;
7701 g_return_if_fail (GDK_IS_WINDOW (window));
7703 composited = composited != FALSE;
7705 if (window->composited == composited)
7709 gdk_window_ensure_native (window);
7711 display = gdk_window_get_display (window);
7713 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
7715 if (composited && (!gdk_display_supports_composite (display) || !impl_class->set_composited))
7717 g_warning ("gdk_window_set_composited called but "
7718 "compositing is not supported");
7722 impl_class->set_composited (window, composited);
7724 recompute_visible_regions (window, TRUE, FALSE);
7726 if (GDK_WINDOW_IS_MAPPED (window))
7727 gdk_window_invalidate_in_parent (window);
7729 window->composited = composited;
7733 * gdk_window_get_modal_hint:
7734 * @window: A toplevel #GdkWindow.
7736 * Determines whether or not the window manager is hinted that @window
7737 * has modal behaviour.
7739 * Return value: whether or not the window has the modal hint set.
7744 gdk_window_get_modal_hint (GdkWindow *window)
7746 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7748 return window->modal_hint;
7752 * gdk_window_get_accept_focus:
7753 * @window: a toplevel #GdkWindow.
7755 * Determines whether or not the desktop environment shuld be hinted that
7756 * the window does not want to receive input focus.
7758 * Return value: whether or not the window should receive input focus.
7763 gdk_window_get_accept_focus (GdkWindow *window)
7765 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7767 return window->accept_focus;
7771 * gdk_window_get_focus_on_map:
7772 * @window: a toplevel #GdkWindow.
7774 * Determines whether or not the desktop environment should be hinted that the
7775 * window does not want to receive input focus when it is mapped.
7777 * Return value: whether or not the window wants to receive input focus when
7783 gdk_window_get_focus_on_map (GdkWindow *window)
7785 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7787 return window->focus_on_map;
7791 * gdk_window_is_input_only:
7792 * @window: a toplevel #GdkWindow
7794 * Determines whether or not the window is an input only window.
7796 * Return value: %TRUE if @window is input only
7801 gdk_window_is_input_only (GdkWindow *window)
7803 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7805 return window->input_only;
7809 * gdk_window_is_shaped:
7810 * @window: a toplevel #GdkWindow
7812 * Determines whether or not the window is shaped.
7814 * Return value: %TRUE if @window is shaped
7819 gdk_window_is_shaped (GdkWindow *window)
7821 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
7823 return window->shaped;
7827 _gdk_window_add_damage (GdkWindow *toplevel,
7828 cairo_region_t *damaged_region)
7830 GdkDisplay *display;
7831 GdkEvent event = { 0, };
7832 event.expose.type = GDK_DAMAGE;
7833 event.expose.window = toplevel;
7834 event.expose.send_event = FALSE;
7835 event.expose.region = damaged_region;
7836 cairo_region_get_extents (event.expose.region, &event.expose.area);
7837 display = gdk_window_get_display (event.expose.window);
7838 _gdk_event_queue_append (display, gdk_event_copy (&event));
7841 /* Gets the toplevel for a window as used for events,
7842 i.e. including offscreen parents */
7844 get_event_parent (GdkWindow *window)
7846 if (gdk_window_is_offscreen (window))
7847 return gdk_offscreen_window_get_embedder ((GdkWindow *)window);
7849 return window->parent;
7852 /* Gets the toplevel for a window as used for events,
7853 i.e. including offscreen parents going up to the native
7856 get_event_toplevel (GdkWindow *window)
7860 while ((parent = get_event_parent (window)) != NULL &&
7861 (parent->window_type != GDK_WINDOW_ROOT))
7868 _gdk_window_event_parent_of (GdkWindow *parent,
7879 w = get_event_parent (w);
7886 update_cursor (GdkDisplay *display,
7889 GdkWindow *cursor_window, *parent, *toplevel;
7890 GdkWindow *pointer_window;
7891 GdkWindowImplClass *impl_class;
7892 GdkPointerWindowInfo *pointer_info;
7893 GdkDeviceGrabInfo *grab;
7896 pointer_info = _gdk_display_get_pointer_info (display, device);
7897 pointer_window = pointer_info->window_under_pointer;
7899 /* We ignore the serials here and just pick the last grab
7900 we've sent, as that would shortly be used anyway. */
7901 grab = _gdk_display_get_last_device_grab (display, device);
7904 /* the pointer is not in a descendant of the grab window */
7905 !_gdk_window_event_parent_of (grab->window, pointer_window))
7907 /* use the cursor from the grab window */
7908 cursor_window = grab->window;
7912 /* otherwise use the cursor from the pointer window */
7913 cursor_window = pointer_window;
7916 /* Find the first window with the cursor actually set, as
7917 the cursor is inherited from the parent */
7918 while (cursor_window->cursor == NULL &&
7919 (parent = get_event_parent (cursor_window)) != NULL &&
7920 parent->window_type != GDK_WINDOW_ROOT)
7921 cursor_window = parent;
7923 cursor = g_hash_table_lookup (cursor_window->device_cursor, device);
7926 cursor = cursor_window->cursor;
7928 /* Set all cursors on toplevel, otherwise its tricky to keep track of
7929 * which native window has what cursor set. */
7930 toplevel = get_event_toplevel (pointer_window);
7931 impl_class = GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl);
7932 impl_class->set_device_cursor (toplevel, device, cursor);
7936 point_in_window (GdkWindow *window,
7941 x >= 0 && x < window->width &&
7942 y >= 0 && y < window->height &&
7943 (window->shape == NULL ||
7944 cairo_region_contains_point (window->shape,
7946 (window->input_shape == NULL ||
7947 cairo_region_contains_point (window->input_shape,
7952 convert_native_coords_to_toplevel (GdkWindow *window,
7955 gdouble *toplevel_x,
7956 gdouble *toplevel_y)
7963 while (!gdk_window_is_toplevel (window))
7967 window = window->parent;
7977 convert_toplevel_coords_to_window (GdkWindow *window,
7985 GList *children, *l;
7991 while ((parent = get_event_parent (window)) != NULL &&
7992 (parent->window_type != GDK_WINDOW_ROOT))
7994 children = g_list_prepend (children, window);
7998 for (l = children; l != NULL; l = l->next)
7999 gdk_window_coords_from_parent (l->data, x, y, &x, &y);
8001 g_list_free (children);
8008 pick_embedded_child (GdkWindow *window,
8015 g_signal_emit (window,
8016 signals[PICK_EMBEDDED_CHILD], 0,
8023 _gdk_window_find_child_at (GdkWindow *window,
8028 double child_x, child_y;
8031 if (point_in_window (window, x, y))
8033 /* Children is ordered in reverse stack order, i.e. first is topmost */
8034 for (l = window->children; l != NULL; l = l->next)
8038 if (!GDK_WINDOW_IS_MAPPED (sub))
8041 gdk_window_coords_from_parent ((GdkWindow *)sub,
8043 &child_x, &child_y);
8044 if (point_in_window (sub, child_x, child_y))
8045 return (GdkWindow *)sub;
8048 if (window->num_offscreen_children > 0)
8050 sub = pick_embedded_child (window,
8053 return (GdkWindow *)sub;
8061 _gdk_window_find_descendant_at (GdkWindow *window,
8068 gdouble child_x, child_y;
8072 if (point_in_window (window, x, y))
8077 /* Children is ordered in reverse stack order, i.e. first is topmost */
8078 for (l = window->children; l != NULL; l = l->next)
8082 if (!GDK_WINDOW_IS_MAPPED (sub))
8085 gdk_window_coords_from_parent ((GdkWindow *)sub,
8087 &child_x, &child_y);
8088 if (point_in_window (sub, child_x, child_y))
8098 window->num_offscreen_children > 0)
8100 sub = pick_embedded_child (window,
8106 from_embedder (sub, x, y, &x, &y);
8114 /* Not in window at all */
8128 * @window: a toplevel #GdkWindow
8130 * Emits a short beep associated to @window in the appropriate
8131 * display, if supported. Otherwise, emits a short beep on
8132 * the display just as gdk_display_beep().
8137 gdk_window_beep (GdkWindow *window)
8139 GdkDisplay *display;
8140 GdkWindow *toplevel;
8142 g_return_if_fail (GDK_IS_WINDOW (window));
8144 if (GDK_WINDOW_DESTROYED (window))
8147 toplevel = get_event_toplevel (window);
8148 display = gdk_window_get_display (window);
8152 if (GDK_WINDOW_IMPL_GET_CLASS (toplevel->impl)->beep (toplevel))
8156 /* If windows fail to beep, we beep the display. */
8157 gdk_display_beep (display);
8161 * gdk_window_set_support_multidevice:
8162 * @window: a #GdkWindow.
8163 * @support_multidevice: %TRUE to enable multidevice support in @window.
8165 * This function will enable multidevice features in @window.
8167 * Multidevice aware windows will need to handle properly multiple,
8168 * per device enter/leave events, device grabs and grab ownerships.
8173 gdk_window_set_support_multidevice (GdkWindow *window,
8174 gboolean support_multidevice)
8176 g_return_if_fail (GDK_IS_WINDOW (window));
8178 if (GDK_WINDOW_DESTROYED (window))
8181 if (window->support_multidevice == support_multidevice)
8184 window->support_multidevice = support_multidevice;
8186 /* FIXME: What to do if called when some pointers are inside the window ? */
8190 * gdk_window_get_support_multidevice:
8191 * @window: a #GdkWindow.
8193 * Returns %TRUE if the window is aware of the existence of multiple
8196 * Returns: %TRUE if the window handles multidevice features.
8201 gdk_window_get_support_multidevice (GdkWindow *window)
8203 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
8205 if (GDK_WINDOW_DESTROYED (window))
8208 return window->support_multidevice;
8211 static const guint type_masks[] = {
8212 GDK_SUBSTRUCTURE_MASK, /* GDK_DELETE = 0 */
8213 GDK_STRUCTURE_MASK, /* GDK_DESTROY = 1 */
8214 GDK_EXPOSURE_MASK, /* GDK_EXPOSE = 2 */
8215 GDK_POINTER_MOTION_MASK, /* GDK_MOTION_NOTIFY = 3 */
8216 GDK_BUTTON_PRESS_MASK, /* GDK_BUTTON_PRESS = 4 */
8217 GDK_BUTTON_PRESS_MASK, /* GDK_2BUTTON_PRESS = 5 */
8218 GDK_BUTTON_PRESS_MASK, /* GDK_3BUTTON_PRESS = 6 */
8219 GDK_BUTTON_RELEASE_MASK, /* GDK_BUTTON_RELEASE = 7 */
8220 GDK_KEY_PRESS_MASK, /* GDK_KEY_PRESS = 8 */
8221 GDK_KEY_RELEASE_MASK, /* GDK_KEY_RELEASE = 9 */
8222 GDK_ENTER_NOTIFY_MASK, /* GDK_ENTER_NOTIFY = 10 */
8223 GDK_LEAVE_NOTIFY_MASK, /* GDK_LEAVE_NOTIFY = 11 */
8224 GDK_FOCUS_CHANGE_MASK, /* GDK_FOCUS_CHANGE = 12 */
8225 GDK_STRUCTURE_MASK, /* GDK_CONFIGURE = 13 */
8226 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_MAP = 14 */
8227 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_UNMAP = 15 */
8228 GDK_PROPERTY_CHANGE_MASK, /* GDK_PROPERTY_NOTIFY = 16 */
8229 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_CLEAR = 17 */
8230 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_REQUEST = 18 */
8231 GDK_PROPERTY_CHANGE_MASK, /* GDK_SELECTION_NOTIFY = 19 */
8232 GDK_PROXIMITY_IN_MASK, /* GDK_PROXIMITY_IN = 20 */
8233 GDK_PROXIMITY_OUT_MASK, /* GDK_PROXIMITY_OUT = 21 */
8234 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_ENTER = 22 */
8235 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_LEAVE = 23 */
8236 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_MOTION = 24 */
8237 GDK_ALL_EVENTS_MASK, /* GDK_DRAG_STATUS = 25 */
8238 GDK_ALL_EVENTS_MASK, /* GDK_DROP_START = 26 */
8239 GDK_ALL_EVENTS_MASK, /* GDK_DROP_FINISHED = 27 */
8240 GDK_ALL_EVENTS_MASK, /* GDK_CLIENT_EVENT = 28 */
8241 GDK_VISIBILITY_NOTIFY_MASK, /* GDK_VISIBILITY_NOTIFY = 29 */
8242 GDK_EXPOSURE_MASK, /* GDK_NO_EXPOSE = 30 */
8243 GDK_SCROLL_MASK | GDK_SMOOTH_SCROLL_MASK,/* GDK_SCROLL= 31 */
8244 0, /* GDK_WINDOW_STATE = 32 */
8245 0, /* GDK_SETTING = 33 */
8246 0, /* GDK_OWNER_CHANGE = 34 */
8247 0, /* GDK_GRAB_BROKEN = 35 */
8248 0, /* GDK_DAMAGE = 36 */
8249 GDK_TOUCH_MASK, /* GDK_TOUCH_BEGIN = 37 */
8250 GDK_TOUCH_MASK, /* GDK_TOUCH_UPDATE = 38 */
8251 GDK_TOUCH_MASK, /* GDK_TOUCH_END = 39 */
8252 GDK_TOUCH_MASK /* GDK_TOUCH_CANCEL = 40 */
8254 G_STATIC_ASSERT (G_N_ELEMENTS (type_masks) == GDK_EVENT_LAST);
8256 /* send motion events if the right buttons are down */
8258 update_evmask_for_button_motion (guint evmask,
8259 GdkModifierType mask)
8261 if (evmask & GDK_BUTTON_MOTION_MASK &&
8262 mask & (GDK_BUTTON1_MASK |
8267 evmask |= GDK_POINTER_MOTION_MASK;
8269 if ((evmask & GDK_BUTTON1_MOTION_MASK && mask & GDK_BUTTON1_MASK) ||
8270 (evmask & GDK_BUTTON2_MOTION_MASK && mask & GDK_BUTTON2_MASK) ||
8271 (evmask & GDK_BUTTON3_MOTION_MASK && mask & GDK_BUTTON3_MASK))
8272 evmask |= GDK_POINTER_MOTION_MASK;
8278 is_button_type (GdkEventType type)
8280 return type == GDK_BUTTON_PRESS ||
8281 type == GDK_2BUTTON_PRESS ||
8282 type == GDK_3BUTTON_PRESS ||
8283 type == GDK_BUTTON_RELEASE ||
8284 type == GDK_TOUCH_BEGIN ||
8285 type == GDK_TOUCH_END ||
8290 is_motion_type (GdkEventType type)
8292 return type == GDK_MOTION_NOTIFY ||
8293 type == GDK_TOUCH_UPDATE ||
8294 type == GDK_ENTER_NOTIFY ||
8295 type == GDK_LEAVE_NOTIFY;
8299 is_touch_type (GdkEventType type)
8301 return type == GDK_TOUCH_BEGIN ||
8302 type == GDK_TOUCH_UPDATE ||
8303 type == GDK_TOUCH_END ||
8304 type == GDK_TOUCH_CANCEL;
8308 find_common_ancestor (GdkWindow *win1,
8312 GList *path1 = NULL, *path2 = NULL;
8313 GList *list1, *list2;
8316 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8318 path1 = g_list_prepend (path1, tmp);
8319 tmp = get_event_parent (tmp);
8323 while (tmp != NULL && tmp->window_type != GDK_WINDOW_ROOT)
8325 path2 = g_list_prepend (path2, tmp);
8326 tmp = get_event_parent (tmp);
8332 while (list1 && list2 && (list1->data == list2->data))
8335 list1 = g_list_next (list1);
8336 list2 = g_list_next (list2);
8338 g_list_free (path1);
8339 g_list_free (path2);
8345 _gdk_make_event (GdkWindow *window,
8347 GdkEvent *event_in_queue,
8348 gboolean before_event)
8350 GdkEvent *event = gdk_event_new (type);
8352 GdkModifierType the_state;
8354 the_time = gdk_event_get_time (event_in_queue);
8355 gdk_event_get_state (event_in_queue, &the_state);
8357 event->any.window = g_object_ref (window);
8358 event->any.send_event = FALSE;
8359 if (event_in_queue && event_in_queue->any.send_event)
8360 event->any.send_event = TRUE;
8364 case GDK_MOTION_NOTIFY:
8365 event->motion.time = the_time;
8366 event->motion.axes = NULL;
8367 event->motion.state = the_state;
8370 case GDK_BUTTON_PRESS:
8371 case GDK_2BUTTON_PRESS:
8372 case GDK_3BUTTON_PRESS:
8373 case GDK_BUTTON_RELEASE:
8374 event->button.time = the_time;
8375 event->button.axes = NULL;
8376 event->button.state = the_state;
8379 case GDK_TOUCH_BEGIN:
8380 case GDK_TOUCH_UPDATE:
8382 case GDK_TOUCH_CANCEL:
8383 event->touch.time = the_time;
8384 event->touch.axes = NULL;
8385 event->touch.state = the_state;
8389 event->scroll.time = the_time;
8390 event->scroll.state = the_state;
8394 case GDK_KEY_RELEASE:
8395 event->key.time = the_time;
8396 event->key.state = the_state;
8399 case GDK_ENTER_NOTIFY:
8400 case GDK_LEAVE_NOTIFY:
8401 event->crossing.time = the_time;
8402 event->crossing.state = the_state;
8405 case GDK_PROPERTY_NOTIFY:
8406 event->property.time = the_time;
8407 event->property.state = the_state;
8410 case GDK_SELECTION_CLEAR:
8411 case GDK_SELECTION_REQUEST:
8412 case GDK_SELECTION_NOTIFY:
8413 event->selection.time = the_time;
8416 case GDK_PROXIMITY_IN:
8417 case GDK_PROXIMITY_OUT:
8418 event->proximity.time = the_time;
8421 case GDK_DRAG_ENTER:
8422 case GDK_DRAG_LEAVE:
8423 case GDK_DRAG_MOTION:
8424 case GDK_DRAG_STATUS:
8425 case GDK_DROP_START:
8426 case GDK_DROP_FINISHED:
8427 event->dnd.time = the_time;
8430 case GDK_FOCUS_CHANGE:
8434 case GDK_CLIENT_EVENT:
8435 case GDK_VISIBILITY_NOTIFY:
8446 _gdk_event_queue_insert_before (gdk_window_get_display (window), event_in_queue, event);
8448 _gdk_event_queue_insert_after (gdk_window_get_display (window), event_in_queue, event);
8451 _gdk_event_queue_append (gdk_window_get_display (window), event);
8457 send_crossing_event (GdkDisplay *display,
8458 GdkWindow *toplevel,
8461 GdkCrossingMode mode,
8462 GdkNotifyType notify_type,
8463 GdkWindow *subwindow,
8465 GdkDevice *source_device,
8468 GdkModifierType mask,
8470 GdkEvent *event_in_queue,
8474 guint32 window_event_mask, type_event_mask;
8475 GdkDeviceGrabInfo *grab;
8476 GdkTouchGrabInfo *touch_grab = NULL;
8477 GdkPointerWindowInfo *pointer_info;
8478 gboolean block_event = FALSE;
8479 GdkEventSequence *sequence;
8481 grab = _gdk_display_has_device_grab (display, device, serial);
8482 pointer_info = _gdk_display_get_pointer_info (display, device);
8484 sequence = gdk_event_get_event_sequence (event_in_queue);
8486 touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
8490 if (window != touch_grab->window)
8493 window_event_mask = touch_grab->event_mask;
8495 else if (grab != NULL &&
8496 !grab->owner_events)
8498 /* !owner_event => only report events wrt grab window, ignore rest */
8499 if ((GdkWindow *)window != grab->window)
8501 window_event_mask = grab->event_mask;
8504 window_event_mask = window->event_mask;
8506 if (type == GDK_ENTER_NOTIFY &&
8507 (pointer_info->need_touch_press_enter ||
8508 gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN) &&
8509 mode != GDK_CROSSING_TOUCH_BEGIN &&
8510 mode != GDK_CROSSING_TOUCH_END)
8512 pointer_info->need_touch_press_enter = TRUE;
8515 else if (type == GDK_LEAVE_NOTIFY)
8517 type_event_mask = GDK_LEAVE_NOTIFY_MASK;
8518 window->devices_inside = g_list_remove (window->devices_inside, device);
8520 if (!window->support_multidevice && window->devices_inside)
8522 /* Block leave events unless it's the last pointer */
8528 type_event_mask = GDK_ENTER_NOTIFY_MASK;
8530 if (!window->support_multidevice && window->devices_inside)
8532 /* Only emit enter events for the first device */
8536 if (gdk_device_get_device_type (device) == GDK_DEVICE_TYPE_MASTER &&
8537 gdk_device_get_mode (device) != GDK_MODE_DISABLED &&
8538 !g_list_find (window->devices_inside, device))
8539 window->devices_inside = g_list_prepend (window->devices_inside, device);
8545 if (window_event_mask & type_event_mask)
8547 event = _gdk_make_event ((GdkWindow *)window, type, event_in_queue, TRUE);
8548 gdk_event_set_device (event, device);
8551 gdk_event_set_source_device (event, source_device);
8553 event->crossing.time = time_;
8554 event->crossing.subwindow = subwindow;
8556 g_object_ref (subwindow);
8557 convert_toplevel_coords_to_window ((GdkWindow *)window,
8558 toplevel_x, toplevel_y,
8559 &event->crossing.x, &event->crossing.y);
8560 event->crossing.x_root = toplevel_x + toplevel->x;
8561 event->crossing.y_root = toplevel_y + toplevel->y;
8562 event->crossing.mode = mode;
8563 event->crossing.detail = notify_type;
8564 event->crossing.focus = FALSE;
8565 event->crossing.state = mask;
8570 /* The coordinates are in the toplevel window that src/dest are in.
8571 * src and dest are always (if != NULL) in the same toplevel, as
8572 * we get a leave-notify and set the window_under_pointer to null
8573 * before crossing to another toplevel.
8576 _gdk_synthesize_crossing_events (GdkDisplay *display,
8580 GdkDevice *source_device,
8581 GdkCrossingMode mode,
8584 GdkModifierType mask,
8586 GdkEvent *event_in_queue,
8588 gboolean non_linear)
8591 GdkWindow *win, *last, *next;
8595 GdkWindow *toplevel;
8596 GdkNotifyType notify_type;
8598 /* TODO: Don't send events to toplevel, as we get those from the windowing system */
8603 return; /* No crossings generated between src and dest */
8605 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER)
8607 if (a && gdk_window_get_device_events (src, device) == 0)
8610 if (b && gdk_window_get_device_events (dest, device) == 0)
8617 c = find_common_ancestor (a, b);
8619 non_linear |= (c != a) && (c != b);
8621 if (a) /* There might not be a source (i.e. if no previous pointer_in_window) */
8623 toplevel = gdk_window_get_toplevel (a);
8625 /* Traverse up from a to (excluding) c sending leave events */
8627 notify_type = GDK_NOTIFY_NONLINEAR;
8629 notify_type = GDK_NOTIFY_INFERIOR;
8631 notify_type = GDK_NOTIFY_ANCESTOR;
8632 send_crossing_event (display, toplevel,
8633 a, GDK_LEAVE_NOTIFY,
8636 NULL, device, source_device,
8637 toplevel_x, toplevel_y,
8645 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8647 notify_type = GDK_NOTIFY_VIRTUAL;
8650 win = get_event_parent (a);
8651 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8653 send_crossing_event (display, toplevel,
8654 win, GDK_LEAVE_NOTIFY,
8658 device, source_device,
8659 toplevel_x, toplevel_y,
8665 win = get_event_parent (win);
8670 if (b) /* Might not be a dest, e.g. if we're moving out of the window */
8672 toplevel = gdk_window_get_toplevel ((GdkWindow *)b);
8674 /* Traverse down from c to b */
8678 win = get_event_parent (b);
8679 while (win != c && win->window_type != GDK_WINDOW_ROOT)
8681 path = g_list_prepend (path, win);
8682 win = get_event_parent (win);
8686 notify_type = GDK_NOTIFY_NONLINEAR_VIRTUAL;
8688 notify_type = GDK_NOTIFY_VIRTUAL;
8694 list = g_list_next (list);
8700 send_crossing_event (display, toplevel,
8701 win, GDK_ENTER_NOTIFY,
8705 device, source_device,
8706 toplevel_x, toplevel_y,
8716 notify_type = GDK_NOTIFY_NONLINEAR;
8718 notify_type = GDK_NOTIFY_ANCESTOR;
8720 notify_type = GDK_NOTIFY_INFERIOR;
8722 send_crossing_event (display, toplevel,
8723 b, GDK_ENTER_NOTIFY,
8727 device, source_device,
8728 toplevel_x, toplevel_y,
8735 /* Returns the window inside the event window with the pointer in it
8736 * at the specified coordinates, or NULL if its not in any child of
8737 * the toplevel. It also takes into account !owner_events grabs.
8740 get_pointer_window (GdkDisplay *display,
8741 GdkWindow *event_window,
8747 GdkWindow *pointer_window;
8748 GdkDeviceGrabInfo *grab;
8749 GdkPointerWindowInfo *pointer_info;
8751 pointer_info = _gdk_display_get_pointer_info (display, device);
8753 if (event_window == pointer_info->toplevel_under_pointer)
8755 _gdk_window_find_descendant_at (event_window,
8756 toplevel_x, toplevel_y,
8759 pointer_window = NULL;
8761 grab = _gdk_display_has_device_grab (display, device, serial);
8763 !grab->owner_events &&
8764 pointer_window != grab->window)
8765 pointer_window = NULL;
8767 return pointer_window;
8771 _gdk_display_set_window_under_pointer (GdkDisplay *display,
8775 GdkPointerWindowInfo *device_info;
8777 device_info = _gdk_display_get_pointer_info (display, device);
8779 if (device_info->window_under_pointer)
8780 g_object_unref (device_info->window_under_pointer);
8781 device_info->window_under_pointer = window;
8785 g_object_ref (window);
8786 update_cursor (display, device);
8789 _gdk_display_enable_motion_hints (display, device);
8794 * @window: the #GdkWindow which will own the grab (the grab window).
8795 * @owner_events: if %FALSE then all pointer events are reported with respect to
8796 * @window and are only reported if selected by @event_mask. If %TRUE then pointer
8797 * events for this application are reported as normal, but pointer events outside
8798 * this application are reported with respect to @window and only if selected by
8799 * @event_mask. In either mode, unreported events are discarded.
8800 * @event_mask: specifies the event mask, which is used in accordance with
8801 * @owner_events. Note that only pointer events (i.e. button and motion events)
8803 * @confine_to: (allow-none): If non-%NULL, the pointer will be confined to this
8804 * window during the grab. If the pointer is outside @confine_to, it will
8805 * automatically be moved to the closest edge of @confine_to and enter
8806 * and leave events will be generated as necessary.
8807 * @cursor: (allow-none): the cursor to display while the grab is active. If this is %NULL then
8808 * the normal cursors are used for @window and its descendants, and the cursor
8809 * for @window is used for all other windows.
8810 * @time_: the timestamp of the event which led to this pointer grab. This usually
8811 * comes from a #GdkEventButton struct, though %GDK_CURRENT_TIME can be used if
8812 * the time isn't known.
8814 * Grabs the pointer (usually a mouse) so that all events are passed to this
8815 * application until the pointer is ungrabbed with gdk_pointer_ungrab(), or
8816 * the grab window becomes unviewable.
8817 * This overrides any previous pointer grab by this client.
8819 * Pointer grabs are used for operations which need complete control over mouse
8820 * events, even if the mouse leaves the application.
8821 * For example in GTK+ it is used for Drag and Drop, for dragging the handle in
8822 * the #GtkHPaned and #GtkVPaned widgets.
8824 * Note that if the event mask of an X window has selected both button press and
8825 * button release events, then a button press event will cause an automatic
8826 * pointer grab until the button is released.
8827 * X does this automatically since most applications expect to receive button
8828 * press and release events in pairs.
8829 * It is equivalent to a pointer grab on the window with @owner_events set to
8832 * If you set up anything at the time you take the grab that needs to be cleaned
8833 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8834 * are emitted when the grab ends unvoluntarily.
8836 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8838 * Deprecated: 3.0: Use gdk_device_grab() instead.
8841 gdk_pointer_grab (GdkWindow * window,
8842 gboolean owner_events,
8843 GdkEventMask event_mask,
8844 GdkWindow * confine_to,
8849 GdkDisplay *display;
8850 GdkDeviceManager *device_manager;
8852 GdkGrabStatus res = 0;
8854 GList *devices, *dev;
8856 g_return_val_if_fail (window != NULL, 0);
8857 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8858 g_return_val_if_fail (confine_to == NULL || GDK_IS_WINDOW (confine_to), 0);
8860 /* We need a native window for confine to to work, ensure we have one */
8863 if (!gdk_window_ensure_native (confine_to))
8865 g_warning ("Can't confine to grabbed window, not native");
8870 /* Non-viewable client side window => fail */
8871 if (!_gdk_window_has_impl (window) &&
8872 !gdk_window_is_viewable (window))
8873 return GDK_GRAB_NOT_VIEWABLE;
8875 native = gdk_window_get_toplevel (window);
8876 while (gdk_window_is_offscreen (native))
8878 native = gdk_offscreen_window_get_embedder (native);
8880 if (native == NULL ||
8881 (!_gdk_window_has_impl (native) &&
8882 !gdk_window_is_viewable (native)))
8883 return GDK_GRAB_NOT_VIEWABLE;
8885 native = gdk_window_get_toplevel (native);
8888 display = gdk_window_get_display (window);
8890 serial = _gdk_display_get_next_serial (display);
8891 device_manager = gdk_display_get_device_manager (display);
8892 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8894 /* FIXME: Should this be generic to all backends? */
8895 /* FIXME: What happens with extended devices? */
8896 for (dev = devices; dev; dev = dev->next)
8900 if (gdk_device_get_source (device) != GDK_SOURCE_MOUSE)
8903 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
8906 get_native_grab_event_mask (event_mask),
8911 if (res == GDK_GRAB_SUCCESS)
8912 _gdk_display_add_device_grab (display,
8924 /* FIXME: handle errors when grabbing */
8926 g_list_free (devices);
8932 * gdk_keyboard_grab:
8933 * @window: the #GdkWindow which will own the grab (the grab window).
8934 * @owner_events: if %FALSE then all keyboard events are reported with respect to
8935 * @window. If %TRUE then keyboard events for this application are
8936 * reported as normal, but keyboard events outside this application
8937 * are reported with respect to @window. Both key press and key
8938 * release events are always reported, independant of the event mask
8939 * set by the application.
8940 * @time_: a timestamp from a #GdkEvent, or %GDK_CURRENT_TIME if no timestamp is
8943 * Grabs the keyboard so that all events are passed to this
8944 * application until the keyboard is ungrabbed with gdk_keyboard_ungrab().
8945 * This overrides any previous keyboard grab by this client.
8947 * If you set up anything at the time you take the grab that needs to be cleaned
8948 * up when the grab ends, you should handle the #GdkEventGrabBroken events that
8949 * are emitted when the grab ends unvoluntarily.
8951 * Returns: %GDK_GRAB_SUCCESS if the grab was successful.
8953 * Deprecated: 3.0: Use gdk_device_grab() instead.
8956 gdk_keyboard_grab (GdkWindow *window,
8957 gboolean owner_events,
8961 GdkDisplay *display;
8962 GdkDeviceManager *device_manager;
8964 GdkGrabStatus res = 0;
8966 GList *devices, *dev;
8968 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
8970 /* Non-viewable client side window => fail */
8971 if (!_gdk_window_has_impl (window) &&
8972 !gdk_window_is_viewable (window))
8973 return GDK_GRAB_NOT_VIEWABLE;
8975 native = gdk_window_get_toplevel (window);
8977 while (gdk_window_is_offscreen (native))
8979 native = gdk_offscreen_window_get_embedder (native);
8981 if (native == NULL ||
8982 (!_gdk_window_has_impl (native) &&
8983 !gdk_window_is_viewable (native)))
8984 return GDK_GRAB_NOT_VIEWABLE;
8986 native = gdk_window_get_toplevel (native);
8989 display = gdk_window_get_display (window);
8990 serial = _gdk_display_get_next_serial (display);
8991 device_manager = gdk_display_get_device_manager (display);
8992 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
8994 /* FIXME: Should this be generic to all backends? */
8995 /* FIXME: What happens with extended devices? */
8996 for (dev = devices; dev; dev = dev->next)
9000 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
9003 res = GDK_DEVICE_GET_CLASS (device)->grab (device,
9006 GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
9011 if (res == GDK_GRAB_SUCCESS)
9012 _gdk_display_add_device_grab (display,
9023 /* FIXME: handle errors when grabbing */
9025 g_list_free (devices);
9031 * gdk_window_geometry_changed:
9032 * @window: an embedded offscreen #GdkWindow
9034 * This function informs GDK that the geometry of an embedded
9035 * offscreen window has changed. This is necessary for GDK to keep
9036 * track of which offscreen window the pointer is in.
9041 gdk_window_geometry_changed (GdkWindow *window)
9043 _gdk_synthesize_crossing_events_for_geometry_change (window);
9047 source_events_device_added (GdkDeviceManager *device_manager,
9052 GdkEventMask event_mask;
9053 GdkInputSource source;
9055 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_FLOATING)
9059 source = gdk_device_get_source (device);
9061 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
9062 GINT_TO_POINTER (source)));
9064 gdk_window_set_device_events (window, device, event_mask);
9068 source_events_device_changed (GdkDeviceManager *device_manager,
9073 GdkInputSource source;
9074 GdkEventMask event_mask;
9078 type = gdk_device_get_device_type (device);
9079 source = gdk_device_get_source (device);
9081 event_mask = GPOINTER_TO_INT (g_hash_table_lookup (window->source_event_masks,
9082 GINT_TO_POINTER (source)));
9087 if (type == GDK_DEVICE_TYPE_FLOATING)
9089 /* The device was just floated, enable its event mask */
9090 gdk_window_set_device_events (window, device, event_mask);
9092 else if (type == GDK_DEVICE_TYPE_SLAVE)
9093 gdk_window_set_device_events (window, device, 0);
9097 * gdk_window_set_source_events:
9098 * @window: a #GdkWindow
9099 * @source: a #GdkInputSource to define the source class.
9100 * @event_mask: event mask for @window
9102 * Sets the event mask for any floating device (i.e. not attached to any
9103 * visible pointer) that has the source defined as @source. This event
9104 * mask will be applied both to currently existing, newly added devices
9105 * after this call, and devices being attached/detached.
9110 gdk_window_set_source_events (GdkWindow *window,
9111 GdkInputSource source,
9112 GdkEventMask event_mask)
9114 GdkDeviceManager *device_manager;
9115 GdkDisplay *display;
9119 g_return_if_fail (GDK_IS_WINDOW (window));
9121 display = gdk_window_get_display (window);
9122 device_manager = gdk_display_get_device_manager (display);
9124 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING);
9126 /* Set event mask for existing devices */
9127 for (d = devices; d; d = d->next)
9129 GdkDevice *device = d->data;
9131 if (source == gdk_device_get_source (device))
9132 gdk_window_set_device_events (window, device, event_mask);
9135 g_list_free (devices);
9137 /* Update accounting */
9138 if (G_UNLIKELY (!window->source_event_masks))
9139 window->source_event_masks = g_hash_table_new (NULL, NULL);
9142 g_hash_table_insert (window->source_event_masks,
9143 GUINT_TO_POINTER (source),
9144 GUINT_TO_POINTER (event_mask));
9146 g_hash_table_remove (window->source_event_masks,
9147 GUINT_TO_POINTER (source));
9149 size = g_hash_table_size (window->source_event_masks);
9151 /* Update handler if needed */
9152 if (!window->device_added_handler_id && size > 0)
9154 window->device_added_handler_id =
9155 g_signal_connect (device_manager, "device-added",
9156 G_CALLBACK (source_events_device_added), window);
9157 window->device_changed_handler_id =
9158 g_signal_connect (device_manager, "device-changed",
9159 G_CALLBACK (source_events_device_changed), window);
9161 else if (window->device_added_handler_id && size == 0)
9162 g_signal_handler_disconnect (device_manager, window->device_added_handler_id);
9166 * gdk_window_get_source_events:
9167 * @window: a #GdkWindow
9168 * @source: a #GdkInputSource to define the source class.
9170 * Returns the event mask for @window corresponding to the device class specified
9173 * Returns: source event mask for @window
9176 gdk_window_get_source_events (GdkWindow *window,
9177 GdkInputSource source)
9179 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
9181 return GPOINTER_TO_UINT (g_hash_table_lookup (window->source_event_masks,
9182 GUINT_TO_POINTER (source)));
9186 do_synthesize_crossing_event (gpointer data)
9188 GdkDisplay *display;
9189 GdkWindow *changed_toplevel;
9190 GHashTableIter iter;
9191 gpointer key, value;
9194 changed_toplevel = data;
9196 changed_toplevel->synthesize_crossing_event_queued = FALSE;
9198 if (GDK_WINDOW_DESTROYED (changed_toplevel))
9201 display = gdk_window_get_display (changed_toplevel);
9202 serial = _gdk_display_get_next_serial (display);
9203 g_hash_table_iter_init (&iter, display->pointers_info);
9205 while (g_hash_table_iter_next (&iter, &key, &value))
9207 GdkWindow *new_window_under_pointer;
9208 GdkPointerWindowInfo *pointer_info = value;
9209 GdkDevice *device = key;
9211 if (changed_toplevel == pointer_info->toplevel_under_pointer)
9213 new_window_under_pointer =
9214 get_pointer_window (display, changed_toplevel,
9216 pointer_info->toplevel_x,
9217 pointer_info->toplevel_y,
9219 if (new_window_under_pointer != pointer_info->window_under_pointer)
9221 GdkDevice *source_device;
9223 if (pointer_info->last_slave)
9224 source_device = pointer_info->last_slave;
9226 source_device = device;
9228 _gdk_synthesize_crossing_events (display,
9229 pointer_info->window_under_pointer,
9230 new_window_under_pointer,
9231 device, source_device,
9232 GDK_CROSSING_NORMAL,
9233 pointer_info->toplevel_x,
9234 pointer_info->toplevel_y,
9235 pointer_info->state,
9240 _gdk_display_set_window_under_pointer (display, device, new_window_under_pointer);
9249 _gdk_synthesize_crossing_events_for_geometry_change (GdkWindow *changed_window)
9251 GdkWindow *toplevel;
9253 toplevel = get_event_toplevel (changed_window);
9255 if (!toplevel->synthesize_crossing_event_queued)
9257 toplevel->synthesize_crossing_event_queued = TRUE;
9259 gdk_threads_add_idle_full (GDK_PRIORITY_EVENTS - 1,
9260 do_synthesize_crossing_event,
9261 g_object_ref (toplevel),
9266 /* Don't use for crossing events */
9268 get_event_window (GdkDisplay *display,
9270 GdkEventSequence *sequence,
9271 GdkWindow *pointer_window,
9273 GdkModifierType mask,
9275 gboolean pointer_emulated,
9278 guint evmask, emulated_mask = 0;
9279 GdkWindow *grab_window;
9280 GdkDeviceGrabInfo *grab;
9281 GdkTouchGrabInfo *touch_grab;
9283 touch_grab = _gdk_display_has_touch_grab (display, device, sequence, serial);
9284 grab = _gdk_display_get_last_device_grab (display, device);
9286 if (is_touch_type (type) && pointer_emulated)
9290 case GDK_TOUCH_BEGIN:
9291 emulated_mask |= GDK_BUTTON_PRESS_MASK;
9293 case GDK_TOUCH_UPDATE:
9294 emulated_mask |= GDK_POINTER_MOTION_MASK;
9297 emulated_mask |= GDK_BUTTON_RELEASE_MASK;
9303 if (touch_grab != NULL &&
9304 (!grab || grab->implicit || touch_grab->serial >= grab->serial_start))
9306 evmask = touch_grab->event_mask;
9307 evmask = update_evmask_for_button_motion (evmask, mask);
9309 if (evmask & (type_masks[type] | emulated_mask))
9312 *evmask_out = evmask;
9313 return touch_grab->window;
9319 if (grab != NULL && !grab->owner_events)
9321 evmask = grab->event_mask;
9322 evmask = update_evmask_for_button_motion (evmask, mask);
9324 grab_window = grab->window;
9326 if (evmask & (type_masks[type] | emulated_mask))
9329 *evmask_out = evmask;
9336 while (pointer_window != NULL)
9338 evmask = pointer_window->event_mask;
9339 evmask = update_evmask_for_button_motion (evmask, mask);
9341 if (evmask & (type_masks[type] | emulated_mask))
9344 *evmask_out = evmask;
9345 return pointer_window;
9348 pointer_window = get_event_parent (pointer_window);
9354 evmask = grab->event_mask;
9355 evmask = update_evmask_for_button_motion (evmask, mask);
9357 if (evmask & (type_masks[type] | emulated_mask))
9360 *evmask_out = evmask;
9361 return grab->window;
9371 proxy_pointer_event (GdkDisplay *display,
9372 GdkEvent *source_event,
9375 GdkWindow *toplevel_window, *event_window;
9376 GdkWindow *pointer_window;
9377 GdkPointerWindowInfo *pointer_info;
9378 GdkDevice *device, *source_device;
9381 gdouble toplevel_x, toplevel_y;
9383 gboolean non_linear, need_synthetic_enter = FALSE;
9386 event_type = source_event->type;
9387 event_window = source_event->any.window;
9388 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9389 gdk_event_get_state (source_event, &state);
9390 time_ = gdk_event_get_time (source_event);
9391 device = gdk_event_get_device (source_event);
9392 source_device = gdk_event_get_source_device (source_event);
9393 pointer_info = _gdk_display_get_pointer_info (display, device);
9394 toplevel_window = convert_native_coords_to_toplevel (event_window,
9395 toplevel_x, toplevel_y,
9396 &toplevel_x, &toplevel_y);
9399 if ((source_event->type == GDK_LEAVE_NOTIFY ||
9400 source_event->type == GDK_ENTER_NOTIFY) &&
9401 (source_event->crossing.detail == GDK_NOTIFY_NONLINEAR ||
9402 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))
9405 if (pointer_info->need_touch_press_enter &&
9406 gdk_device_get_source (pointer_info->last_slave) != GDK_SOURCE_TOUCHSCREEN &&
9407 (source_event->type != GDK_TOUCH_UPDATE ||
9408 _gdk_event_get_pointer_emulated (source_event)))
9410 pointer_info->need_touch_press_enter = FALSE;
9411 need_synthetic_enter = TRUE;
9414 /* If we get crossing events with subwindow unexpectedly being NULL
9415 that means there is a native subwindow that gdk doesn't know about.
9416 We track these and forward them, with the correct virtual window
9418 This is important to get right, as metacity uses gdk for the frame
9419 windows, but gdk doesn't know about the client windows reparented
9421 if (((source_event->type == GDK_LEAVE_NOTIFY &&
9422 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9423 (source_event->type == GDK_ENTER_NOTIFY &&
9424 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9425 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9426 source_event->crossing.subwindow == NULL)
9428 /* Left for an unknown (to gdk) subwindow */
9430 /* Send leave events from window under pointer to event window
9431 that will get the subwindow == NULL window */
9432 _gdk_synthesize_crossing_events (display,
9433 pointer_info->window_under_pointer,
9435 device, source_device,
9436 source_event->crossing.mode,
9437 toplevel_x, toplevel_y,
9443 /* Send subwindow == NULL event */
9444 send_crossing_event (display,
9448 source_event->crossing.mode,
9449 source_event->crossing.detail,
9451 device, source_device,
9452 toplevel_x, toplevel_y,
9457 _gdk_display_set_window_under_pointer (display, device, NULL);
9461 pointer_window = get_pointer_window (display, toplevel_window, device,
9462 toplevel_x, toplevel_y, serial);
9464 if (((source_event->type == GDK_ENTER_NOTIFY &&
9465 source_event->crossing.detail == GDK_NOTIFY_INFERIOR) ||
9466 (source_event->type == GDK_LEAVE_NOTIFY &&
9467 (source_event->crossing.detail == GDK_NOTIFY_VIRTUAL ||
9468 source_event->crossing.detail == GDK_NOTIFY_NONLINEAR_VIRTUAL))) &&
9469 source_event->crossing.subwindow == NULL)
9471 /* Entered from an unknown (to gdk) subwindow */
9473 /* Send subwindow == NULL event */
9474 send_crossing_event (display,
9478 source_event->crossing.mode,
9479 source_event->crossing.detail,
9481 device, source_device,
9482 toplevel_x, toplevel_y,
9487 /* Send enter events from event window to pointer_window */
9488 _gdk_synthesize_crossing_events (display,
9491 device, source_device,
9492 source_event->crossing.mode,
9493 toplevel_x, toplevel_y,
9496 serial, non_linear);
9497 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9501 if ((source_event->type != GDK_TOUCH_UPDATE ||
9502 _gdk_event_get_pointer_emulated (source_event)) &&
9503 pointer_info->window_under_pointer != pointer_window)
9505 /* Either a toplevel crossing notify that ended up inside a child window,
9506 or a motion notify that got into another child window */
9508 /* Different than last time, send crossing events */
9509 _gdk_synthesize_crossing_events (display,
9510 pointer_info->window_under_pointer,
9512 device, source_device,
9513 GDK_CROSSING_NORMAL,
9514 toplevel_x, toplevel_y,
9517 serial, non_linear);
9518 _gdk_display_set_window_under_pointer (display, device, pointer_window);
9520 else if (source_event->type == GDK_MOTION_NOTIFY ||
9521 source_event->type == GDK_TOUCH_UPDATE)
9523 GdkWindow *event_win;
9526 GdkEventSequence *sequence;
9528 sequence = gdk_event_get_event_sequence (source_event);
9530 event_win = get_event_window (display,
9537 _gdk_event_get_pointer_emulated (source_event),
9540 if (event_type == GDK_TOUCH_UPDATE)
9542 if (_gdk_event_get_pointer_emulated (source_event))
9544 /* Touch events emulating pointer events are transformed back
9545 * to pointer events if:
9546 * 1 - The event window doesn't select for touch events
9547 * 2 - There's no touch grab for this sequence, which means
9548 * it was started as a pointer sequence, but a device
9549 * grab added touch events afterwards, the sequence must
9550 * not mutate in this case.
9552 if ((evmask & GDK_TOUCH_MASK) == 0 ||
9553 !_gdk_display_has_touch_grab (display, device, sequence, serial))
9554 event_type = GDK_MOTION_NOTIFY;
9556 else if ((evmask & GDK_TOUCH_MASK) == 0)
9560 if (is_touch_type (source_event->type) && !is_touch_type (event_type))
9561 state |= GDK_BUTTON1_MASK;
9564 gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9565 gdk_window_get_device_events (event_win, device) == 0)
9568 /* The last device to interact with the window was a touch device,
9569 * which synthesized a leave notify event, so synthesize another enter
9570 * notify to tell the pointer is on the window.
9572 if (need_synthetic_enter)
9573 _gdk_synthesize_crossing_events (display,
9574 NULL, pointer_window,
9575 device, source_device,
9576 GDK_CROSSING_DEVICE_SWITCH,
9577 toplevel_x, toplevel_y,
9584 event_type == GDK_MOTION_NOTIFY &&
9585 (evmask & GDK_POINTER_MOTION_HINT_MASK))
9587 gulong *device_serial;
9589 device_serial = g_hash_table_lookup (display->motion_hint_info, device);
9591 if (!device_serial ||
9592 (*device_serial != 0 &&
9593 serial < *device_serial))
9594 event_win = NULL; /* Ignore event */
9598 *device_serial = G_MAXULONG;
9605 event = gdk_event_new (event_type);
9606 event->any.window = g_object_ref (event_win);
9607 event->any.send_event = source_event->any.send_event;
9609 gdk_event_set_device (event, gdk_event_get_device (source_event));
9610 gdk_event_set_source_device (event, source_device);
9612 if (event_type == GDK_TOUCH_UPDATE)
9614 event->touch.time = time_;
9615 event->touch.state = state | GDK_BUTTON1_MASK;
9616 event->touch.sequence = source_event->touch.sequence;
9617 event->touch.emulating_pointer = source_event->touch.emulating_pointer;
9618 convert_toplevel_coords_to_window (event_win,
9619 toplevel_x, toplevel_y,
9620 &event->touch.x, &event->touch.y);
9621 gdk_event_get_root_coords (source_event,
9622 &event->touch.x_root,
9623 &event->touch.y_root);
9625 event->touch.axes = g_memdup (source_event->touch.axes,
9626 sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
9630 event->motion.time = time_;
9631 event->motion.state = state;
9632 event->motion.is_hint = is_hint;
9634 convert_toplevel_coords_to_window (event_win,
9635 toplevel_x, toplevel_y,
9636 &event->motion.x, &event->motion.y);
9637 gdk_event_get_root_coords (source_event,
9638 &event->motion.x_root,
9639 &event->motion.y_root);
9641 if (is_touch_type (source_event->type))
9642 event->motion.axes = g_memdup (source_event->touch.axes,
9643 sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
9645 event->motion.axes = g_memdup (source_event->motion.axes,
9646 sizeof (gdouble) * gdk_device_get_n_axes (source_event->motion.device));
9649 /* Just insert the event */
9650 _gdk_event_queue_insert_after (gdk_window_get_display (event_win),
9651 source_event, event);
9654 /* unlink all move events from queue.
9655 We handle our own, including our emulated masks. */
9659 #define GDK_ANY_BUTTON_MASK (GDK_BUTTON1_MASK | \
9660 GDK_BUTTON2_MASK | \
9661 GDK_BUTTON3_MASK | \
9662 GDK_BUTTON4_MASK | \
9666 proxy_button_event (GdkEvent *source_event,
9669 GdkWindow *toplevel_window, *event_window;
9670 GdkWindow *event_win;
9671 GdkWindow *pointer_window;
9674 GdkPointerWindowInfo *pointer_info;
9675 GdkDeviceGrabInfo *pointer_grab;
9679 gdouble toplevel_x, toplevel_y;
9680 GdkDisplay *display;
9682 GdkDevice *device, *source_device;
9683 GdkEventMask evmask;
9684 GdkEventSequence *sequence;
9686 type = source_event->any.type;
9687 event_window = source_event->any.window;
9688 gdk_event_get_coords (source_event, &toplevel_x, &toplevel_y);
9689 gdk_event_get_state (source_event, &state);
9690 time_ = gdk_event_get_time (source_event);
9691 device = gdk_event_get_device (source_event);
9692 source_device = gdk_event_get_source_device (source_event);
9693 display = gdk_window_get_display (source_event->any.window);
9694 toplevel_window = convert_native_coords_to_toplevel (event_window,
9695 toplevel_x, toplevel_y,
9696 &toplevel_x, &toplevel_y);
9698 sequence = gdk_event_get_event_sequence (source_event);
9700 pointer_info = _gdk_display_get_pointer_info (display, device);
9701 pointer_grab = _gdk_display_has_device_grab (display, device, serial);
9703 if ((type == GDK_BUTTON_PRESS ||
9704 type == GDK_TOUCH_BEGIN) &&
9705 !source_event->any.send_event &&
9707 (type == GDK_TOUCH_BEGIN && pointer_grab->implicit &&
9708 !_gdk_event_get_pointer_emulated (source_event))))
9711 _gdk_window_find_descendant_at (toplevel_window,
9712 toplevel_x, toplevel_y,
9715 /* Find the event window, that gets the grab */
9718 (parent = get_event_parent (w)) != NULL &&
9719 parent->window_type != GDK_WINDOW_ROOT)
9721 if (w->event_mask & GDK_BUTTON_PRESS_MASK &&
9722 (type == GDK_BUTTON_PRESS ||
9723 _gdk_event_get_pointer_emulated (source_event)))
9726 if (type == GDK_TOUCH_BEGIN &&
9727 w->event_mask & GDK_TOUCH_MASK)
9736 if (type == GDK_TOUCH_BEGIN &&
9737 pointer_window->event_mask & GDK_TOUCH_MASK)
9739 _gdk_display_add_touch_grab (display, device, sequence,
9740 pointer_window, event_window,
9741 gdk_window_get_events (pointer_window),
9744 else if (type == GDK_BUTTON_PRESS ||
9745 _gdk_event_get_pointer_emulated (source_event))
9747 _gdk_display_add_device_grab (display,
9753 gdk_window_get_events (pointer_window),
9757 _gdk_display_device_grab_update (display, device,
9758 source_device, serial);
9763 pointer_window = get_pointer_window (display, toplevel_window, device,
9764 toplevel_x, toplevel_y,
9767 event_win = get_event_window (display,
9773 _gdk_event_get_pointer_emulated (source_event),
9776 if (type == GDK_TOUCH_BEGIN || type == GDK_TOUCH_END)
9778 if (_gdk_event_get_pointer_emulated (source_event))
9780 if ((evmask & GDK_TOUCH_MASK) == 0 ||
9781 !_gdk_display_has_touch_grab (display, device, sequence, serial))
9783 if (type == GDK_TOUCH_BEGIN)
9784 type = GDK_BUTTON_PRESS;
9785 else if (type == GDK_TOUCH_END)
9786 type = GDK_BUTTON_RELEASE;
9789 else if ((evmask & GDK_TOUCH_MASK) == 0)
9793 if (source_event->type == GDK_TOUCH_END && !is_touch_type (type))
9794 state |= GDK_BUTTON1_MASK;
9796 if (event_win == NULL)
9799 if (gdk_device_get_device_type (device) != GDK_DEVICE_TYPE_MASTER &&
9800 gdk_window_get_device_events (event_win, device) == 0)
9803 if ((type == GDK_BUTTON_PRESS ||
9804 (type == GDK_TOUCH_BEGIN &&
9805 _gdk_event_get_pointer_emulated (source_event))) &&
9806 pointer_info->need_touch_press_enter)
9808 GdkCrossingMode mode;
9810 /* The last device to interact with the window was a touch device,
9811 * which synthesized a leave notify event, so synthesize another enter
9812 * notify to tell the pointer is on the window.
9814 if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
9815 mode = GDK_CROSSING_TOUCH_BEGIN;
9817 mode = GDK_CROSSING_DEVICE_SWITCH;
9819 pointer_info->need_touch_press_enter = FALSE;
9820 _gdk_synthesize_crossing_events (display,
9822 pointer_info->window_under_pointer,
9823 device, source_device, mode,
9824 toplevel_x, toplevel_y,
9825 state, time_, source_event,
9828 else if (type == GDK_SCROLL &&
9829 (((evmask & GDK_SMOOTH_SCROLL_MASK) == 0 &&
9830 source_event->scroll.direction == GDK_SCROLL_SMOOTH) ||
9831 ((evmask & GDK_SMOOTH_SCROLL_MASK) != 0 &&
9832 source_event->scroll.direction != GDK_SCROLL_SMOOTH &&
9833 _gdk_event_get_pointer_emulated (source_event))))
9836 event = _gdk_make_event (event_win, type, source_event, FALSE);
9840 case GDK_BUTTON_PRESS:
9841 case GDK_BUTTON_RELEASE:
9842 event->button.button = source_event->button.button;
9843 convert_toplevel_coords_to_window (event_win,
9844 toplevel_x, toplevel_y,
9845 &event->button.x, &event->button.y);
9846 gdk_event_get_root_coords (source_event,
9847 &event->button.x_root,
9848 &event->button.y_root);
9849 gdk_event_set_device (event, gdk_event_get_device (source_event));
9850 gdk_event_set_source_device (event, source_device);
9852 if (is_touch_type (source_event->type))
9854 if (type == GDK_BUTTON_RELEASE)
9855 event->button.state |= GDK_BUTTON1_MASK;
9856 event->button.button = 1;
9857 event->button.axes = g_memdup (source_event->touch.axes,
9858 sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
9862 event->button.button = source_event->button.button;
9863 event->button.axes = g_memdup (source_event->button.axes,
9864 sizeof (gdouble) * gdk_device_get_n_axes (source_event->button.device));
9867 if (type == GDK_BUTTON_PRESS)
9868 _gdk_event_button_generate (display, event);
9869 else if ((type == GDK_BUTTON_RELEASE ||
9870 (type == GDK_TOUCH_END &&
9871 _gdk_event_get_pointer_emulated (source_event))) &&
9872 pointer_window == pointer_info->window_under_pointer &&
9873 gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
9875 /* Synthesize a leave notify event
9876 * whenever a touch device is released
9878 pointer_info->need_touch_press_enter = TRUE;
9879 _gdk_synthesize_crossing_events (display,
9880 pointer_window, NULL,
9881 device, source_device,
9882 GDK_CROSSING_TOUCH_END,
9883 toplevel_x, toplevel_y,
9889 case GDK_TOUCH_BEGIN:
9891 convert_toplevel_coords_to_window (event_win,
9892 toplevel_x, toplevel_y,
9893 &event->button.x, &event->button.y);
9894 gdk_event_get_root_coords (source_event,
9895 &event->touch.x_root,
9896 &event->touch.y_root);
9897 event->touch.state = state;
9898 event->touch.device = source_event->touch.device;
9899 event->touch.axes = g_memdup (source_event->touch.axes,
9900 sizeof (gdouble) * gdk_device_get_n_axes (source_event->touch.device));
9901 event->touch.sequence = source_event->touch.sequence;
9902 event->touch.emulating_pointer = source_event->touch.emulating_pointer;
9904 gdk_event_set_source_device (event, source_device);
9906 if ((type == GDK_TOUCH_END &&
9907 _gdk_event_get_pointer_emulated (source_event)) &&
9908 pointer_window == pointer_info->window_under_pointer &&
9909 gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
9911 /* Synthesize a leave notify event
9912 * whenever a touch device is released
9914 pointer_info->need_touch_press_enter = TRUE;
9915 _gdk_synthesize_crossing_events (display,
9916 pointer_window, NULL,
9917 device, source_device,
9918 GDK_CROSSING_TOUCH_END,
9919 toplevel_x, toplevel_y,
9926 event->scroll.direction = source_event->scroll.direction;
9927 convert_toplevel_coords_to_window (event_win,
9928 toplevel_x, toplevel_y,
9929 &event->scroll.x, &event->scroll.y);
9930 event->scroll.x_root = source_event->scroll.x_root;
9931 event->scroll.y_root = source_event->scroll.y_root;
9932 event->scroll.state = state;
9933 event->scroll.device = source_event->scroll.device;
9934 event->scroll.delta_x = source_event->scroll.delta_x;
9935 event->scroll.delta_y = source_event->scroll.delta_y;
9936 gdk_event_set_source_device (event, source_device);
9943 return TRUE; /* Always unlink original, we want to obey the emulated event mask */
9946 #ifdef DEBUG_WINDOW_PRINTING
9948 #ifdef GDK_WINDOWING_X11
9949 #include "x11/gdkx.h"
9953 gdk_window_print (GdkWindow *window,
9957 const char *window_types[] = {
9967 g_print ("%*s%p: [%s] %d,%d %dx%d", indent, "", window,
9968 window->user_data ? g_type_name_from_instance (window->user_data) : "no widget",
9969 window->x, window->y,
9970 window->width, window->height
9973 if (gdk_window_has_impl (window))
9975 #ifdef GDK_WINDOWING_X11
9976 g_print (" impl(0x%lx)", gdk_x11_window_get_xid (window));
9980 if (window->window_type != GDK_WINDOW_CHILD)
9981 g_print (" %s", window_types[window->window_type]);
9983 if (window->input_only)
9984 g_print (" input-only");
9987 g_print (" shaped");
9989 if (!gdk_window_is_visible ((GdkWindow *)window))
9990 g_print (" hidden");
9992 g_print (" abs[%d,%d]",
9993 window->abs_x, window->abs_y);
9995 if (window->alpha != 255)
9996 g_print (" alpha[%d]",
9999 s = print_region (window->clip_region);
10000 g_print (" clipbox[%s]", s);
10007 gdk_window_print_tree (GdkWindow *window,
10009 gboolean include_input_only)
10013 if (window->input_only && !include_input_only)
10016 gdk_window_print (window, indent);
10018 for (l = window->children; l != NULL; l = l->next)
10019 gdk_window_print_tree (l->data, indent + 4, include_input_only);
10022 #endif /* DEBUG_WINDOW_PRINTING */
10025 _gdk_windowing_got_event (GdkDisplay *display,
10030 GdkWindow *event_window;
10032 gboolean unlink_event = FALSE;
10033 GdkDeviceGrabInfo *button_release_grab;
10034 GdkPointerWindowInfo *pointer_info = NULL;
10035 GdkDevice *device, *source_device;
10036 gboolean is_toplevel;
10038 if (gdk_event_get_time (event) != GDK_CURRENT_TIME)
10039 display->last_event_time = gdk_event_get_time (event);
10041 device = gdk_event_get_device (event);
10042 source_device = gdk_event_get_source_device (event);
10048 if (gdk_device_get_source (device) != GDK_SOURCE_KEYBOARD)
10050 pointer_info = _gdk_display_get_pointer_info (display, device);
10052 if (source_device != pointer_info->last_slave &&
10053 gdk_device_get_device_type (source_device) == GDK_DEVICE_TYPE_SLAVE)
10054 pointer_info->last_slave = source_device;
10055 else if (pointer_info->last_slave)
10056 source_device = pointer_info->last_slave;
10059 g_object_get (device, "input-mode", &mode, NULL);
10060 _gdk_display_device_grab_update (display, device, source_device, serial);
10062 if (mode == GDK_MODE_DISABLED ||
10063 !_gdk_display_check_grab_ownership (display, device, serial))
10065 /* Device events are blocked by another
10066 * device grab, or the device is disabled
10068 unlink_event = TRUE;
10073 event_window = event->any.window;
10077 #ifdef DEBUG_WINDOW_PRINTING
10078 if (event->type == GDK_KEY_PRESS &&
10079 (event->key.keyval == 0xa7 ||
10080 event->key.keyval == 0xbd))
10082 gdk_window_print_tree (event_window, 0, event->key.keyval == 0xbd);
10086 if (event->type == GDK_VISIBILITY_NOTIFY)
10088 event_window->native_visibility = event->visibility.state;
10089 gdk_window_update_visibility_recursively (event_window, event_window);
10093 if (!(is_button_type (event->type) ||
10094 is_motion_type (event->type)) ||
10095 event_window->window_type == GDK_WINDOW_ROOT)
10098 is_toplevel = gdk_window_is_toplevel (event_window);
10100 if ((event->type == GDK_ENTER_NOTIFY ||
10101 event->type == GDK_LEAVE_NOTIFY) &&
10102 (event->crossing.mode == GDK_CROSSING_GRAB ||
10103 event->crossing.mode == GDK_CROSSING_UNGRAB) &&
10104 (_gdk_display_has_device_grab (display, device, serial) ||
10105 event->crossing.detail == GDK_NOTIFY_INFERIOR))
10107 /* We synthesize all crossing events due to grabs ourselves,
10108 * so we ignore the native ones caused by our native pointer_grab
10109 * calls. Otherwise we would proxy these crossing event and cause
10110 * multiple copies of crossing events for grabs.
10112 * We do want to handle grabs from other clients though, as for
10113 * instance alt-tab in metacity causes grabs like these and
10114 * we want to handle those. Thus the has_pointer_grab check.
10116 * Implicit grabs on child windows create some grabbing events
10117 * that are sent before the button press. This means we can't
10118 * detect these with the has_pointer_grab check (as the implicit
10119 * grab is only noticed when we get button press event), so we
10120 * detect these events by checking for INFERIOR enter or leave
10121 * events. These should never be a problem to filter out.
10124 /* We ended up in this window after some (perhaps other clients)
10125 * grab, so update the toplevel_under_window state
10128 event->type == GDK_ENTER_NOTIFY &&
10129 event->crossing.mode == GDK_CROSSING_UNGRAB)
10131 if (pointer_info->toplevel_under_pointer)
10132 g_object_unref (pointer_info->toplevel_under_pointer);
10133 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
10136 unlink_event = TRUE;
10140 /* Track toplevel_under_pointer */
10143 if (event->type == GDK_ENTER_NOTIFY &&
10144 event->crossing.detail != GDK_NOTIFY_INFERIOR)
10146 if (pointer_info->toplevel_under_pointer)
10147 g_object_unref (pointer_info->toplevel_under_pointer);
10148 pointer_info->toplevel_under_pointer = g_object_ref (event_window);
10150 else if (event->type == GDK_LEAVE_NOTIFY &&
10151 event->crossing.detail != GDK_NOTIFY_INFERIOR &&
10152 pointer_info->toplevel_under_pointer == event_window)
10154 if (pointer_info->toplevel_under_pointer)
10155 g_object_unref (pointer_info->toplevel_under_pointer);
10156 pointer_info->toplevel_under_pointer = NULL;
10160 if (pointer_info &&
10161 (!is_touch_type (event->type) ||
10162 _gdk_event_get_pointer_emulated (event)))
10164 guint old_state, old_button;
10166 /* Store last pointer window and position/state */
10167 old_state = pointer_info->state;
10168 old_button = pointer_info->button;
10170 gdk_event_get_coords (event, &x, &y);
10171 convert_native_coords_to_toplevel (event_window, x, y, &x, &y);
10172 pointer_info->toplevel_x = x;
10173 pointer_info->toplevel_y = y;
10174 gdk_event_get_state (event, &pointer_info->state);
10176 if (event->type == GDK_BUTTON_PRESS ||
10177 event->type == GDK_BUTTON_RELEASE)
10178 pointer_info->button = event->button.button;
10179 else if (event->type == GDK_TOUCH_BEGIN ||
10180 event->type == GDK_TOUCH_END)
10181 pointer_info->button = 1;
10184 (pointer_info->state != old_state ||
10185 pointer_info->button != old_button))
10186 _gdk_display_enable_motion_hints (display, device);
10189 if (is_motion_type (event->type))
10190 unlink_event = proxy_pointer_event (display, event, serial);
10191 else if (is_button_type (event->type))
10192 unlink_event = proxy_button_event (event, serial);
10194 if ((event->type == GDK_BUTTON_RELEASE ||
10195 event->type == GDK_TOUCH_END) &&
10196 !event->any.send_event)
10198 GdkEventSequence *sequence;
10200 sequence = gdk_event_get_event_sequence (event);
10201 if (event->type == GDK_TOUCH_END && sequence)
10203 _gdk_display_end_touch_grab (display, device, sequence);
10206 if (event->type == GDK_BUTTON_RELEASE ||
10207 _gdk_event_get_pointer_emulated (event))
10209 button_release_grab =
10210 _gdk_display_has_device_grab (display, device, serial);
10212 if (button_release_grab &&
10213 button_release_grab->implicit &&
10214 (event->button.state & GDK_ANY_BUTTON_MASK & ~(GDK_BUTTON1_MASK << (event->button.button - 1))) == 0)
10216 button_release_grab->serial_end = serial;
10217 button_release_grab->implicit_ungrab = FALSE;
10218 _gdk_display_device_grab_update (display, device, source_device, serial);
10226 _gdk_event_queue_remove_link (display, event_link);
10227 g_list_free_1 (event_link);
10228 gdk_event_free (event);
10231 /* This does two things - first it sees if there are motions at the
10232 * end of the queue that can be compressed. Second, if there is just
10233 * a single motion that won't be dispatched because it is a compression
10234 * candidate it queues up flushing the event queue.
10236 _gdk_event_queue_handle_motion_compression (display);
10240 * gdk_window_create_similar_surface:
10241 * @window: window to make new surface similar to
10242 * @content: the content for the new surface
10243 * @width: width of the new surface
10244 * @height: height of the new surface
10246 * Create a new surface that is as compatible as possible with the
10247 * given @window. For example the new surface will have the same
10248 * fallback resolution and font options as @window. Generally, the new
10249 * surface will also use the same backend as @window, unless that is
10250 * not possible for some reason. The type of the returned surface may
10251 * be examined with cairo_surface_get_type().
10253 * Initially the surface contents are all 0 (transparent if contents
10254 * have transparency, black otherwise.)
10256 * Returns: a pointer to the newly allocated surface. The caller
10257 * owns the surface and should call cairo_surface_destroy() when done
10260 * This function always returns a valid pointer, but it will return a
10261 * pointer to a "nil" surface if @other is already in an error state
10262 * or any other error occurs.
10267 gdk_window_create_similar_surface (GdkWindow * window,
10268 cairo_content_t content,
10272 cairo_surface_t *window_surface, *surface;
10274 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
10276 window_surface = gdk_window_ref_impl_surface (window);
10278 switch (_gdk_rendering_mode)
10280 case GDK_RENDERING_MODE_RECORDING:
10282 cairo_rectangle_t rect = { 0, 0, width, height };
10283 surface = cairo_recording_surface_create (content, &rect);
10286 case GDK_RENDERING_MODE_IMAGE:
10287 surface = cairo_image_surface_create (content == CAIRO_CONTENT_COLOR ? CAIRO_FORMAT_RGB24 :
10288 content == CAIRO_CONTENT_ALPHA ? CAIRO_FORMAT_A8 : CAIRO_FORMAT_ARGB32,
10291 case GDK_RENDERING_MODE_SIMILAR:
10293 surface = cairo_surface_create_similar (window_surface,
10299 cairo_surface_destroy (window_surface);
10305 * gdk_window_focus:
10306 * @window: a #GdkWindow
10307 * @timestamp: timestamp of the event triggering the window focus
10309 * Sets keyboard focus to @window. In most cases, gtk_window_present()
10310 * should be used on a #GtkWindow, rather than calling this function.
10314 gdk_window_focus (GdkWindow *window,
10317 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->focus (window, timestamp);
10321 * gdk_window_set_type_hint:
10322 * @window: A toplevel #GdkWindow
10323 * @hint: A hint of the function this window will have
10325 * The application can use this call to provide a hint to the window
10326 * manager about the functionality of a window. The window manager
10327 * can use this information when determining the decoration and behaviour
10330 * The hint must be set before the window is mapped.
10333 gdk_window_set_type_hint (GdkWindow *window,
10334 GdkWindowTypeHint hint)
10336 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_type_hint (window, hint);
10340 * gdk_window_get_type_hint:
10341 * @window: A toplevel #GdkWindow
10343 * This function returns the type hint set for a window.
10345 * Return value: The type hint set for @window
10350 gdk_window_get_type_hint (GdkWindow *window)
10352 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_type_hint (window);
10356 * gdk_window_set_modal_hint:
10357 * @window: A toplevel #GdkWindow
10358 * @modal: %TRUE if the window is modal, %FALSE otherwise.
10360 * The application can use this hint to tell the window manager
10361 * that a certain window has modal behaviour. The window manager
10362 * can use this information to handle modal windows in a special
10365 * You should only use this on windows for which you have
10366 * previously called gdk_window_set_transient_for()
10369 gdk_window_set_modal_hint (GdkWindow *window,
10372 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_modal_hint (window, modal);
10376 * gdk_window_set_skip_taskbar_hint:
10377 * @window: a toplevel #GdkWindow
10378 * @skips_taskbar: %TRUE to skip the taskbar
10380 * Toggles whether a window should appear in a task list or window
10381 * list. If a window's semantic type as specified with
10382 * gdk_window_set_type_hint() already fully describes the window, this
10383 * function should <emphasis>not</emphasis> be called in addition,
10384 * instead you should allow the window to be treated according to
10385 * standard policy for its semantic type.
10390 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
10391 gboolean skips_taskbar)
10393 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_taskbar_hint (window, skips_taskbar);
10397 * gdk_window_set_skip_pager_hint:
10398 * @window: a toplevel #GdkWindow
10399 * @skips_pager: %TRUE to skip the pager
10401 * Toggles whether a window should appear in a pager (workspace
10402 * switcher, or other desktop utility program that displays a small
10403 * thumbnail representation of the windows on the desktop). If a
10404 * window's semantic type as specified with gdk_window_set_type_hint()
10405 * already fully describes the window, this function should
10406 * <emphasis>not</emphasis> be called in addition, instead you should
10407 * allow the window to be treated according to standard policy for
10408 * its semantic type.
10413 gdk_window_set_skip_pager_hint (GdkWindow *window,
10414 gboolean skips_pager)
10416 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_skip_pager_hint (window, skips_pager);
10420 * gdk_window_set_urgency_hint:
10421 * @window: a toplevel #GdkWindow
10422 * @urgent: %TRUE if the window is urgent
10424 * Toggles whether a window needs the user's
10425 * urgent attention.
10430 gdk_window_set_urgency_hint (GdkWindow *window,
10433 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_urgency_hint (window, urgent);
10437 * gdk_window_set_geometry_hints:
10438 * @window: a toplevel #GdkWindow
10439 * @geometry: geometry hints
10440 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
10442 * Sets the geometry hints for @window. Hints flagged in @geom_mask
10443 * are set, hints not flagged in @geom_mask are unset.
10444 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
10446 * This function provides hints to the windowing system about
10447 * acceptable sizes for a toplevel window. The purpose of
10448 * this is to constrain user resizing, but the windowing system
10449 * will typically (but is not required to) also constrain the
10450 * current size of the window to the provided values and
10451 * constrain programatic resizing via gdk_window_resize() or
10452 * gdk_window_move_resize().
10454 * Note that on X11, this effect has no effect on windows
10455 * of type %GDK_WINDOW_TEMP or windows where override redirect
10456 * has been turned on via gdk_window_set_override_redirect()
10457 * since these windows are not resizable by the user.
10459 * Since you can't count on the windowing system doing the
10460 * constraints for programmatic resizes, you should generally
10461 * call gdk_window_constrain_size() yourself to determine
10462 * appropriate sizes.
10466 gdk_window_set_geometry_hints (GdkWindow *window,
10467 const GdkGeometry *geometry,
10468 GdkWindowHints geom_mask)
10470 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_geometry_hints (window, geometry, geom_mask);
10474 * gdk_window_set_title:
10475 * @window: a toplevel #GdkWindow
10476 * @title: title of @window
10478 * Sets the title of a toplevel window, to be displayed in the titlebar.
10479 * If you haven't explicitly set the icon name for the window
10480 * (using gdk_window_set_icon_name()), the icon name will be set to
10481 * @title as well. @title must be in UTF-8 encoding (as with all
10482 * user-readable strings in GDK/GTK+). @title may not be %NULL.
10485 gdk_window_set_title (GdkWindow *window,
10486 const gchar *title)
10488 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_title (window, title);
10492 * gdk_window_set_role:
10493 * @window: a toplevel #GdkWindow
10494 * @role: a string indicating its role
10496 * When using GTK+, typically you should use gtk_window_set_role() instead
10497 * of this low-level function.
10499 * The window manager and session manager use a window's role to
10500 * distinguish it from other kinds of window in the same application.
10501 * When an application is restarted after being saved in a previous
10502 * session, all windows with the same title and role are treated as
10503 * interchangeable. So if you have two windows with the same title
10504 * that should be distinguished for session management purposes, you
10505 * should set the role on those windows. It doesn't matter what string
10506 * you use for the role, as long as you have a different role for each
10507 * non-interchangeable kind of window.
10511 gdk_window_set_role (GdkWindow *window,
10514 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_role (window, role);
10518 * gdk_window_set_startup_id:
10519 * @window: a toplevel #GdkWindow
10520 * @startup_id: a string with startup-notification identifier
10522 * When using GTK+, typically you should use gtk_window_set_startup_id()
10523 * instead of this low-level function.
10529 gdk_window_set_startup_id (GdkWindow *window,
10530 const gchar *startup_id)
10532 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_startup_id (window, startup_id);
10536 * gdk_window_set_transient_for:
10537 * @window: a toplevel #GdkWindow
10538 * @parent: another toplevel #GdkWindow
10540 * Indicates to the window manager that @window is a transient dialog
10541 * associated with the application window @parent. This allows the
10542 * window manager to do things like center @window on @parent and
10543 * keep @window above @parent.
10545 * See gtk_window_set_transient_for() if you're using #GtkWindow or
10549 gdk_window_set_transient_for (GdkWindow *window,
10552 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_transient_for (window, parent);
10556 * gdk_window_get_root_origin:
10557 * @window: a toplevel #GdkWindow
10558 * @x: (out): return location for X position of window frame
10559 * @y: (out): return location for Y position of window frame
10561 * Obtains the top-left corner of the window manager frame in root
10562 * window coordinates.
10566 gdk_window_get_root_origin (GdkWindow *window,
10570 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_root_origin (window, x, y);
10574 * gdk_window_get_frame_extents:
10575 * @window: a toplevel #GdkWindow
10576 * @rect: (out): rectangle to fill with bounding box of the window frame
10578 * Obtains the bounding box of the window, including window manager
10579 * titlebar/borders if any. The frame position is given in root window
10580 * coordinates. To get the position of the window itself (rather than
10581 * the frame) in root window coordinates, use gdk_window_get_origin().
10585 gdk_window_get_frame_extents (GdkWindow *window,
10586 GdkRectangle *rect)
10588 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_frame_extents (window, rect);
10592 * gdk_window_set_override_redirect:
10593 * @window: a toplevel #GdkWindow
10594 * @override_redirect: %TRUE if window should be override redirect
10596 * An override redirect window is not under the control of the window manager.
10597 * This means it won't have a titlebar, won't be minimizable, etc. - it will
10598 * be entirely under the control of the application. The window manager
10599 * can't see the override redirect window at all.
10601 * Override redirect should only be used for short-lived temporary
10602 * windows, such as popup menus. #GtkMenu uses an override redirect
10603 * window in its implementation, for example.
10607 gdk_window_set_override_redirect (GdkWindow *window,
10608 gboolean override_redirect)
10610 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_override_redirect (window, override_redirect);
10614 * gdk_window_set_accept_focus:
10615 * @window: a toplevel #GdkWindow
10616 * @accept_focus: %TRUE if the window should receive input focus
10618 * Setting @accept_focus to %FALSE hints the desktop environment that the
10619 * window doesn't want to receive input focus.
10621 * On X, it is the responsibility of the window manager to interpret this
10622 * hint. ICCCM-compliant window manager usually respect it.
10627 gdk_window_set_accept_focus (GdkWindow *window,
10628 gboolean accept_focus)
10630 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_accept_focus (window, accept_focus);
10634 * gdk_window_set_focus_on_map:
10635 * @window: a toplevel #GdkWindow
10636 * @focus_on_map: %TRUE if the window should receive input focus when mapped
10638 * Setting @focus_on_map to %FALSE hints the desktop environment that the
10639 * window doesn't want to receive input focus when it is mapped.
10640 * focus_on_map should be turned off for windows that aren't triggered
10641 * interactively (such as popups from network activity).
10643 * On X, it is the responsibility of the window manager to interpret
10644 * this hint. Window managers following the freedesktop.org window
10645 * manager extension specification should respect it.
10650 gdk_window_set_focus_on_map (GdkWindow *window,
10651 gboolean focus_on_map)
10653 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_focus_on_map (window, focus_on_map);
10657 * gdk_window_set_icon_list:
10658 * @window: The #GdkWindow toplevel window to set the icon of.
10659 * @pixbufs: (transfer none) (element-type GdkPixbuf):
10660 * A list of pixbufs, of different sizes.
10662 * Sets a list of icons for the window. One of these will be used
10663 * to represent the window when it has been iconified. The icon is
10664 * usually shown in an icon box or some sort of task bar. Which icon
10665 * size is shown depends on the window manager. The window manager
10666 * can scale the icon but setting several size icons can give better
10667 * image quality since the window manager may only need to scale the
10668 * icon by a small amount or not at all.
10672 gdk_window_set_icon_list (GdkWindow *window,
10675 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_list (window, pixbufs);
10679 * gdk_window_set_icon_name:
10680 * @window: a toplevel #GdkWindow
10681 * @name: (allow-none): name of window while iconified (minimized)
10683 * Windows may have a name used while minimized, distinct from the
10684 * name they display in their titlebar. Most of the time this is a bad
10685 * idea from a user interface standpoint. But you can set such a name
10686 * with this function, if you like.
10688 * After calling this with a non-%NULL @name, calls to gdk_window_set_title()
10689 * will not update the icon title.
10691 * Using %NULL for @name unsets the icon title; further calls to
10692 * gdk_window_set_title() will again update the icon title as well.
10695 gdk_window_set_icon_name (GdkWindow *window,
10698 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_icon_name (window, name);
10702 * gdk_window_iconify:
10703 * @window: a toplevel #GdkWindow
10705 * Asks to iconify (minimize) @window. The window manager may choose
10706 * to ignore the request, but normally will honor it. Using
10707 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
10709 * This function only makes sense when @window is a toplevel window.
10713 gdk_window_iconify (GdkWindow *window)
10715 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->iconify (window);
10719 * gdk_window_deiconify:
10720 * @window: a toplevel #GdkWindow
10722 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
10723 * choose to ignore the request to deiconify. When using GTK+,
10724 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
10725 * you probably want to use gtk_window_present(), which raises the window, focuses it,
10726 * unminimizes it, and puts it on the current desktop.
10730 gdk_window_deiconify (GdkWindow *window)
10732 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->deiconify (window);
10736 * gdk_window_stick:
10737 * @window: a toplevel #GdkWindow
10739 * "Pins" a window such that it's on all workspaces and does not scroll
10740 * with viewports, for window managers that have scrollable viewports.
10741 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
10743 * On the X11 platform, this function depends on window manager
10744 * support, so may have no effect with many window managers. However,
10745 * GDK will do the best it can to convince the window manager to stick
10746 * the window. For window managers that don't support this operation,
10747 * there's nothing you can do to force it to happen.
10751 gdk_window_stick (GdkWindow *window)
10753 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->stick (window);
10757 * gdk_window_unstick:
10758 * @window: a toplevel #GdkWindow
10760 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
10761 * and gtk_window_unstick().
10765 gdk_window_unstick (GdkWindow *window)
10767 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unstick (window);
10771 * gdk_window_maximize:
10772 * @window: a toplevel #GdkWindow
10774 * Maximizes the window. If the window was already maximized, then
10775 * this function does nothing.
10777 * On X11, asks the window manager to maximize @window, if the window
10778 * manager supports this operation. Not all window managers support
10779 * this, and some deliberately ignore it or don't have a concept of
10780 * "maximized"; so you can't rely on the maximization actually
10781 * happening. But it will happen with most standard window managers,
10782 * and GDK makes a best effort to get it to happen.
10784 * On Windows, reliably maximizes the window.
10788 gdk_window_maximize (GdkWindow *window)
10790 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->maximize (window);
10794 * gdk_window_unmaximize:
10795 * @window: a toplevel #GdkWindow
10797 * Unmaximizes the window. If the window wasn't maximized, then this
10798 * function does nothing.
10800 * On X11, asks the window manager to unmaximize @window, if the
10801 * window manager supports this operation. Not all window managers
10802 * support this, and some deliberately ignore it or don't have a
10803 * concept of "maximized"; so you can't rely on the unmaximization
10804 * actually happening. But it will happen with most standard window
10805 * managers, and GDK makes a best effort to get it to happen.
10807 * On Windows, reliably unmaximizes the window.
10811 gdk_window_unmaximize (GdkWindow *window)
10813 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unmaximize (window);
10817 * gdk_window_fullscreen:
10818 * @window: a toplevel #GdkWindow
10820 * Moves the window into fullscreen mode. This means the
10821 * window covers the entire screen and is above any panels
10824 * If the window was already fullscreen, then this function does nothing.
10826 * On X11, asks the window manager to put @window in a fullscreen
10827 * state, if the window manager supports this operation. Not all
10828 * window managers support this, and some deliberately ignore it or
10829 * don't have a concept of "fullscreen"; so you can't rely on the
10830 * fullscreenification actually happening. But it will happen with
10831 * most standard window managers, and GDK makes a best effort to get
10837 gdk_window_fullscreen (GdkWindow *window)
10839 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->fullscreen (window);
10843 * gdk_window_set_fullscreen_mode:
10844 * @window: a toplevel #GdkWindow
10845 * @mode: fullscreen mode
10847 * Specifies whether the @window should span over all monitors (in a multi-head
10848 * setup) or only the current monitor when in fullscreen mode.
10850 * The @mode argument is from the #GdkFullscreenMode enumeration.
10851 * If #GDK_FULLSCREEN_ON_ALL_MONITORS is specified, the fullscreen @window will
10852 * span over all monitors from the #GdkScreen.
10854 * On X11, searches through the list of monitors from the #GdkScreen the ones
10855 * which delimit the 4 edges of the entire #GdkScreen and will ask the window
10856 * manager to span the @window over these monitors.
10858 * If the XINERAMA extension is not available or not usable, this function
10861 * Not all window managers support this, so you can't rely on the fullscreen
10862 * window to span over the multiple monitors when #GDK_FULLSCREEN_ON_ALL_MONITORS
10868 gdk_window_set_fullscreen_mode (GdkWindow *window,
10869 GdkFullscreenMode mode)
10871 GdkWindowImplClass *impl_class;
10873 g_return_if_fail (GDK_IS_WINDOW (window));
10875 if (window->fullscreen_mode != mode)
10877 window->fullscreen_mode = mode;
10879 impl_class = GDK_WINDOW_IMPL_GET_CLASS (window->impl);
10880 if (impl_class->apply_fullscreen_mode != NULL)
10881 impl_class->apply_fullscreen_mode (window);
10886 * gdk_window_get_fullscreen_mode:
10887 * @window: a toplevel #GdkWindow
10889 * Obtains the #GdkFullscreenMode of the @window.
10891 * Returns: The #GdkFullscreenMode applied to the window when fullscreen.
10896 gdk_window_get_fullscreen_mode (GdkWindow *window)
10898 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_FULLSCREEN_ON_CURRENT_MONITOR);
10900 return window->fullscreen_mode;
10904 * gdk_window_unfullscreen:
10905 * @window: a toplevel #GdkWindow
10907 * Moves the window out of fullscreen mode. If the window was not
10908 * fullscreen, does nothing.
10910 * On X11, asks the window manager to move @window out of the fullscreen
10911 * state, if the window manager supports this operation. Not all
10912 * window managers support this, and some deliberately ignore it or
10913 * don't have a concept of "fullscreen"; so you can't rely on the
10914 * unfullscreenification actually happening. But it will happen with
10915 * most standard window managers, and GDK makes a best effort to get
10921 gdk_window_unfullscreen (GdkWindow *window)
10923 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->unfullscreen (window);
10927 * gdk_window_set_keep_above:
10928 * @window: a toplevel #GdkWindow
10929 * @setting: whether to keep @window above other windows
10931 * Set if @window must be kept above other windows. If the
10932 * window was already above, then this function does nothing.
10934 * On X11, asks the window manager to keep @window above, if the window
10935 * manager supports this operation. Not all window managers support
10936 * this, and some deliberately ignore it or don't have a concept of
10937 * "keep above"; so you can't rely on the window being kept above.
10938 * But it will happen with most standard window managers,
10939 * and GDK makes a best effort to get it to happen.
10944 gdk_window_set_keep_above (GdkWindow *window,
10947 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_above (window, setting);
10951 * gdk_window_set_keep_below:
10952 * @window: a toplevel #GdkWindow
10953 * @setting: whether to keep @window below other windows
10955 * Set if @window must be kept below other windows. If the
10956 * window was already below, then this function does nothing.
10958 * On X11, asks the window manager to keep @window below, if the window
10959 * manager supports this operation. Not all window managers support
10960 * this, and some deliberately ignore it or don't have a concept of
10961 * "keep below"; so you can't rely on the window being kept below.
10962 * But it will happen with most standard window managers,
10963 * and GDK makes a best effort to get it to happen.
10968 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
10970 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_keep_below (window, setting);
10974 * gdk_window_get_group:
10975 * @window: a toplevel #GdkWindow
10977 * Returns the group leader window for @window. See gdk_window_set_group().
10979 * Return value: (transfer none): the group leader window for @window
10984 gdk_window_get_group (GdkWindow *window)
10986 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_group (window);
10990 * gdk_window_set_group:
10991 * @window: a toplevel #GdkWindow
10992 * @leader: (allow-none): group leader window, or %NULL to restore the default group leader window
10994 * Sets the group leader window for @window. By default,
10995 * GDK sets the group leader for all toplevel windows
10996 * to a global window implicitly created by GDK. With this function
10997 * you can override this default.
10999 * The group leader window allows the window manager to distinguish
11000 * all windows that belong to a single application. It may for example
11001 * allow users to minimize/unminimize all windows belonging to an
11002 * application at once. You should only set a non-default group window
11003 * if your application pretends to be multiple applications.
11006 gdk_window_set_group (GdkWindow *window,
11009 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_group (window, leader);
11013 * gdk_window_set_decorations:
11014 * @window: a toplevel #GdkWindow
11015 * @decorations: decoration hint mask
11017 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
11018 * This function sets the traditional Motif window manager hints that tell the
11019 * window manager which decorations you would like your window to have.
11020 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
11021 * using the GDK function directly.
11023 * The @decorations argument is the logical OR of the fields in
11024 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
11025 * mask, the other bits indicate which decorations should be turned off.
11026 * If #GDK_DECOR_ALL is not included, then the other bits indicate
11027 * which decorations should be turned on.
11029 * Most window managers honor a decorations hint of 0 to disable all decorations,
11030 * but very few honor all possible combinations of bits.
11034 gdk_window_set_decorations (GdkWindow *window,
11035 GdkWMDecoration decorations)
11037 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_decorations (window, decorations);
11041 * gdk_window_get_decorations:
11042 * @window: The toplevel #GdkWindow to get the decorations from
11043 * @decorations: (out): The window decorations will be written here
11045 * Returns the decorations set on the GdkWindow with
11046 * gdk_window_set_decorations().
11048 * Returns: %TRUE if the window has decorations set, %FALSE otherwise.
11051 gdk_window_get_decorations(GdkWindow *window,
11052 GdkWMDecoration *decorations)
11054 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_decorations (window, decorations);
11058 * gdk_window_set_functions:
11059 * @window: a toplevel #GdkWindow
11060 * @functions: bitmask of operations to allow on @window
11062 * Sets hints about the window management functions to make available
11063 * via buttons on the window frame.
11065 * On the X backend, this function sets the traditional Motif window
11066 * manager hint for this purpose. However, few window managers do
11067 * anything reliable or interesting with this hint. Many ignore it
11070 * The @functions argument is the logical OR of values from the
11071 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
11072 * then the other bits indicate which functions to disable; if
11073 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
11078 gdk_window_set_functions (GdkWindow *window,
11079 GdkWMFunction functions)
11081 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_functions (window, functions);
11085 * gdk_window_begin_resize_drag_for_device:
11086 * @window: a toplevel #GdkWindow
11087 * @edge: the edge or corner from which the drag is started
11088 * @device: the device used for the operation
11089 * @button: the button being used to drag
11090 * @root_x: root window X coordinate of mouse click that began the drag
11091 * @root_y: root window Y coordinate of mouse click that began the drag
11092 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
11094 * Begins a window resize operation (for a toplevel window).
11095 * You might use this function to implement a "window resize grip," for
11096 * example; in fact #GtkStatusbar uses it. The function works best
11097 * with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a
11098 * fallback implementation for other window managers.
11103 gdk_window_begin_resize_drag_for_device (GdkWindow *window,
11104 GdkWindowEdge edge,
11111 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_resize_drag (window, edge, device, button, root_x, root_y, timestamp);
11115 * gdk_window_begin_resize_drag:
11116 * @window: a toplevel #GdkWindow
11117 * @edge: the edge or corner from which the drag is started
11118 * @button: the button being used to drag
11119 * @root_x: root window X coordinate of mouse click that began the drag
11120 * @root_y: root window Y coordinate of mouse click that began the drag
11121 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
11123 * Begins a window resize operation (for a toplevel window).
11125 * This function assumes that the drag is controlled by the
11126 * client pointer device, use gdk_window_begin_resize_drag_for_device()
11127 * to begin a drag with a different device.
11130 gdk_window_begin_resize_drag (GdkWindow *window,
11131 GdkWindowEdge edge,
11137 GdkDeviceManager *device_manager;
11140 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
11141 device = gdk_device_manager_get_client_pointer (device_manager);
11142 gdk_window_begin_resize_drag_for_device (window, edge,
11143 device, button, root_x, root_y, timestamp);
11147 * gdk_window_begin_move_drag_for_device:
11148 * @window: a toplevel #GdkWindow
11149 * @device: the device used for the operation
11150 * @button: the button being used to drag
11151 * @root_x: root window X coordinate of mouse click that began the drag
11152 * @root_y: root window Y coordinate of mouse click that began the drag
11153 * @timestamp: timestamp of mouse click that began the drag
11155 * Begins a window move operation (for a toplevel window).
11156 * You might use this function to implement a "window move grip," for
11157 * example. The function works best with window managers that support
11158 * the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
11159 * Window Manager Hints</ulink>, but has a fallback implementation for
11160 * other window managers.
11165 gdk_window_begin_move_drag_for_device (GdkWindow *window,
11172 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->begin_move_drag (window,
11173 device, button, root_x, root_y, timestamp);
11177 * gdk_window_begin_move_drag:
11178 * @window: a toplevel #GdkWindow
11179 * @button: the button being used to drag
11180 * @root_x: root window X coordinate of mouse click that began the drag
11181 * @root_y: root window Y coordinate of mouse click that began the drag
11182 * @timestamp: timestamp of mouse click that began the drag
11184 * Begins a window move operation (for a toplevel window).
11186 * This function assumes that the drag is controlled by the
11187 * client pointer device, use gdk_window_begin_move_drag_for_device()
11188 * to begin a drag with a different device.
11191 gdk_window_begin_move_drag (GdkWindow *window,
11197 GdkDeviceManager *device_manager;
11200 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
11201 device = gdk_device_manager_get_client_pointer (device_manager);
11202 gdk_window_begin_move_drag_for_device (window, device, button, root_x, root_y, timestamp);
11206 * gdk_window_enable_synchronized_configure:
11207 * @window: a toplevel #GdkWindow
11209 * Does nothing, present only for compatiblity.
11212 * Deprecated: 3.8: this function is no longer needed
11215 gdk_window_enable_synchronized_configure (GdkWindow *window)
11220 * gdk_window_configure_finished:
11221 * @window: a toplevel #GdkWindow
11223 * Does nothing, present only for compatiblity.
11226 * Deprecated: 3.8: this function is no longer needed
11229 gdk_window_configure_finished (GdkWindow *window)
11234 * gdk_window_set_opacity:
11235 * @window: a top-level or non-native #GdkWindow
11236 * @opacity: opacity
11238 * Set @window to render as partially transparent,
11239 * with opacity 0 being fully transparent and 1 fully opaque. (Values
11240 * of the opacity parameter are clamped to the [0,1] range.)
11242 * For toplevel windows this depends on support from the windowing system
11243 * that may not always be there. For instance, On X11, this works only on
11244 * X screens with a compositing manager running.
11246 * For child windows this function only works for non-native windows.
11248 * For setting up per-pixel alpha topelevels, see gdk_screen_get_rgba_visual(),
11249 * and for non-toplevels, see gdk_window_set_composited().
11251 * Support for non-toplevel windows was added in 3.8.
11256 gdk_window_set_opacity (GdkWindow *window,
11261 else if (opacity > 1)
11264 window->alpha = round (opacity * 255);
11266 if (window->destroyed)
11269 if (gdk_window_has_impl (window))
11270 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->set_opacity (window, opacity);
11273 recompute_visible_regions (window, TRUE, FALSE);
11274 gdk_window_invalidate_rect_full (window, NULL, TRUE, CLEAR_BG_ALL);
11278 /* This function is called when the XWindow is really gone.
11281 gdk_window_destroy_notify (GdkWindow *window)
11283 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->destroy_notify (window);
11287 * gdk_window_register_dnd:
11288 * @window: a #GdkWindow.
11290 * Registers a window as a potential drop destination.
11293 gdk_window_register_dnd (GdkWindow *window)
11295 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->register_dnd (window);
11299 * gdk_window_get_drag_protocol:
11300 * @window: the destination window
11301 * @target: (out) (allow-none) (transfer full): location of the window
11302 * where the drop should happen. This may be @window or a proxy window,
11303 * or %NULL if @window does not support Drag and Drop.
11305 * Finds out the DND protocol supported by a window.
11307 * Returns: the supported DND protocol.
11312 gdk_window_get_drag_protocol (GdkWindow *window,
11313 GdkWindow **target)
11315 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_DRAG_PROTO_NONE);
11317 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->get_drag_protocol (window, target);
11322 * @window: the source window for this drag.
11323 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
11324 * as list of #GdkAtoms
11326 * Starts a drag and creates a new drag context for it.
11327 * This function assumes that the drag is controlled by the
11328 * client pointer device, use gdk_drag_begin_for_device() to
11329 * begin a drag with a different device.
11331 * This function is called by the drag source.
11333 * Return value: (transfer full): a newly created #GdkDragContext
11336 gdk_drag_begin (GdkWindow *window,
11339 GdkDeviceManager *device_manager;
11342 device_manager = gdk_display_get_device_manager (gdk_window_get_display (window));
11343 device = gdk_device_manager_get_client_pointer (device_manager);
11345 return gdk_drag_begin_for_device (window, device, targets);
11349 * gdk_drag_begin_for_device:
11350 * @window: the source window for this drag
11351 * @device: the device that controls this drag
11352 * @targets: (transfer none) (element-type GdkAtom): the offered targets,
11353 * as list of #GdkAtoms
11355 * Starts a drag and creates a new drag context for it.
11357 * This function is called by the drag source.
11359 * Return value: (transfer full): a newly created #GdkDragContext
11362 gdk_drag_begin_for_device (GdkWindow *window,
11366 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)->drag_begin (window, device, targets);
11370 * gdk_test_render_sync:
11371 * @window: a mapped #GdkWindow
11373 * Retrieves a pixel from @window to force the windowing
11374 * system to carry out any pending rendering commands.
11376 * This function is intended to be used to synchronize with rendering
11377 * pipelines, to benchmark windowing system rendering operations.
11382 gdk_test_render_sync (GdkWindow *window)
11384 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->sync_rendering (window);
11388 * gdk_test_simulate_key:
11389 * @window: a #GdkWindow to simulate a key event for
11390 * @x: x coordinate within @window for the key event
11391 * @y: y coordinate within @window for the key event
11392 * @keyval: A GDK keyboard value
11393 * @modifiers: Keyboard modifiers the event is setup with
11394 * @key_pressrelease: either %GDK_KEY_PRESS or %GDK_KEY_RELEASE
11396 * This function is intended to be used in GTK+ test programs.
11397 * If (@x,@y) are > (-1,-1), it will warp the mouse pointer to
11398 * the given (@x,@y) coordinates within @window and simulate a
11399 * key press or release event.
11401 * When the mouse pointer is warped to the target location, use
11402 * of this function outside of test programs that run in their
11403 * own virtual windowing system (e.g. Xvfb) is not recommended.
11404 * If (@x,@y) are passed as (-1,-1), the mouse pointer will not
11405 * be warped and @window origin will be used as mouse pointer
11406 * location for the event.
11408 * Also, gdk_test_simulate_key() is a fairly low level function,
11409 * for most testing purposes, gtk_test_widget_send_key() is the
11410 * right function to call which will generate a key press event
11411 * followed by its accompanying key release event.
11413 * Returns: whether all actions necessary for a key event simulation
11414 * were carried out successfully
11419 gdk_test_simulate_key (GdkWindow *window,
11423 GdkModifierType modifiers,
11424 GdkEventType key_pressrelease)
11426 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
11427 ->simulate_key (window, x, y, keyval, modifiers, key_pressrelease);
11431 * gdk_test_simulate_button:
11432 * @window: a #GdkWindow to simulate a button event for
11433 * @x: x coordinate within @window for the button event
11434 * @y: y coordinate within @window for the button event
11435 * @button: Number of the pointer button for the event, usually 1, 2 or 3
11436 * @modifiers: Keyboard modifiers the event is setup with
11437 * @button_pressrelease: either %GDK_BUTTON_PRESS or %GDK_BUTTON_RELEASE
11439 * This function is intended to be used in GTK+ test programs.
11440 * It will warp the mouse pointer to the given (@x,@y) coordinates
11441 * within @window and simulate a button press or release event.
11442 * Because the mouse pointer needs to be warped to the target
11443 * location, use of this function outside of test programs that
11444 * run in their own virtual windowing system (e.g. Xvfb) is not
11447 * Also, gdk_test_simulate_button() is a fairly low level function,
11448 * for most testing purposes, gtk_test_widget_click() is the right
11449 * function to call which will generate a button press event followed
11450 * by its accompanying button release event.
11452 * Returns: whether all actions necessary for a button event simulation
11453 * were carried out successfully
11458 gdk_test_simulate_button (GdkWindow *window,
11461 guint button, /*1..3*/
11462 GdkModifierType modifiers,
11463 GdkEventType button_pressrelease)
11465 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
11466 ->simulate_button (window, x, y, button, modifiers, button_pressrelease);
11470 * gdk_property_get:
11471 * @window: a #GdkWindow
11472 * @property: the property to retrieve
11473 * @type: the desired property type, or %GDK_NONE, if any type of data
11474 * is acceptable. If this does not match the actual
11475 * type, then @actual_format and @actual_length will
11476 * be filled in, a warning will be printed to stderr
11477 * and no data will be returned.
11478 * @offset: the offset into the property at which to begin
11479 * retrieving data, in 4 byte units.
11480 * @length: the length of the data to retrieve in bytes. Data is
11481 * considered to be retrieved in 4 byte chunks, so @length
11482 * will be rounded up to the next highest 4 byte boundary
11483 * (so be careful not to pass a value that might overflow
11484 * when rounded up).
11485 * @pdelete: if %TRUE, delete the property after retrieving the
11487 * @actual_property_type: (out) (transfer none): location to store the
11488 * actual type of the property.
11489 * @actual_format: (out): location to store the actual return format of the
11490 * data; either 8, 16 or 32 bits.
11491 * @actual_length: location to store the length of the retrieved data, in
11492 * bytes. Data returned in the 32 bit format is stored
11493 * in a long variable, so the actual number of 32 bit
11494 * elements should be be calculated via
11495 * @actual_length / sizeof(glong) to ensure portability to
11497 * @data: (out) (array length=actual_length) (transfer full): location
11498 * to store a pointer to the data. The retrieved data should be
11499 * freed with g_free() when you are finished using it.
11501 * Retrieves a portion of the contents of a property. If the
11502 * property does not exist, then the function returns %FALSE,
11503 * and %GDK_NONE will be stored in @actual_property_type.
11507 * The XGetWindowProperty() function that gdk_property_get()
11508 * uses has a very confusing and complicated set of semantics.
11509 * Unfortunately, gdk_property_get() makes the situation
11510 * worse instead of better (the semantics should be considered
11511 * undefined), and also prints warnings to stderr in cases where it
11512 * should return a useful error to the program. You are advised to use
11513 * XGetWindowProperty() directly until a replacement function for
11514 * gdk_property_get()
11519 * Returns: %TRUE if data was successfully received and stored
11520 * in @data, otherwise %FALSE.
11523 gdk_property_get (GdkWindow *window,
11529 GdkAtom *actual_property_type,
11530 gint *actual_format_type,
11531 gint *actual_length,
11534 return GDK_WINDOW_IMPL_GET_CLASS (window->impl)
11535 ->get_property (window, property, type, offset, length, pdelete,
11536 actual_property_type, actual_format_type,
11537 actual_length, data);
11541 * gdk_property_change: (skip)
11542 * @window: a #GdkWindow
11543 * @property: the property to change
11544 * @type: the new type for the property. If @mode is
11545 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
11546 * must match the existing type or an error will occur.
11547 * @format: the new format for the property. If @mode is
11548 * %GDK_PROP_MODE_PREPEND or %GDK_PROP_MODE_APPEND, then this
11549 * must match the existing format or an error will occur.
11550 * @mode: a value describing how the new data is to be combined
11551 * with the current data.
11552 * @data: the data (a <literal>guchar *</literal>
11553 * <literal>gushort *</literal>, or <literal>gulong *</literal>,
11554 * depending on @format), cast to a <literal>guchar *</literal>.
11555 * @nelements: the number of elements of size determined by the format,
11556 * contained in @data.
11558 * Changes the contents of a property on a window.
11561 gdk_property_change (GdkWindow *window,
11566 const guchar *data,
11569 GDK_WINDOW_IMPL_GET_CLASS (window->impl)
11570 ->change_property (window, property, type, format, mode, data, nelements);
11574 * gdk_property_delete:
11575 * @window: a #GdkWindow
11576 * @property: the property to delete
11578 * Deletes a property from a window.
11581 gdk_property_delete (GdkWindow *window,
11584 GDK_WINDOW_IMPL_GET_CLASS (window->impl)->delete_property (window, property);
11588 gdk_window_flush_events (GdkFrameClock *clock,
11592 GdkDisplay *display;
11594 window = GDK_WINDOW (data);
11596 display = gdk_window_get_display (window);
11597 _gdk_display_flush_events (display);
11598 _gdk_display_pause_events (display);
11600 gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_RESUME_EVENTS);
11604 gdk_window_paint_on_clock (GdkFrameClock *clock,
11609 window = GDK_WINDOW (data);
11611 /* Update window and any children on the same clock.
11613 gdk_window_process_updates_with_mode (window, PROCESS_UPDATES_WITH_SAME_CLOCK_CHILDREN);
11617 gdk_window_resume_events (GdkFrameClock *clock,
11621 GdkDisplay *display;
11623 window = GDK_WINDOW (data);
11625 display = gdk_window_get_display (window);
11626 _gdk_display_unpause_events (display);
11630 gdk_window_set_frame_clock (GdkWindow *window,
11631 GdkFrameClock *clock)
11633 g_return_if_fail (GDK_IS_WINDOW (window));
11634 g_return_if_fail (clock == NULL || GDK_IS_FRAME_CLOCK (clock));
11635 g_return_if_fail (clock == NULL || gdk_window_is_toplevel (window));
11637 if (clock == window->frame_clock)
11642 g_object_ref (clock);
11643 g_signal_connect (G_OBJECT (clock),
11645 G_CALLBACK (gdk_window_flush_events),
11647 g_signal_connect (G_OBJECT (clock),
11649 G_CALLBACK (gdk_window_paint_on_clock),
11651 g_signal_connect (G_OBJECT (clock),
11653 G_CALLBACK (gdk_window_resume_events),
11657 if (window->frame_clock)
11659 g_signal_handlers_disconnect_by_func (G_OBJECT (window->frame_clock),
11660 G_CALLBACK (gdk_window_flush_events),
11662 g_signal_handlers_disconnect_by_func (G_OBJECT (window->frame_clock),
11663 G_CALLBACK (gdk_window_paint_on_clock),
11665 g_signal_handlers_disconnect_by_func (G_OBJECT (window->frame_clock),
11666 G_CALLBACK (gdk_window_resume_events),
11668 g_object_unref (window->frame_clock);
11671 window->frame_clock = clock;
11675 * gdk_window_get_frame_clock:
11676 * @window: window to get frame clock for
11678 * Gets the frame clock for the window. The frame clock for a window
11679 * never changes unless the window is reparented to a new toplevel
11683 * Return value: (transfer none): the frame clock
11686 gdk_window_get_frame_clock (GdkWindow *window)
11688 GdkWindow *toplevel;
11690 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
11692 toplevel = gdk_window_get_toplevel (window);
11694 return toplevel->frame_clock;