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 "gdkwindow-x11.h"
30 #include "gdkwindow.h"
31 #include "gdkwindowimpl.h"
32 #include "gdkvisualprivate.h"
33 #include "gdkinternals.h"
34 #include "gdkdeviceprivate.h"
36 #include "gdkeventsource.h"
37 #include "gdkdisplay-x11.h"
38 #include "gdkprivate-x11.h"
43 #include <netinet/in.h>
46 #include <cairo-xlib.h>
51 #include <X11/Xutil.h>
52 #include <X11/Xatom.h>
54 #include <X11/extensions/shape.h>
57 #include <X11/XKBlib.h>
60 #ifdef HAVE_XCOMPOSITE
61 #include <X11/extensions/Xcomposite.h>
65 #include <X11/extensions/Xfixes.h>
69 #include <X11/extensions/Xdamage.h>
72 const int _gdk_x11_event_mask_table[21] =
76 PointerMotionHintMask,
93 SubstructureNotifyMask,
94 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
97 const gint _gdk_x11_event_mask_table_size = G_N_ELEMENTS (_gdk_x11_event_mask_table);
99 /* Forward declarations */
100 static void gdk_window_set_static_win_gravity (GdkWindow *window,
102 static gboolean gdk_window_icon_name_set (GdkWindow *window);
103 static void set_wm_name (GdkDisplay *display,
106 static void move_to_current_desktop (GdkWindow *window);
107 static void gdk_window_x11_set_background (GdkWindow *window,
108 cairo_pattern_t *pattern);
110 static void gdk_window_impl_x11_finalize (GObject *object);
112 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
113 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
114 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
116 #define WINDOW_IS_TOPLEVEL(window) \
117 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
118 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
119 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
121 /* Return whether time1 is considered later than time2 as far as xserver
122 * time is concerned. Accounts for wraparound.
124 #define XSERVER_TIME_IS_LATER(time1, time2) \
125 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
126 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
129 struct _GdkX11Window {
133 struct _GdkX11WindowClass {
134 GdkWindowClass parent_class;
137 G_DEFINE_TYPE (GdkX11Window, gdk_x11_window, GDK_TYPE_WINDOW)
140 gdk_x11_window_class_init (GdkX11WindowClass *x11_window_class)
145 gdk_x11_window_init (GdkX11Window *x11_window)
150 G_DEFINE_TYPE (GdkWindowImplX11, gdk_window_impl_x11, GDK_TYPE_WINDOW_IMPL)
153 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
155 impl->toplevel_window_type = -1;
156 impl->device_cursor = g_hash_table_new_full (NULL, NULL,
157 NULL, g_object_unref);
161 _gdk_x11_window_get_toplevel (GdkWindow *window)
163 GdkWindowImplX11 *impl;
165 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
167 if (!WINDOW_IS_TOPLEVEL (window))
170 impl = GDK_WINDOW_IMPL_X11 (window->impl);
174 impl->toplevel = g_new0 (GdkToplevelX11, 1);
175 impl->toplevel->have_focused = TRUE;
178 return impl->toplevel;
181 static const cairo_user_data_key_t gdk_x11_cairo_key;
184 * _gdk_x11_window_update_size:
185 * @impl: a #GdkWindowImplX11.
187 * Updates the state of the window (in particular the drawable's
188 * cairo surface) when its size has changed.
191 _gdk_x11_window_update_size (GdkWindowImplX11 *impl)
193 if (impl->cairo_surface)
195 cairo_xlib_surface_set_size (impl->cairo_surface,
196 gdk_window_get_width (impl->wrapper),
197 gdk_window_get_height (impl->wrapper));
201 /*****************************************************
202 * X11 specific implementations of generic functions *
203 *****************************************************/
206 gdk_x11_cairo_surface_destroy (void *data)
208 GdkWindowImplX11 *impl = data;
210 impl->cairo_surface = NULL;
213 static cairo_surface_t *
214 gdk_x11_create_cairo_surface (GdkWindowImplX11 *impl,
220 visual = gdk_window_get_visual (impl->wrapper);
221 return cairo_xlib_surface_create (GDK_WINDOW_XDISPLAY (impl->wrapper),
222 GDK_WINDOW_IMPL_X11 (impl)->xid,
223 GDK_VISUAL_XVISUAL (visual),
227 static cairo_surface_t *
228 gdk_x11_ref_cairo_surface (GdkWindow *window)
230 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
232 if (GDK_WINDOW_DESTROYED (window))
235 if (!impl->cairo_surface)
237 impl->cairo_surface = gdk_x11_create_cairo_surface (impl,
238 gdk_window_get_width (window),
239 gdk_window_get_height (window));
241 if (impl->cairo_surface)
242 cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
243 impl, gdk_x11_cairo_surface_destroy);
246 cairo_surface_reference (impl->cairo_surface);
248 return impl->cairo_surface;
252 gdk_window_impl_x11_finalize (GObject *object)
255 GdkWindowImplX11 *impl;
257 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
259 impl = GDK_WINDOW_IMPL_X11 (object);
261 wrapper = impl->wrapper;
263 _gdk_x11_window_grab_check_destroy (wrapper);
265 if (!GDK_WINDOW_DESTROYED (wrapper))
267 GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
269 _gdk_x11_display_remove_window (display, impl->xid);
270 if (impl->toplevel && impl->toplevel->focus_window)
271 _gdk_x11_display_remove_window (display, impl->toplevel->focus_window);
274 g_free (impl->toplevel);
277 g_object_unref (impl->cursor);
279 g_hash_table_destroy (impl->device_cursor);
281 G_OBJECT_CLASS (gdk_window_impl_x11_parent_class)->finalize (object);
290 free_pixmap (gpointer datap)
292 FreePixmapData *data = datap;
294 if (!gdk_display_is_closed (data->display))
296 XFreePixmap (GDK_DISPLAY_XDISPLAY (data->display),
300 g_object_unref (data->display);
301 g_slice_free (FreePixmapData, data);
305 attach_free_pixmap_handler (cairo_surface_t *surface,
309 static const cairo_user_data_key_t key;
310 FreePixmapData *data;
312 data = g_slice_new (FreePixmapData);
313 data->display = g_object_ref (display);
314 data->pixmap = pixmap;
316 cairo_surface_set_user_data (surface, &key, data, free_pixmap);
319 /* Cairo does not guarantee we get an xlib surface if we call
320 * cairo_surface_create_similar(). In some cases however, we must use a
321 * pixmap or bitmap in the X11 API.
322 * These functions ensure an Xlib surface.
325 _gdk_x11_window_create_bitmap_surface (GdkWindow *window,
329 cairo_surface_t *surface;
332 pixmap = XCreatePixmap (GDK_WINDOW_XDISPLAY (window),
333 GDK_WINDOW_XID (window),
335 surface = cairo_xlib_surface_create_for_bitmap (GDK_WINDOW_XDISPLAY (window),
337 GDK_X11_SCREEN (GDK_WINDOW_SCREEN (window))->xscreen,
339 attach_free_pixmap_handler (surface, GDK_WINDOW_DISPLAY (window), pixmap);
344 /* Create a surface backed with a pixmap without alpha on the same screen as window */
345 static cairo_surface_t *
346 gdk_x11_window_create_pixmap_surface (GdkWindow *window,
350 GdkScreen *screen = gdk_window_get_screen (window);
351 GdkVisual *visual = gdk_screen_get_system_visual (screen);
352 cairo_surface_t *surface;
355 pixmap = XCreatePixmap (GDK_WINDOW_XDISPLAY (window),
356 GDK_WINDOW_XID (window),
358 gdk_visual_get_depth (visual));
359 surface = cairo_xlib_surface_create (GDK_WINDOW_XDISPLAY (window),
361 GDK_VISUAL_XVISUAL (visual),
363 attach_free_pixmap_handler (surface, GDK_WINDOW_DISPLAY (window), pixmap);
369 tmp_unset_bg (GdkWindow *window)
371 GdkWindowImplX11 *impl;
373 impl = GDK_WINDOW_IMPL_X11 (window->impl);
377 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
378 GDK_WINDOW_XID (window), None);
382 tmp_reset_bg (GdkWindow *window)
384 GdkWindowImplX11 *impl;
386 impl = GDK_WINDOW_IMPL_X11 (window->impl);
390 gdk_window_x11_set_background (window, window->background);
393 /* Unsetting and resetting window backgrounds.
395 * In many cases it is possible to avoid flicker by unsetting the
396 * background of windows. For example if the background of the
397 * parent window is unset when a window is unmapped, a brief flicker
398 * of background painting is avoided.
401 _gdk_x11_window_tmp_unset_bg (GdkWindow *window,
404 g_return_if_fail (GDK_IS_WINDOW (window));
406 if (window->input_only || window->destroyed ||
407 (window->window_type != GDK_WINDOW_ROOT &&
408 !GDK_WINDOW_IS_MAPPED (window)))
411 if (_gdk_window_has_impl (window) &&
412 GDK_WINDOW_IS_X11 (window) &&
413 window->window_type != GDK_WINDOW_ROOT &&
414 window->window_type != GDK_WINDOW_FOREIGN)
415 tmp_unset_bg (window);
421 for (l = window->children; l != NULL; l = l->next)
422 _gdk_x11_window_tmp_unset_bg (l->data, TRUE);
427 _gdk_x11_window_tmp_unset_parent_bg (GdkWindow *window)
429 if (GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_ROOT)
432 window = _gdk_window_get_impl_window (window->parent);
433 _gdk_x11_window_tmp_unset_bg (window, FALSE);
437 _gdk_x11_window_tmp_reset_bg (GdkWindow *window,
440 g_return_if_fail (GDK_IS_WINDOW (window));
442 if (window->input_only || window->destroyed ||
443 (window->window_type != GDK_WINDOW_ROOT &&
444 !GDK_WINDOW_IS_MAPPED (window)))
448 if (_gdk_window_has_impl (window) &&
449 GDK_WINDOW_IS_X11 (window) &&
450 window->window_type != GDK_WINDOW_ROOT &&
451 window->window_type != GDK_WINDOW_FOREIGN)
452 tmp_reset_bg (window);
458 for (l = window->children; l != NULL; l = l->next)
459 _gdk_x11_window_tmp_reset_bg (l->data, TRUE);
464 _gdk_x11_window_tmp_reset_parent_bg (GdkWindow *window)
466 if (GDK_WINDOW_TYPE (window->parent) == GDK_WINDOW_ROOT)
469 window = _gdk_window_get_impl_window (window->parent);
471 _gdk_x11_window_tmp_reset_bg (window, FALSE);
475 _gdk_x11_screen_init_root_window (GdkScreen *screen)
478 GdkWindowImplX11 *impl;
479 GdkX11Screen *x11_screen;
481 x11_screen = GDK_X11_SCREEN (screen);
483 g_assert (x11_screen->root_window == NULL);
485 window = x11_screen->root_window = _gdk_display_create_window (gdk_screen_get_display (screen));
487 window->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_X11, NULL);
488 window->impl_window = window;
489 window->visual = gdk_screen_get_system_visual (screen);
491 impl = GDK_WINDOW_IMPL_X11 (window->impl);
493 impl->xid = x11_screen->xroot_window;
494 impl->wrapper = window;
496 window->window_type = GDK_WINDOW_ROOT;
497 window->depth = DefaultDepthOfScreen (x11_screen->xscreen);
503 window->width = WidthOfScreen (x11_screen->xscreen);
504 window->height = HeightOfScreen (x11_screen->xscreen);
505 window->viewable = TRUE;
507 /* see init_randr_support() in gdkscreen-x11.c */
508 window->event_mask = GDK_STRUCTURE_MASK;
510 _gdk_window_update_size (x11_screen->root_window);
512 _gdk_x11_display_add_window (x11_screen->display,
513 &x11_screen->xroot_window,
514 x11_screen->root_window);
518 set_wm_protocols (GdkWindow *window)
520 GdkDisplay *display = gdk_window_get_display (window);
524 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
525 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
526 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
529 if (GDK_X11_DISPLAY (display)->use_sync)
530 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
533 XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
537 get_default_title (void)
541 title = g_get_application_name ();
543 title = g_get_prgname ();
551 check_leader_window_title (GdkDisplay *display)
553 GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
555 if (display_x11->leader_window && !display_x11->leader_window_title_set)
557 set_wm_name (display,
558 display_x11->leader_window,
559 get_default_title ());
561 display_x11->leader_window_title_set = TRUE;
566 create_focus_window (GdkDisplay *display,
569 GdkX11Display *display_x11;
570 GdkEventMask event_mask;
574 xdisplay = GDK_DISPLAY_XDISPLAY (display);
575 display_x11 = GDK_X11_DISPLAY (display);
577 focus_window = XCreateSimpleWindow (xdisplay, parent,
581 /* FIXME: probably better to actually track the requested event mask for the toplevel
583 event_mask = (GDK_KEY_PRESS_MASK |
584 GDK_KEY_RELEASE_MASK |
585 GDK_FOCUS_CHANGE_MASK);
587 gdk_x11_event_source_select_events ((GdkEventSource *) display_x11->event_source,
591 XMapWindow (xdisplay, focus_window);
597 ensure_sync_counter (GdkWindow *window)
600 if (!GDK_WINDOW_DESTROYED (window))
602 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
603 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
604 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
606 if (toplevel && impl->use_synchronized_configure &&
607 toplevel->update_counter == None &&
608 GDK_X11_DISPLAY (display)->use_sync)
610 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
614 XSyncIntToValue (&value, 0);
616 toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
618 atom = gdk_x11_get_xatom_by_name_for_display (display,
619 "_NET_WM_SYNC_REQUEST_COUNTER");
621 XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
624 (guchar *)&toplevel->update_counter, 1);
626 XSyncIntToValue (&toplevel->current_counter_value, 0);
633 setup_toplevel_window (GdkWindow *window,
636 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
637 GdkDisplay *display = gdk_window_get_display (window);
638 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
639 XID xid = GDK_WINDOW_XID (window);
640 GdkX11Screen *x11_screen = GDK_X11_SCREEN (GDK_WINDOW_SCREEN (parent));
641 XSizeHints size_hints;
643 Window leader_window;
645 set_wm_protocols (window);
647 if (!window->input_only)
649 /* The focus window is off the visible area, and serves to receive key
650 * press events so they don't get sent to child windows.
652 toplevel->focus_window = create_focus_window (display, xid);
653 _gdk_x11_display_add_window (x11_screen->display,
654 &toplevel->focus_window,
658 check_leader_window_title (x11_screen->display);
660 /* FIXME: Is there any point in doing this? Do any WM's pay
661 * attention to PSize, and even if they do, is this the
664 size_hints.flags = PSize;
665 size_hints.width = window->width;
666 size_hints.height = window->height;
668 XSetWMNormalHints (xdisplay, xid, &size_hints);
670 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
671 XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
674 XChangeProperty (xdisplay, xid,
675 gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_PID"),
680 leader_window = GDK_X11_DISPLAY (x11_screen->display)->leader_window;
683 XChangeProperty (xdisplay, xid,
684 gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "WM_CLIENT_LEADER"),
685 XA_WINDOW, 32, PropModeReplace,
686 (guchar *) &leader_window, 1);
688 if (toplevel->focus_window != None)
689 XChangeProperty (xdisplay, xid,
690 gdk_x11_get_xatom_by_name_for_display (x11_screen->display, "_NET_WM_USER_TIME_WINDOW"),
691 XA_WINDOW, 32, PropModeReplace,
692 (guchar *) &toplevel->focus_window, 1);
694 if (!window->focus_on_map)
695 gdk_x11_window_set_user_time (window, 0);
696 else if (GDK_X11_DISPLAY (x11_screen->display)->user_time != 0)
697 gdk_x11_window_set_user_time (window, GDK_X11_DISPLAY (x11_screen->display)->user_time);
699 ensure_sync_counter (window);
703 _gdk_x11_display_create_window_impl (GdkDisplay *display,
705 GdkWindow *real_parent,
707 GdkEventMask event_mask,
708 GdkWindowAttr *attributes,
709 gint attributes_mask)
711 GdkWindowImplX11 *impl;
712 GdkX11Screen *x11_screen;
713 GdkX11Display *display_x11;
719 XSetWindowAttributes xattributes;
720 long xattributes_mask;
721 XClassHint *class_hint;
726 display_x11 = GDK_X11_DISPLAY (display);
727 xparent = GDK_WINDOW_XID (real_parent);
728 x11_screen = GDK_X11_SCREEN (screen);
730 impl = g_object_new (GDK_TYPE_WINDOW_IMPL_X11, NULL);
731 window->impl = GDK_WINDOW_IMPL (impl);
732 impl->wrapper = GDK_WINDOW (window);
734 xdisplay = x11_screen->xdisplay;
736 xattributes_mask = 0;
738 xvisual = gdk_x11_visual_get_xvisual (window->visual);
740 if (attributes_mask & GDK_WA_NOREDIR)
742 xattributes.override_redirect =
743 (attributes->override_redirect == FALSE)?False:True;
744 xattributes_mask |= CWOverrideRedirect;
747 xattributes.override_redirect = False;
749 impl->override_redirect = xattributes.override_redirect;
751 if (window->parent && window->parent->guffaw_gravity)
753 xattributes.win_gravity = StaticGravity;
754 xattributes_mask |= CWWinGravity;
758 switch (window->window_type)
760 case GDK_WINDOW_TOPLEVEL:
761 case GDK_WINDOW_TEMP:
762 if (GDK_WINDOW_TYPE (window->parent) != GDK_WINDOW_ROOT)
764 /* The common code warns for this case */
765 xparent = GDK_SCREEN_XROOTWIN (screen);
769 if (!window->input_only)
773 xattributes.background_pixel = BlackPixel (xdisplay, x11_screen->screen_num);
775 xattributes.border_pixel = BlackPixel (xdisplay, x11_screen->screen_num);
776 xattributes_mask |= CWBorderPixel | CWBackPixel;
778 if (window->guffaw_gravity)
779 xattributes.bit_gravity = StaticGravity;
781 xattributes.bit_gravity = NorthWestGravity;
783 xattributes_mask |= CWBitGravity;
785 xattributes.colormap = _gdk_visual_get_x11_colormap (window->visual);
786 xattributes_mask |= CWColormap;
788 if (window->window_type == GDK_WINDOW_TEMP)
790 xattributes.save_under = True;
791 xattributes.override_redirect = True;
792 xattributes.cursor = None;
793 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
795 impl->override_redirect = TRUE;
803 if (window->width > 65535 ||
804 window->height > 65535)
806 g_warning ("Native Windows wider or taller than 65535 pixels are not supported");
808 if (window->width > 65535)
809 window->width = 65535;
810 if (window->height > 65535)
811 window->height = 65535;
814 impl->xid = XCreateWindow (xdisplay, xparent,
815 window->x + window->parent->abs_x,
816 window->y + window->parent->abs_y,
817 window->width, window->height,
818 0, window->depth, class, xvisual,
819 xattributes_mask, &xattributes);
821 g_object_ref (window);
822 _gdk_x11_display_add_window (x11_screen->display, &impl->xid, window);
824 switch (GDK_WINDOW_TYPE (window))
826 case GDK_WINDOW_TOPLEVEL:
827 case GDK_WINDOW_TEMP:
828 if (attributes_mask & GDK_WA_TITLE)
829 title = attributes->title;
831 title = get_default_title ();
833 gdk_window_set_title (window, title);
835 if (attributes_mask & GDK_WA_WMCLASS)
837 class_hint = XAllocClassHint ();
838 class_hint->res_name = attributes->wmclass_name;
839 class_hint->res_class = attributes->wmclass_class;
840 XSetClassHint (xdisplay, impl->xid, class_hint);
844 setup_toplevel_window (window, window->parent);
847 case GDK_WINDOW_CHILD:
852 if (attributes_mask & GDK_WA_TYPE_HINT)
853 gdk_window_set_type_hint (window, attributes->type_hint);
855 gdk_x11_event_source_select_events ((GdkEventSource *) display_x11->event_source,
856 GDK_WINDOW_XID (window), event_mask,
857 StructureNotifyMask | PropertyChangeMask);
861 x_event_mask_to_gdk_event_mask (long mask)
863 GdkEventMask event_mask = 0;
866 for (i = 0; i < _gdk_x11_event_mask_table_size; i++)
868 if (mask & _gdk_x11_event_mask_table[i])
869 event_mask |= 1 << (i + 1);
876 * gdk_x11_window_foreign_new_for_display:
877 * @display: the #GdkDisplay where the window handle comes from.
878 * @window: an XLib <type>Window</type>
880 * Wraps a native window in a #GdkWindow. The function will try to
881 * look up the window using gdk_x11_window_lookup_for_display() first.
882 * If it does not find it there, it will create a new window.
884 * This may fail if the window has been destroyed. If the window
885 * was already known to GDK, a new reference to the existing
886 * #GdkWindow is returned.
888 * Return value: (transfer full): a #GdkWindow wrapper for the native
889 * window, or %NULL if the window has been destroyed. The wrapper
890 * will be newly created, if one doesn't exist already.
895 gdk_x11_window_foreign_new_for_display (GdkDisplay *display,
900 GdkWindowImplX11 *impl;
901 GdkX11Display *display_x11;
902 XWindowAttributes attrs;
904 Window *children = NULL;
908 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
910 display_x11 = GDK_X11_DISPLAY (display);
912 if ((win = gdk_x11_window_lookup_for_display (display, window)) != NULL)
913 return g_object_ref (win);
915 gdk_x11_display_error_trap_push (display);
916 result = XGetWindowAttributes (display_x11->xdisplay, window, &attrs);
917 if (gdk_x11_display_error_trap_pop (display) || !result)
920 /* FIXME: This is pretty expensive.
921 * Maybe the caller should supply the parent
923 gdk_x11_display_error_trap_push (display);
924 result = XQueryTree (display_x11->xdisplay, window, &root, &parent, &children, &nchildren);
925 if (gdk_x11_display_error_trap_pop (display) || !result)
931 screen = _gdk_x11_display_screen_for_xrootwin (display, root);
933 win = _gdk_display_create_window (display);
934 win->impl = g_object_new (GDK_TYPE_WINDOW_IMPL_X11, NULL);
935 win->impl_window = win;
936 win->visual = gdk_x11_screen_lookup_visual (screen,
937 XVisualIDFromVisual (attrs.visual));
939 impl = GDK_WINDOW_IMPL_X11 (win->impl);
942 win->parent = gdk_x11_window_lookup_for_display (display, parent);
944 if (!win->parent || GDK_WINDOW_TYPE (win->parent) == GDK_WINDOW_FOREIGN)
945 win->parent = gdk_screen_get_root_window (screen);
947 win->parent->children = g_list_prepend (win->parent->children, win);
953 win->width = attrs.width;
954 win->height = attrs.height;
955 win->window_type = GDK_WINDOW_FOREIGN;
956 win->destroyed = FALSE;
958 win->event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
960 if (attrs.map_state == IsUnmapped)
961 win->state = GDK_WINDOW_STATE_WITHDRAWN;
964 win->viewable = TRUE;
966 win->depth = attrs.depth;
969 _gdk_x11_display_add_window (display, &GDK_WINDOW_XID (win), win);
971 /* Update the clip region, etc */
972 _gdk_window_update_size (win);
978 gdk_toplevel_x11_free_contents (GdkDisplay *display,
979 GdkToplevelX11 *toplevel)
981 if (toplevel->icon_pixmap)
983 cairo_surface_destroy (toplevel->icon_pixmap);
984 toplevel->icon_pixmap = NULL;
986 if (toplevel->icon_mask)
988 cairo_surface_destroy (toplevel->icon_mask);
989 toplevel->icon_mask = NULL;
991 if (toplevel->group_leader)
993 g_object_unref (toplevel->group_leader);
994 toplevel->group_leader = NULL;
997 if (toplevel->update_counter != None)
999 XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display),
1000 toplevel->update_counter);
1001 toplevel->update_counter = None;
1003 XSyncIntToValue (&toplevel->current_counter_value, 0);
1009 gdk_x11_window_destroy (GdkWindow *window,
1011 gboolean foreign_destroy)
1013 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
1014 GdkToplevelX11 *toplevel;
1016 g_return_if_fail (GDK_IS_WINDOW (window));
1018 _gdk_x11_selection_window_destroyed (window);
1020 toplevel = _gdk_x11_window_get_toplevel (window);
1022 gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
1024 if (impl->cairo_surface)
1026 cairo_surface_finish (impl->cairo_surface);
1027 cairo_surface_set_user_data (impl->cairo_surface, &gdk_x11_cairo_key,
1031 if (!recursing && !foreign_destroy)
1032 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1035 static cairo_surface_t *
1036 gdk_window_x11_resize_cairo_surface (GdkWindow *window,
1037 cairo_surface_t *surface,
1041 cairo_xlib_surface_set_size (surface, width, height);
1047 gdk_x11_window_destroy_foreign (GdkWindow *window)
1049 /* It's somebody else's window, but in our hierarchy,
1050 * so reparent it to the root window, and then send
1051 * it a delete event, as if we were a WM
1053 XClientMessageEvent xclient;
1054 GdkDisplay *display;
1056 display = GDK_WINDOW_DISPLAY (window);
1057 gdk_x11_display_error_trap_push (display);
1058 gdk_window_hide (window);
1059 gdk_window_reparent (window, NULL, 0, 0);
1061 memset (&xclient, 0, sizeof (xclient));
1062 xclient.type = ClientMessage;
1063 xclient.window = GDK_WINDOW_XID (window);
1064 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "WM_PROTOCOLS");
1065 xclient.format = 32;
1066 xclient.data.l[0] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
1067 xclient.data.l[1] = CurrentTime;
1068 xclient.data.l[2] = 0;
1069 xclient.data.l[3] = 0;
1070 xclient.data.l[4] = 0;
1072 XSendEvent (GDK_WINDOW_XDISPLAY (window),
1073 GDK_WINDOW_XID (window),
1074 False, 0, (XEvent *)&xclient);
1075 gdk_x11_display_error_trap_pop_ignored (display);
1079 get_root (GdkWindow *window)
1081 GdkScreen *screen = gdk_window_get_screen (window);
1083 return gdk_screen_get_root_window (screen);
1086 /* This function is called when the XWindow is really gone.
1089 gdk_x11_window_destroy_notify (GdkWindow *window)
1091 GdkWindowImplX11 *window_impl;
1093 window_impl = GDK_WINDOW_IMPL_X11 ((window)->impl);
1095 if (!GDK_WINDOW_DESTROYED (window))
1097 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
1098 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
1100 _gdk_window_destroy (window, TRUE);
1103 _gdk_x11_display_remove_window (GDK_WINDOW_DISPLAY (window), GDK_WINDOW_XID (window));
1104 if (window_impl->toplevel && window_impl->toplevel->focus_window)
1105 _gdk_x11_display_remove_window (GDK_WINDOW_DISPLAY (window), window_impl->toplevel->focus_window);
1107 _gdk_x11_window_grab_check_destroy (window);
1109 g_object_unref (window);
1112 static GdkDragProtocol
1113 gdk_x11_window_get_drag_protocol (GdkWindow *window,
1116 GdkDragProtocol protocol;
1117 GdkDisplay *display;
1121 display = gdk_window_get_display (window);
1122 xid = _gdk_x11_display_get_drag_protocol (display,
1123 GDK_WINDOW_XID (window->impl_window),
1130 *target = gdk_x11_window_foreign_new_for_display (display, xid);
1139 update_wm_hints (GdkWindow *window,
1142 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
1143 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1147 !toplevel->is_leader &&
1148 window->state & GDK_WINDOW_STATE_WITHDRAWN)
1151 wm_hints.flags = StateHint | InputHint;
1152 wm_hints.input = window->accept_focus ? True : False;
1153 wm_hints.initial_state = NormalState;
1155 if (window->state & GDK_WINDOW_STATE_ICONIFIED)
1157 wm_hints.flags |= StateHint;
1158 wm_hints.initial_state = IconicState;
1161 if (toplevel->icon_pixmap)
1163 wm_hints.flags |= IconPixmapHint;
1164 wm_hints.icon_pixmap = cairo_xlib_surface_get_drawable (toplevel->icon_pixmap);
1167 if (toplevel->icon_mask)
1169 wm_hints.flags |= IconMaskHint;
1170 wm_hints.icon_mask = cairo_xlib_surface_get_drawable (toplevel->icon_mask);
1173 wm_hints.flags |= WindowGroupHint;
1174 if (toplevel->group_leader && !GDK_WINDOW_DESTROYED (toplevel->group_leader))
1176 wm_hints.flags |= WindowGroupHint;
1177 wm_hints.window_group = GDK_WINDOW_XID (toplevel->group_leader);
1180 wm_hints.window_group = GDK_X11_DISPLAY (display)->leader_window;
1182 if (toplevel->urgency_hint)
1183 wm_hints.flags |= XUrgencyHint;
1185 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1186 GDK_WINDOW_XID (window),
1191 set_initial_hints (GdkWindow *window)
1193 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1194 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1195 Window xwindow = GDK_WINDOW_XID (window);
1196 GdkToplevelX11 *toplevel;
1200 toplevel = _gdk_x11_window_get_toplevel (window);
1205 update_wm_hints (window, TRUE);
1207 /* We set the spec hints regardless of whether the spec is supported,
1208 * since it can't hurt and it's kind of expensive to check whether
1214 if (window->state & GDK_WINDOW_STATE_MAXIMIZED)
1216 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1217 "_NET_WM_STATE_MAXIMIZED_VERT");
1219 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1220 "_NET_WM_STATE_MAXIMIZED_HORZ");
1222 toplevel->have_maxhorz = toplevel->have_maxvert = TRUE;
1225 if (window->state & GDK_WINDOW_STATE_ABOVE)
1227 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1228 "_NET_WM_STATE_ABOVE");
1232 if (window->state & GDK_WINDOW_STATE_BELOW)
1234 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1235 "_NET_WM_STATE_BELOW");
1239 if (window->state & GDK_WINDOW_STATE_STICKY)
1241 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1242 "_NET_WM_STATE_STICKY");
1244 toplevel->have_sticky = TRUE;
1247 if (window->state & GDK_WINDOW_STATE_FULLSCREEN)
1249 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1250 "_NET_WM_STATE_FULLSCREEN");
1252 toplevel->have_fullscreen = TRUE;
1255 if (window->modal_hint)
1257 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1258 "_NET_WM_STATE_MODAL");
1262 if (toplevel->skip_taskbar_hint)
1264 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1265 "_NET_WM_STATE_SKIP_TASKBAR");
1269 if (toplevel->skip_pager_hint)
1271 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1272 "_NET_WM_STATE_SKIP_PAGER");
1276 if (window->state & GDK_WINDOW_STATE_ICONIFIED)
1278 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1279 "_NET_WM_STATE_HIDDEN");
1281 toplevel->have_hidden = TRUE;
1286 XChangeProperty (xdisplay,
1288 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
1289 XA_ATOM, 32, PropModeReplace,
1290 (guchar*) atoms, i);
1294 XDeleteProperty (xdisplay,
1296 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"));
1299 if (window->state & GDK_WINDOW_STATE_STICKY)
1301 atoms[0] = 0xFFFFFFFF;
1302 XChangeProperty (xdisplay,
1304 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
1305 XA_CARDINAL, 32, PropModeReplace,
1306 (guchar*) atoms, 1);
1307 toplevel->on_all_desktops = TRUE;
1311 XDeleteProperty (xdisplay,
1313 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"));
1316 toplevel->map_serial = NextRequest (xdisplay);
1320 gdk_window_x11_show (GdkWindow *window, gboolean already_mapped)
1322 GdkDisplay *display;
1323 GdkX11Display *display_x11;
1324 GdkToplevelX11 *toplevel;
1325 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
1326 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
1327 Window xwindow = GDK_WINDOW_XID (window);
1330 if (!already_mapped)
1331 set_initial_hints (window);
1333 if (WINDOW_IS_TOPLEVEL (window))
1335 display = gdk_window_get_display (window);
1336 display_x11 = GDK_X11_DISPLAY (display);
1337 toplevel = _gdk_x11_window_get_toplevel (window);
1339 if (toplevel->user_time != 0 &&
1340 display_x11->user_time != 0 &&
1341 XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time))
1342 gdk_x11_window_set_user_time (window, display_x11->user_time);
1345 unset_bg = !window->input_only &&
1346 (window->window_type == GDK_WINDOW_CHILD ||
1347 impl->override_redirect) &&
1348 gdk_window_is_viewable (window);
1351 _gdk_x11_window_tmp_unset_bg (window, TRUE);
1353 XMapWindow (xdisplay, xwindow);
1356 _gdk_x11_window_tmp_reset_bg (window, TRUE);
1360 pre_unmap (GdkWindow *window)
1362 GdkWindow *start_window = NULL;
1364 if (window->input_only)
1367 if (window->window_type == GDK_WINDOW_CHILD)
1368 start_window = _gdk_window_get_impl_window ((GdkWindow *)window->parent);
1369 else if (window->window_type == GDK_WINDOW_TEMP)
1370 start_window = get_root (window);
1373 _gdk_x11_window_tmp_unset_bg (start_window, TRUE);
1377 post_unmap (GdkWindow *window)
1379 GdkWindow *start_window = NULL;
1381 if (window->input_only)
1384 if (window->window_type == GDK_WINDOW_CHILD)
1385 start_window = _gdk_window_get_impl_window ((GdkWindow *)window->parent);
1386 else if (window->window_type == GDK_WINDOW_TEMP)
1387 start_window = get_root (window);
1391 _gdk_x11_window_tmp_reset_bg (start_window, TRUE);
1393 if (window->window_type == GDK_WINDOW_CHILD && window->parent)
1395 GdkRectangle invalid_rect;
1397 gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
1398 invalid_rect.width = gdk_window_get_width (window);
1399 invalid_rect.height = gdk_window_get_height (window);
1400 gdk_window_invalidate_rect ((GdkWindow *)window->parent,
1401 &invalid_rect, TRUE);
1407 gdk_window_x11_hide (GdkWindow *window)
1409 /* We'll get the unmap notify eventually, and handle it then,
1410 * but checking here makes things more consistent if we are
1411 * just doing stuff ourself.
1413 _gdk_x11_window_grab_check_unmap (window,
1414 NextRequest (GDK_WINDOW_XDISPLAY (window)));
1416 /* You can't simply unmap toplevel windows. */
1417 switch (window->window_type)
1419 case GDK_WINDOW_TOPLEVEL:
1420 case GDK_WINDOW_TEMP: /* ? */
1421 gdk_window_withdraw (window);
1424 case GDK_WINDOW_FOREIGN:
1425 case GDK_WINDOW_ROOT:
1426 case GDK_WINDOW_CHILD:
1430 _gdk_window_clear_update_area (window);
1433 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
1434 GDK_WINDOW_XID (window));
1435 post_unmap (window);
1439 gdk_window_x11_withdraw (GdkWindow *window)
1441 if (!window->destroyed)
1443 if (GDK_WINDOW_IS_MAPPED (window))
1444 gdk_synthesize_window_state (window,
1446 GDK_WINDOW_STATE_WITHDRAWN);
1448 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1452 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
1453 GDK_WINDOW_XID (window), 0);
1455 post_unmap (window);
1460 window_x11_move (GdkWindow *window,
1464 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
1466 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1468 _gdk_x11_window_move_resize_child (window,
1470 window->width, window->height);
1474 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
1475 GDK_WINDOW_XID (window),
1478 if (impl->override_redirect)
1487 window_x11_resize (GdkWindow *window,
1497 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1499 _gdk_x11_window_move_resize_child (window,
1500 window->x, window->y,
1505 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
1507 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
1508 GDK_WINDOW_XID (window),
1511 if (impl->override_redirect)
1513 window->width = width;
1514 window->height = height;
1515 _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
1519 if (width != window->width || height != window->height)
1520 window->resize_count += 1;
1524 _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
1528 window_x11_move_resize (GdkWindow *window,
1540 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1542 _gdk_x11_window_move_resize_child (window, x, y, width, height);
1543 _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
1547 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
1549 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
1550 GDK_WINDOW_XID (window),
1551 x, y, width, height);
1553 if (impl->override_redirect)
1558 window->width = width;
1559 window->height = height;
1561 _gdk_x11_window_update_size (GDK_WINDOW_IMPL_X11 (window->impl));
1565 if (width != window->width || height != window->height)
1566 window->resize_count += 1;
1572 gdk_window_x11_move_resize (GdkWindow *window,
1579 if (with_move && (width < 0 && height < 0))
1580 window_x11_move (window, x, y);
1584 window_x11_move_resize (window, x, y, width, height);
1586 window_x11_resize (window, width, height);
1591 gdk_window_x11_reparent (GdkWindow *window,
1592 GdkWindow *new_parent,
1596 GdkWindowImplX11 *impl;
1598 impl = GDK_WINDOW_IMPL_X11 (window->impl);
1600 _gdk_x11_window_tmp_unset_bg (window, TRUE);
1601 _gdk_x11_window_tmp_unset_parent_bg (window);
1602 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1603 GDK_WINDOW_XID (window),
1604 GDK_WINDOW_XID (new_parent),
1605 new_parent->abs_x + x, new_parent->abs_y + y);
1606 _gdk_x11_window_tmp_reset_parent_bg (window);
1607 _gdk_x11_window_tmp_reset_bg (window, TRUE);
1609 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1610 new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1612 window->parent = new_parent;
1614 /* Switch the window type as appropriate */
1616 switch (GDK_WINDOW_TYPE (new_parent))
1618 case GDK_WINDOW_ROOT:
1619 case GDK_WINDOW_FOREIGN:
1620 /* Reparenting to toplevel */
1622 if (!WINDOW_IS_TOPLEVEL (window) &&
1623 GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1625 /* This is also done in common code at a later stage, but we
1626 need it in setup_toplevel, so do it here too */
1627 if (window->toplevel_window_type != -1)
1628 GDK_WINDOW_TYPE (window) = window->toplevel_window_type;
1629 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1630 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1632 /* Wasn't a toplevel, set up */
1633 setup_toplevel_window (window, new_parent);
1638 case GDK_WINDOW_TOPLEVEL:
1639 case GDK_WINDOW_CHILD:
1640 case GDK_WINDOW_TEMP:
1641 if (WINDOW_IS_TOPLEVEL (window) &&
1644 if (impl->toplevel->focus_window)
1646 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window);
1647 _gdk_x11_display_remove_window (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
1650 gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window),
1652 g_free (impl->toplevel);
1653 impl->toplevel = NULL;
1661 gdk_window_x11_raise (GdkWindow *window)
1663 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1667 gdk_window_x11_restack_under (GdkWindow *window,
1668 GList *native_siblings /* in requested order, first is bottom-most */)
1674 n_windows = g_list_length (native_siblings) + 1;
1675 windows = g_new (Window, n_windows);
1677 windows[0] = GDK_WINDOW_XID (window);
1678 /* Reverse order, as input order is bottom-most first */
1680 for (l = native_siblings; l != NULL; l = l->next)
1681 windows[i--] = GDK_WINDOW_XID (l->data);
1683 XRestackWindows (GDK_WINDOW_XDISPLAY (window), windows, n_windows);
1689 gdk_window_x11_restack_toplevel (GdkWindow *window,
1693 XWindowChanges changes;
1695 changes.sibling = GDK_WINDOW_XID (sibling);
1696 changes.stack_mode = above ? Above : Below;
1697 XReconfigureWMWindow (GDK_WINDOW_XDISPLAY (window),
1698 GDK_WINDOW_XID (window),
1699 gdk_screen_get_number (GDK_WINDOW_SCREEN (window)),
1700 CWStackMode | CWSibling, &changes);
1704 gdk_window_x11_lower (GdkWindow *window)
1706 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1710 * gdk_x11_window_move_to_current_desktop:
1711 * @window: (type GdkX11Window): a #GdkWindow
1713 * Moves the window to the correct workspace when running under a
1714 * window manager that supports multiple workspaces, as described
1715 * in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
1716 * Window Manager Hints</ulink>. Will not do anything if the
1717 * window is already on all workspaces.
1722 gdk_x11_window_move_to_current_desktop (GdkWindow *window)
1724 GdkToplevelX11 *toplevel;
1726 g_return_if_fail (GDK_IS_WINDOW (window));
1727 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1729 toplevel = _gdk_x11_window_get_toplevel (window);
1731 if (toplevel->on_all_desktops)
1734 move_to_current_desktop (window);
1738 move_to_current_desktop (GdkWindow *window)
1740 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
1741 gdk_atom_intern_static_string ("_NET_WM_DESKTOP")))
1748 gulong *current_desktop;
1749 GdkDisplay *display;
1751 display = gdk_window_get_display (window);
1753 /* Get current desktop, then set it; this is a race, but not
1754 * one that matters much in practice.
1756 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
1757 GDK_WINDOW_XROOTWIN (window),
1758 gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
1760 False, XA_CARDINAL, &type, &format, &nitems,
1761 &bytes_after, &data);
1763 if (type == XA_CARDINAL)
1765 XClientMessageEvent xclient;
1766 current_desktop = (gulong *)data;
1768 memset (&xclient, 0, sizeof (xclient));
1769 xclient.type = ClientMessage;
1771 xclient.send_event = True;
1772 xclient.window = GDK_WINDOW_XID (window);
1773 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
1774 xclient.format = 32;
1776 xclient.data.l[0] = *current_desktop;
1777 xclient.data.l[1] = 1; /* source indication */
1778 xclient.data.l[2] = 0;
1779 xclient.data.l[3] = 0;
1780 xclient.data.l[4] = 0;
1782 XSendEvent (GDK_DISPLAY_XDISPLAY (display),
1783 GDK_WINDOW_XROOTWIN (window),
1785 SubstructureRedirectMask | SubstructureNotifyMask,
1786 (XEvent *)&xclient);
1788 XFree (current_desktop);
1794 gdk_x11_window_focus (GdkWindow *window,
1797 GdkDisplay *display;
1799 g_return_if_fail (GDK_IS_WINDOW (window));
1801 if (GDK_WINDOW_DESTROYED (window) ||
1802 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1805 display = GDK_WINDOW_DISPLAY (window);
1807 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
1808 gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
1810 XClientMessageEvent xclient;
1812 memset (&xclient, 0, sizeof (xclient));
1813 xclient.type = ClientMessage;
1814 xclient.window = GDK_WINDOW_XID (window);
1815 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
1816 "_NET_ACTIVE_WINDOW");
1817 xclient.format = 32;
1818 xclient.data.l[0] = 1; /* requestor type; we're an app */
1819 xclient.data.l[1] = timestamp;
1820 xclient.data.l[2] = None; /* currently active window */
1821 xclient.data.l[3] = 0;
1822 xclient.data.l[4] = 0;
1824 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
1825 SubstructureRedirectMask | SubstructureNotifyMask,
1826 (XEvent *)&xclient);
1830 XRaiseWindow (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window));
1832 /* There is no way of knowing reliably whether we are viewable;
1833 * so trap errors asynchronously around the XSetInputFocus call
1835 gdk_x11_display_error_trap_push (display);
1836 XSetInputFocus (GDK_DISPLAY_XDISPLAY (display),
1837 GDK_WINDOW_XID (window),
1840 gdk_x11_display_error_trap_pop_ignored (display);
1845 gdk_x11_window_set_type_hint (GdkWindow *window,
1846 GdkWindowTypeHint hint)
1848 GdkDisplay *display;
1851 if (GDK_WINDOW_DESTROYED (window) ||
1852 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1855 display = gdk_window_get_display (window);
1859 case GDK_WINDOW_TYPE_HINT_DIALOG:
1860 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
1862 case GDK_WINDOW_TYPE_HINT_MENU:
1863 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU");
1865 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1866 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR");
1868 case GDK_WINDOW_TYPE_HINT_UTILITY:
1869 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
1871 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1872 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
1874 case GDK_WINDOW_TYPE_HINT_DOCK:
1875 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
1877 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1878 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
1880 case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
1881 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
1883 case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
1884 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
1886 case GDK_WINDOW_TYPE_HINT_TOOLTIP:
1887 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
1889 case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
1890 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
1892 case GDK_WINDOW_TYPE_HINT_COMBO:
1893 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
1895 case GDK_WINDOW_TYPE_HINT_DND:
1896 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
1899 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
1901 case GDK_WINDOW_TYPE_HINT_NORMAL:
1902 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL");
1906 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
1907 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
1908 XA_ATOM, 32, PropModeReplace,
1909 (guchar *)&atom, 1);
1912 static GdkWindowTypeHint
1913 gdk_x11_window_get_type_hint (GdkWindow *window)
1915 GdkDisplay *display;
1916 GdkWindowTypeHint type;
1919 gulong nitems_return;
1920 gulong bytes_after_return;
1921 guchar *data = NULL;
1923 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
1925 if (GDK_WINDOW_DESTROYED (window) ||
1926 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1927 return GDK_WINDOW_TYPE_HINT_NORMAL;
1929 type = GDK_WINDOW_TYPE_HINT_NORMAL;
1931 display = gdk_window_get_display (window);
1933 if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
1934 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
1935 0, G_MAXLONG, False, XA_ATOM, &type_return,
1936 &format_return, &nitems_return, &bytes_after_return,
1939 if ((type_return == XA_ATOM) && (format_return == 32) &&
1940 (data) && (nitems_return == 1))
1942 Atom atom = *(Atom*)data;
1944 if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG"))
1945 type = GDK_WINDOW_TYPE_HINT_DIALOG;
1946 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU"))
1947 type = GDK_WINDOW_TYPE_HINT_MENU;
1948 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR"))
1949 type = GDK_WINDOW_TYPE_HINT_TOOLBAR;
1950 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY"))
1951 type = GDK_WINDOW_TYPE_HINT_UTILITY;
1952 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH"))
1953 type = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN;
1954 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK"))
1955 type = GDK_WINDOW_TYPE_HINT_DOCK;
1956 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
1957 type = GDK_WINDOW_TYPE_HINT_DESKTOP;
1958 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
1959 type = GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
1960 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
1961 type = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
1962 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
1963 type = GDK_WINDOW_TYPE_HINT_TOOLTIP;
1964 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
1965 type = GDK_WINDOW_TYPE_HINT_NOTIFICATION;
1966 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
1967 type = GDK_WINDOW_TYPE_HINT_COMBO;
1968 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
1969 type = GDK_WINDOW_TYPE_HINT_DND;
1972 if (type_return != None && data != NULL)
1980 gdk_wmspec_change_state (gboolean add,
1985 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1986 XClientMessageEvent xclient;
1988 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
1989 #define _NET_WM_STATE_ADD 1 /* add/set property */
1990 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
1992 memset (&xclient, 0, sizeof (xclient));
1993 xclient.type = ClientMessage;
1994 xclient.window = GDK_WINDOW_XID (window);
1995 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
1996 xclient.format = 32;
1997 xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1998 xclient.data.l[1] = gdk_x11_atom_to_xatom_for_display (display, state1);
1999 xclient.data.l[2] = gdk_x11_atom_to_xatom_for_display (display, state2);
2000 xclient.data.l[3] = 1; /* source indication */
2001 xclient.data.l[4] = 0;
2003 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
2004 SubstructureRedirectMask | SubstructureNotifyMask,
2005 (XEvent *)&xclient);
2009 gdk_x11_window_set_modal_hint (GdkWindow *window,
2012 if (GDK_WINDOW_DESTROYED (window) ||
2013 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2016 window->modal_hint = modal;
2018 if (GDK_WINDOW_IS_MAPPED (window))
2019 gdk_wmspec_change_state (modal, window,
2020 gdk_atom_intern_static_string ("_NET_WM_STATE_MODAL"),
2025 gdk_x11_window_set_skip_taskbar_hint (GdkWindow *window,
2026 gboolean skips_taskbar)
2028 GdkToplevelX11 *toplevel;
2030 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2032 if (GDK_WINDOW_DESTROYED (window) ||
2033 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2036 toplevel = _gdk_x11_window_get_toplevel (window);
2037 toplevel->skip_taskbar_hint = skips_taskbar;
2039 if (GDK_WINDOW_IS_MAPPED (window))
2040 gdk_wmspec_change_state (skips_taskbar, window,
2041 gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_TASKBAR"),
2046 gdk_x11_window_set_skip_pager_hint (GdkWindow *window,
2047 gboolean skips_pager)
2049 GdkToplevelX11 *toplevel;
2051 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2053 if (GDK_WINDOW_DESTROYED (window) ||
2054 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2057 toplevel = _gdk_x11_window_get_toplevel (window);
2058 toplevel->skip_pager_hint = skips_pager;
2060 if (GDK_WINDOW_IS_MAPPED (window))
2061 gdk_wmspec_change_state (skips_pager, window,
2062 gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_PAGER"),
2067 gdk_x11_window_set_urgency_hint (GdkWindow *window,
2070 GdkToplevelX11 *toplevel;
2072 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2074 if (GDK_WINDOW_DESTROYED (window) ||
2075 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2078 toplevel = _gdk_x11_window_get_toplevel (window);
2079 toplevel->urgency_hint = urgent;
2081 update_wm_hints (window, FALSE);
2085 gdk_x11_window_set_geometry_hints (GdkWindow *window,
2086 const GdkGeometry *geometry,
2087 GdkWindowHints geom_mask)
2089 XSizeHints size_hints;
2091 if (GDK_WINDOW_DESTROYED (window) ||
2092 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2095 size_hints.flags = 0;
2097 if (geom_mask & GDK_HINT_POS)
2099 size_hints.flags |= PPosition;
2100 /* We need to initialize the following obsolete fields because KWM
2101 * apparently uses these fields if they are non-zero.
2108 if (geom_mask & GDK_HINT_USER_POS)
2110 size_hints.flags |= USPosition;
2113 if (geom_mask & GDK_HINT_USER_SIZE)
2115 size_hints.flags |= USSize;
2118 if (geom_mask & GDK_HINT_MIN_SIZE)
2120 size_hints.flags |= PMinSize;
2121 size_hints.min_width = geometry->min_width;
2122 size_hints.min_height = geometry->min_height;
2125 if (geom_mask & GDK_HINT_MAX_SIZE)
2127 size_hints.flags |= PMaxSize;
2128 size_hints.max_width = MAX (geometry->max_width, 1);
2129 size_hints.max_height = MAX (geometry->max_height, 1);
2132 if (geom_mask & GDK_HINT_BASE_SIZE)
2134 size_hints.flags |= PBaseSize;
2135 size_hints.base_width = geometry->base_width;
2136 size_hints.base_height = geometry->base_height;
2139 if (geom_mask & GDK_HINT_RESIZE_INC)
2141 size_hints.flags |= PResizeInc;
2142 size_hints.width_inc = geometry->width_inc;
2143 size_hints.height_inc = geometry->height_inc;
2146 if (geom_mask & GDK_HINT_ASPECT)
2148 size_hints.flags |= PAspect;
2149 if (geometry->min_aspect <= 1)
2151 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
2152 size_hints.min_aspect.y = 65536;
2156 size_hints.min_aspect.x = 65536;
2157 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
2159 if (geometry->max_aspect <= 1)
2161 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
2162 size_hints.max_aspect.y = 65536;
2166 size_hints.max_aspect.x = 65536;
2167 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
2171 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2173 size_hints.flags |= PWinGravity;
2174 size_hints.win_gravity = geometry->win_gravity;
2177 /* FIXME: Would it be better to delete this property if
2178 * geom_mask == 0? It would save space on the server
2180 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2181 GDK_WINDOW_XID (window),
2186 gdk_window_get_geometry_hints (GdkWindow *window,
2187 GdkGeometry *geometry,
2188 GdkWindowHints *geom_mask)
2190 XSizeHints *size_hints;
2191 glong junk_supplied_mask = 0;
2193 g_return_if_fail (GDK_IS_WINDOW (window));
2194 g_return_if_fail (geometry != NULL);
2195 g_return_if_fail (geom_mask != NULL);
2199 if (GDK_WINDOW_DESTROYED (window) ||
2200 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2203 size_hints = XAllocSizeHints ();
2207 if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2208 GDK_WINDOW_XID (window),
2210 &junk_supplied_mask))
2211 size_hints->flags = 0;
2213 if (size_hints->flags & PMinSize)
2215 *geom_mask |= GDK_HINT_MIN_SIZE;
2216 geometry->min_width = size_hints->min_width;
2217 geometry->min_height = size_hints->min_height;
2220 if (size_hints->flags & PMaxSize)
2222 *geom_mask |= GDK_HINT_MAX_SIZE;
2223 geometry->max_width = MAX (size_hints->max_width, 1);
2224 geometry->max_height = MAX (size_hints->max_height, 1);
2227 if (size_hints->flags & PResizeInc)
2229 *geom_mask |= GDK_HINT_RESIZE_INC;
2230 geometry->width_inc = size_hints->width_inc;
2231 geometry->height_inc = size_hints->height_inc;
2234 if (size_hints->flags & PAspect)
2236 *geom_mask |= GDK_HINT_ASPECT;
2238 geometry->min_aspect = (gdouble) size_hints->min_aspect.x / (gdouble) size_hints->min_aspect.y;
2239 geometry->max_aspect = (gdouble) size_hints->max_aspect.x / (gdouble) size_hints->max_aspect.y;
2242 if (size_hints->flags & PWinGravity)
2244 *geom_mask |= GDK_HINT_WIN_GRAVITY;
2245 geometry->win_gravity = size_hints->win_gravity;
2252 utf8_is_latin1 (const gchar *str)
2254 const char *p = str;
2258 gunichar ch = g_utf8_get_char (p);
2263 p = g_utf8_next_char (p);
2269 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
2270 * convertable to STRING, otherwise, set it as compound text
2273 set_text_property (GdkDisplay *display,
2276 const gchar *utf8_str)
2278 gchar *prop_text = NULL;
2282 gboolean is_compound_text;
2284 if (utf8_is_latin1 (utf8_str))
2286 prop_type = XA_STRING;
2287 prop_text = _gdk_x11_display_utf8_to_string_target (display, utf8_str);
2288 prop_length = prop_text ? strlen (prop_text) : 0;
2290 is_compound_text = FALSE;
2296 gdk_x11_display_utf8_to_compound_text (display,
2297 utf8_str, &gdk_type, &prop_format,
2298 (guchar **)&prop_text, &prop_length);
2299 prop_type = gdk_x11_atom_to_xatom_for_display (display, gdk_type);
2300 is_compound_text = TRUE;
2305 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
2308 prop_type, prop_format,
2309 PropModeReplace, (guchar *)prop_text,
2312 if (is_compound_text)
2313 gdk_x11_free_compound_text ((guchar *)prop_text);
2319 /* Set WM_NAME and _NET_WM_NAME
2322 set_wm_name (GdkDisplay *display,
2326 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
2327 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
2328 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2329 PropModeReplace, (guchar *)name, strlen (name));
2331 set_text_property (display, xwindow,
2332 gdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"),
2337 gdk_x11_window_set_title (GdkWindow *window,
2340 GdkDisplay *display;
2344 g_return_if_fail (title != NULL);
2346 if (GDK_WINDOW_DESTROYED (window) ||
2347 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2350 display = gdk_window_get_display (window);
2351 xdisplay = GDK_DISPLAY_XDISPLAY (display);
2352 xwindow = GDK_WINDOW_XID (window);
2354 set_wm_name (display, xwindow, title);
2356 if (!gdk_window_icon_name_set (window))
2358 XChangeProperty (xdisplay, xwindow,
2359 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
2360 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2361 PropModeReplace, (guchar *)title, strlen (title));
2363 set_text_property (display, xwindow,
2364 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
2370 gdk_x11_window_set_role (GdkWindow *window,
2373 GdkDisplay *display;
2375 display = gdk_window_get_display (window);
2377 if (GDK_WINDOW_DESTROYED (window) ||
2378 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2382 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2383 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
2384 XA_STRING, 8, PropModeReplace, (guchar *)role, strlen (role));
2386 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2387 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
2391 gdk_x11_window_set_startup_id (GdkWindow *window,
2392 const gchar *startup_id)
2394 GdkDisplay *display;
2396 g_return_if_fail (GDK_IS_WINDOW (window));
2398 display = gdk_window_get_display (window);
2400 if (GDK_WINDOW_DESTROYED (window) ||
2401 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2405 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2406 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
2407 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2408 PropModeReplace, (unsigned char *)startup_id, strlen (startup_id));
2410 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2411 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
2415 gdk_x11_window_set_transient_for (GdkWindow *window,
2418 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent) &&
2419 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2420 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
2421 GDK_WINDOW_XID (window),
2422 GDK_WINDOW_XID (parent));
2426 gdk_window_x11_set_back_color (GdkWindow *window,
2432 GdkVisual *visual = gdk_window_get_visual (window);
2434 /* I suppose we could handle these, but that'd require fiddling with
2435 * xrender formats... */
2439 switch (visual->type)
2441 case GDK_VISUAL_DIRECT_COLOR:
2442 case GDK_VISUAL_TRUE_COLOR:
2444 /* If bits not used for color are used for something other than padding,
2445 * it's likely alpha, so we set them to 1s.
2447 guint padding, pixel;
2449 /* Shifting by >= width-of-type isn't defined in C */
2450 if (visual->depth >= 32)
2453 padding = ((~(guint32)0)) << visual->depth;
2455 pixel = ~ (visual->red_mask | visual->green_mask | visual->blue_mask | padding);
2457 pixel += (((int) (red * ((1 << visual->red_prec ) - 1))) << visual->red_shift ) +
2458 (((int) (green * ((1 << visual->green_prec) - 1))) << visual->green_shift) +
2459 (((int) (blue * ((1 << visual->blue_prec ) - 1))) << visual->blue_shift );
2461 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
2462 GDK_WINDOW_XID (window), pixel);
2466 /* These require fiddling with the colormap, and as they're essentially unused
2467 * we're just gonna skip them for now.
2469 case GDK_VISUAL_PSEUDO_COLOR:
2470 case GDK_VISUAL_GRAYSCALE:
2471 case GDK_VISUAL_STATIC_GRAY:
2472 case GDK_VISUAL_STATIC_COLOR:
2481 matrix_is_identity (cairo_matrix_t *matrix)
2483 return matrix->xx == 1.0 && matrix->yy == 1.0 &&
2484 matrix->yx == 0.0 && matrix->xy == 0.0 &&
2485 matrix->x0 == 0.0 && matrix->y0 == 0.0;
2489 gdk_window_x11_set_background (GdkWindow *window,
2490 cairo_pattern_t *pattern)
2493 cairo_surface_t *surface;
2494 cairo_matrix_t matrix;
2496 if (GDK_WINDOW_DESTROYED (window))
2499 if (pattern == NULL)
2503 /* X throws BadMatch if the parent has a different visual when
2504 * using ParentRelative */
2505 parent = gdk_window_get_parent (window);
2506 if (parent && gdk_window_get_visual (parent) == gdk_window_get_visual (window))
2507 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2508 GDK_WINDOW_XID (window), ParentRelative);
2510 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2511 GDK_WINDOW_XID (window), None);
2515 switch (cairo_pattern_get_type (pattern))
2517 case CAIRO_PATTERN_TYPE_SOLID:
2518 cairo_pattern_get_rgba (pattern, &r, &g, &b, &a);
2519 if (gdk_window_x11_set_back_color (window, r, g, b, a))
2522 case CAIRO_PATTERN_TYPE_SURFACE:
2523 cairo_pattern_get_matrix (pattern, &matrix);
2524 if (cairo_pattern_get_surface (pattern, &surface) == CAIRO_STATUS_SUCCESS &&
2525 matrix_is_identity (&matrix) &&
2526 cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XLIB &&
2527 cairo_xlib_surface_get_visual (surface) == GDK_VISUAL_XVISUAL (gdk_window_get_visual ((window))) &&
2528 cairo_xlib_surface_get_display (surface) == GDK_WINDOW_XDISPLAY (window))
2532 cairo_surface_get_device_offset (surface, &x, &y);
2533 /* XXX: This still bombs for non-pixmaps, but there's no way to
2534 * detect we're not a pixmap in Cairo... */
2535 if (x == 0.0 && y == 0.0)
2537 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2538 GDK_WINDOW_XID (window),
2539 cairo_xlib_surface_get_drawable (surface));
2544 case CAIRO_PATTERN_TYPE_LINEAR:
2545 case CAIRO_PATTERN_TYPE_RADIAL:
2547 /* fallback: just use black */
2551 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2552 GDK_WINDOW_XID (window), None);
2556 gdk_window_x11_set_device_cursor (GdkWindow *window,
2560 GdkWindowImplX11 *impl;
2562 g_return_if_fail (GDK_IS_WINDOW (window));
2563 g_return_if_fail (GDK_IS_DEVICE (device));
2565 impl = GDK_WINDOW_IMPL_X11 (window->impl);
2568 g_hash_table_remove (impl->device_cursor, device);
2571 _gdk_x11_cursor_update_theme (cursor);
2572 g_hash_table_replace (impl->device_cursor,
2573 device, g_object_ref (cursor));
2576 if (!GDK_WINDOW_DESTROYED (window))
2577 GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
2581 _gdk_x11_window_get_cursor (GdkWindow *window)
2583 GdkWindowImplX11 *impl;
2585 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2587 impl = GDK_WINDOW_IMPL_X11 (window->impl);
2589 return impl->cursor;
2593 gdk_window_x11_get_geometry (GdkWindow *window,
2604 guint tborder_width;
2607 if (!GDK_WINDOW_DESTROYED (window))
2609 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
2610 GDK_WINDOW_XID (window),
2611 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
2625 gdk_window_x11_get_root_coords (GdkWindow *window,
2636 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2637 GDK_WINDOW_XID (window),
2638 GDK_WINDOW_XROOTWIN (window),
2651 gdk_x11_window_get_root_origin (GdkWindow *window,
2657 gdk_window_get_frame_extents (window, &rect);
2667 gdk_x11_window_get_frame_extents (GdkWindow *window,
2670 GdkDisplay *display;
2671 GdkWindowImplX11 *impl;
2682 gulong nitems_return;
2683 gulong bytes_after_return;
2686 guint ww, wh, wb, wd;
2688 gboolean got_frame_extents = FALSE;
2690 g_return_if_fail (rect != NULL);
2697 while (window->parent && (window->parent)->parent)
2698 window = window->parent;
2700 /* Refine our fallback answer a bit using local information */
2701 rect->x = window->x;
2702 rect->y = window->y;
2703 rect->width = window->width;
2704 rect->height = window->height;
2706 impl = GDK_WINDOW_IMPL_X11 (window->impl);
2707 if (GDK_WINDOW_DESTROYED (window) || impl->override_redirect)
2713 display = gdk_window_get_display (window);
2715 gdk_x11_display_error_trap_push (display);
2717 xwindow = GDK_WINDOW_XID (window);
2719 /* first try: use _NET_FRAME_EXTENTS */
2720 if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
2721 gdk_x11_get_xatom_by_name_for_display (display,
2722 "_NET_FRAME_EXTENTS"),
2723 0, G_MAXLONG, False, XA_CARDINAL, &type_return,
2724 &format_return, &nitems_return, &bytes_after_return,
2728 if ((type_return == XA_CARDINAL) && (format_return == 32) &&
2729 (nitems_return == 4) && (data))
2731 gulong *ldata = (gulong *) data;
2732 got_frame_extents = TRUE;
2734 /* try to get the real client window geometry */
2735 if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow,
2736 &root, &wx, &wy, &ww, &wh, &wb, &wd) &&
2737 XTranslateCoordinates (GDK_DISPLAY_XDISPLAY (display),
2738 xwindow, root, 0, 0, &wx, &wy, &child))
2746 /* _NET_FRAME_EXTENTS format is left, right, top, bottom */
2747 rect->x -= ldata[0];
2748 rect->y -= ldata[2];
2749 rect->width += ldata[0] + ldata[1];
2750 rect->height += ldata[2] + ldata[3];
2757 if (got_frame_extents)
2760 /* no frame extents property available, which means we either have a WM that
2761 is not EWMH compliant or is broken - try fallback and walk up the window
2762 tree to get our window's parent which hopefully is the window frame */
2764 /* use NETWM_VIRTUAL_ROOTS if available */
2765 root = GDK_WINDOW_XROOTWIN (window);
2767 if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), root,
2768 gdk_x11_get_xatom_by_name_for_display (display,
2769 "_NET_VIRTUAL_ROOTS"),
2770 0, G_MAXLONG, False, XA_WINDOW, &type_return,
2771 &format_return, &nitems_return, &bytes_after_return,
2775 if ((type_return == XA_WINDOW) && (format_return == 32) && (data))
2777 nvroots = nitems_return;
2778 vroots = (Window *)data;
2782 xparent = GDK_WINDOW_XID (window);
2788 if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xwindow,
2790 &children, &nchildren))
2796 /* check virtual roots */
2797 for (i = 0; i < nvroots; i++)
2799 if (xparent == vroots[i])
2806 while (xparent != root);
2808 if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow,
2809 &root, &wx, &wy, &ww, &wh, &wb, &wd))
2821 gdk_x11_display_error_trap_pop_ignored (display);
2825 gdk_window_x11_get_device_state (GdkWindow *window,
2829 GdkModifierType *mask)
2833 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
2835 if (GDK_WINDOW_DESTROYED (window))
2838 GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
2842 return child != NULL;
2846 gdk_window_x11_get_events (GdkWindow *window)
2848 XWindowAttributes attrs;
2849 GdkEventMask event_mask;
2850 GdkEventMask filtered;
2852 if (GDK_WINDOW_DESTROYED (window))
2856 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2857 GDK_WINDOW_XID (window),
2859 event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
2860 /* if property change was filtered out before, keep it filtered out */
2861 filtered = GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK;
2862 window->event_mask = event_mask & ((window->event_mask & filtered) | ~filtered);
2868 gdk_window_x11_set_events (GdkWindow *window,
2869 GdkEventMask event_mask)
2871 long xevent_mask = 0;
2873 if (!GDK_WINDOW_DESTROYED (window))
2875 GdkX11Display *display_x11;
2877 if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
2878 xevent_mask = StructureNotifyMask | PropertyChangeMask;
2880 display_x11 = GDK_X11_DISPLAY (gdk_window_get_display (window));
2881 gdk_x11_event_source_select_events ((GdkEventSource *) display_x11->event_source,
2882 GDK_WINDOW_XID (window), event_mask,
2888 do_shape_combine_region (GdkWindow *window,
2889 const cairo_region_t *shape_region,
2894 if (GDK_WINDOW_DESTROYED (window))
2897 if (shape_region == NULL)
2899 /* Use NULL mask to unset the shape */
2900 if (shape == ShapeBounding
2901 ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
2902 : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
2904 if (shape == ShapeBounding)
2906 _gdk_x11_window_tmp_unset_parent_bg (window);
2907 _gdk_x11_window_tmp_unset_bg (window, TRUE);
2909 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
2910 GDK_WINDOW_XID (window),
2915 if (shape == ShapeBounding)
2917 _gdk_x11_window_tmp_reset_parent_bg (window);
2918 _gdk_x11_window_tmp_reset_bg (window, TRUE);
2924 if (shape == ShapeBounding
2925 ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
2926 : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
2929 XRectangle *xrects = NULL;
2931 _gdk_x11_region_get_xrectangles (shape_region,
2935 if (shape == ShapeBounding)
2937 _gdk_x11_window_tmp_unset_parent_bg (window);
2938 _gdk_x11_window_tmp_unset_bg (window, TRUE);
2940 XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
2941 GDK_WINDOW_XID (window),
2948 if (shape == ShapeBounding)
2950 _gdk_x11_window_tmp_reset_parent_bg (window);
2951 _gdk_x11_window_tmp_reset_bg (window, TRUE);
2959 gdk_window_x11_shape_combine_region (GdkWindow *window,
2960 const cairo_region_t *shape_region,
2964 do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeBounding);
2968 gdk_window_x11_input_shape_combine_region (GdkWindow *window,
2969 const cairo_region_t *shape_region,
2974 do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeInput);
2980 gdk_x11_window_set_override_redirect (GdkWindow *window,
2981 gboolean override_redirect)
2983 XSetWindowAttributes attr;
2985 if (!GDK_WINDOW_DESTROYED (window) &&
2986 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2988 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (window->impl);
2990 attr.override_redirect = (override_redirect? True : False);
2991 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2992 GDK_WINDOW_XID (window),
2996 impl->override_redirect = attr.override_redirect;
3001 gdk_x11_window_set_accept_focus (GdkWindow *window,
3002 gboolean accept_focus)
3004 accept_focus = accept_focus != FALSE;
3006 if (window->accept_focus != accept_focus)
3008 window->accept_focus = accept_focus;
3010 if (!GDK_WINDOW_DESTROYED (window) &&
3011 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3012 update_wm_hints (window, FALSE);
3017 gdk_x11_window_set_focus_on_map (GdkWindow *window,
3018 gboolean focus_on_map)
3020 focus_on_map = focus_on_map != FALSE;
3022 if (window->focus_on_map != focus_on_map)
3024 window->focus_on_map = focus_on_map;
3026 if ((!GDK_WINDOW_DESTROYED (window)) &&
3027 (!window->focus_on_map) &&
3028 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3029 gdk_x11_window_set_user_time (window, 0);
3034 * gdk_x11_window_set_user_time:
3035 * @window: (type GdkX11Window): A toplevel #GdkWindow
3036 * @timestamp: An XServer timestamp to which the property should be set
3038 * The application can use this call to update the _NET_WM_USER_TIME
3039 * property on a toplevel window. This property stores an Xserver
3040 * time which represents the time of the last user input event
3041 * received for this window. This property may be used by the window
3042 * manager to alter the focus, stacking, and/or placement behavior of
3043 * windows when they are mapped depending on whether the new window
3044 * was created by a user action or is a "pop-up" window activated by a
3045 * timer or some other event.
3047 * Note that this property is automatically updated by GDK, so this
3048 * function should only be used by applications which handle input
3049 * events bypassing GDK.
3054 gdk_x11_window_set_user_time (GdkWindow *window,
3057 GdkDisplay *display;
3058 GdkX11Display *display_x11;
3059 GdkToplevelX11 *toplevel;
3060 glong timestamp_long = (glong)timestamp;
3063 if (GDK_WINDOW_DESTROYED (window) ||
3064 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3067 display = gdk_window_get_display (window);
3068 display_x11 = GDK_X11_DISPLAY (display);
3069 toplevel = _gdk_x11_window_get_toplevel (window);
3073 g_warning ("gdk_window_set_user_time called on non-toplevel\n");
3077 if (toplevel->focus_window != None &&
3078 gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
3079 gdk_atom_intern_static_string ("_NET_WM_USER_TIME_WINDOW")))
3080 xid = toplevel->focus_window;
3082 xid = GDK_WINDOW_XID (window);
3084 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xid,
3085 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
3086 XA_CARDINAL, 32, PropModeReplace,
3087 (guchar *)×tamp_long, 1);
3089 if (timestamp_long != GDK_CURRENT_TIME &&
3090 (display_x11->user_time == GDK_CURRENT_TIME ||
3091 XSERVER_TIME_IS_LATER (timestamp_long, display_x11->user_time)))
3092 display_x11->user_time = timestamp_long;
3095 toplevel->user_time = timestamp_long;
3099 * gdk_x11_window_set_utf8_property:
3100 * @window: (type GdkX11Window): a #GdkWindow
3101 * @name: Property name, will be interned as an X atom
3102 * @value: (allow-none): Property value, or %NULL to delete
3104 * This function modifies or removes an arbitrary X11 window
3105 * property of type UTF8_STRING. If the given @window is
3106 * not a toplevel window, it is ignored.
3111 gdk_x11_window_set_utf8_property (GdkWindow *window,
3115 GdkDisplay *display;
3117 if (!WINDOW_IS_TOPLEVEL (window))
3120 display = gdk_window_get_display (window);
3124 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3125 GDK_WINDOW_XID (window),
3126 gdk_x11_get_xatom_by_name_for_display (display, name),
3127 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
3128 PropModeReplace, (guchar *)value, strlen (value));
3132 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3133 GDK_WINDOW_XID (window),
3134 gdk_x11_get_xatom_by_name_for_display (display, name));
3139 * gdk_x11_window_set_hide_titlebar_when_maximized:
3140 * @window: (type GdkX11Window): a #GdkWindow
3141 * @hide_titlebar_when_maximized: whether to hide the titlebar when
3144 * Set a hint for the window manager, requesting that the titlebar
3145 * should be hidden when the window is maximized.
3147 * Note that this property is automatically updated by GTK+, so this
3148 * function should only be used by applications which do not use GTK+
3149 * to create toplevel windows.
3154 gdk_x11_window_set_hide_titlebar_when_maximized (GdkWindow *window,
3155 gboolean hide_titlebar_when_maximized)
3157 GdkDisplay *display;
3159 if (!WINDOW_IS_TOPLEVEL (window))
3162 display = gdk_window_get_display (window);
3164 if (hide_titlebar_when_maximized)
3167 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3168 GDK_WINDOW_XID (window),
3169 gdk_x11_get_xatom_by_name_for_display (display, "_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"),
3171 PropModeReplace, (guchar *)&hide, 1);
3175 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3176 GDK_WINDOW_XID (window),
3177 gdk_x11_get_xatom_by_name_for_display (display, "_GTK_HIDE_TITLEBAR_WHEN_MAXIMIZED"));
3182 * gdk_x11_window_set_theme_variant:
3183 * @window: (type GdkX11Window): a #GdkWindow
3184 * @variant: the theme variant to export
3186 * GTK+ applications can request a dark theme variant. In order to
3187 * make other applications - namely window managers using GTK+ for
3188 * themeing - aware of this choice, GTK+ uses this function to
3189 * export the requested theme variant as _GTK_THEME_VARIANT property
3190 * on toplevel windows.
3192 * Note that this property is automatically updated by GTK+, so this
3193 * function should only be used by applications which do not use GTK+
3194 * to create toplevel windows.
3199 gdk_x11_window_set_theme_variant (GdkWindow *window,
3202 return gdk_x11_window_set_utf8_property (window, "_GTK_THEME_VARIANT", variant);
3205 #define GDK_SELECTION_MAX_SIZE(display) \
3207 XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0 \
3208 ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100 \
3209 : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
3212 gdk_window_update_icon (GdkWindow *window,
3215 GdkToplevelX11 *toplevel;
3216 GdkPixbuf *best_icon;
3220 toplevel = _gdk_x11_window_get_toplevel (window);
3222 if (toplevel->icon_pixmap != NULL)
3224 cairo_surface_destroy (toplevel->icon_pixmap);
3225 toplevel->icon_pixmap = NULL;
3228 if (toplevel->icon_mask != NULL)
3230 cairo_surface_destroy (toplevel->icon_mask);
3231 toplevel->icon_mask = NULL;
3234 #define IDEAL_SIZE 48
3236 best_size = G_MAXINT;
3238 for (tmp_list = icon_list; tmp_list; tmp_list = tmp_list->next)
3240 GdkPixbuf *pixbuf = tmp_list->data;
3243 /* average width and height - if someone passes in a rectangular
3244 * icon they deserve what they get.
3246 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3249 if (best_icon == NULL)
3256 /* icon is better if it's 32 pixels or larger, and closer to
3257 * the ideal size than the current best.
3260 (ABS (best_size - IDEAL_SIZE) <
3261 ABS (this - IDEAL_SIZE)))
3271 int width = gdk_pixbuf_get_width (best_icon);
3272 int height = gdk_pixbuf_get_height (best_icon);
3275 toplevel->icon_pixmap = gdk_x11_window_create_pixmap_surface (window,
3279 cr = cairo_create (toplevel->icon_pixmap);
3280 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
3281 gdk_cairo_set_source_pixbuf (cr, best_icon, 0, 0);
3282 if (gdk_pixbuf_get_has_alpha (best_icon))
3284 /* Saturate the image, so it has bilevel alpha */
3285 cairo_push_group_with_content (cr, CAIRO_CONTENT_COLOR_ALPHA);
3287 cairo_set_operator (cr, CAIRO_OPERATOR_SATURATE);
3289 cairo_pop_group_to_source (cr);
3294 if (gdk_pixbuf_get_has_alpha (best_icon))
3296 toplevel->icon_mask = _gdk_x11_window_create_bitmap_surface (window,
3300 cr = cairo_create (toplevel->icon_mask);
3301 gdk_cairo_set_source_pixbuf (cr, best_icon, 0, 0);
3302 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
3308 update_wm_hints (window, FALSE);
3312 gdk_x11_window_set_icon_list (GdkWindow *window,
3321 gint width, height, stride;
3324 GdkDisplay *display;
3327 if (GDK_WINDOW_DESTROYED (window) ||
3328 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3331 display = gdk_window_get_display (window);
3339 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
3341 width = gdk_pixbuf_get_width (pixbuf);
3342 height = gdk_pixbuf_get_height (pixbuf);
3344 /* silently ignore overlarge icons */
3345 if (size + 2 + width * height > GDK_SELECTION_MAX_SIZE(display))
3347 g_warning ("gdk_window_set_icon_list: icons too large");
3352 size += 2 + width * height;
3354 l = g_list_next (l);
3357 data = g_malloc (size * sizeof (gulong));
3365 width = gdk_pixbuf_get_width (pixbuf);
3366 height = gdk_pixbuf_get_height (pixbuf);
3367 stride = gdk_pixbuf_get_rowstride (pixbuf);
3368 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
3373 pixels = gdk_pixbuf_get_pixels (pixbuf);
3375 for (y = 0; y < height; y++)
3377 for (x = 0; x < width; x++)
3381 r = pixels[y*stride + x*n_channels + 0];
3382 g = pixels[y*stride + x*n_channels + 1];
3383 b = pixels[y*stride + x*n_channels + 2];
3384 if (n_channels >= 4)
3385 a = pixels[y*stride + x*n_channels + 3];
3389 *p++ = a << 24 | r << 16 | g << 8 | b ;
3393 l = g_list_next (l);
3399 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3400 GDK_WINDOW_XID (window),
3401 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"),
3404 (guchar*) data, size);
3408 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3409 GDK_WINDOW_XID (window),
3410 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"));
3415 gdk_window_update_icon (window, pixbufs);
3419 gdk_window_icon_name_set (GdkWindow *window)
3421 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
3422 g_quark_from_static_string ("gdk-icon-name-set")));
3426 gdk_x11_window_set_icon_name (GdkWindow *window,
3429 GdkDisplay *display;
3431 if (GDK_WINDOW_DESTROYED (window) ||
3432 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3435 display = gdk_window_get_display (window);
3437 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
3438 GUINT_TO_POINTER (name != NULL));
3442 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3443 GDK_WINDOW_XID (window),
3444 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
3445 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
3446 PropModeReplace, (guchar *)name, strlen (name));
3448 set_text_property (display, GDK_WINDOW_XID (window),
3449 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
3454 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3455 GDK_WINDOW_XID (window),
3456 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"));
3457 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3458 GDK_WINDOW_XID (window),
3459 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"));
3464 gdk_x11_window_iconify (GdkWindow *window)
3466 if (GDK_WINDOW_DESTROYED (window) ||
3467 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3470 if (GDK_WINDOW_IS_MAPPED (window))
3472 XIconifyWindow (GDK_WINDOW_XDISPLAY (window),
3473 GDK_WINDOW_XID (window),
3474 gdk_screen_get_number (GDK_WINDOW_SCREEN (window)));
3478 /* Flip our client side flag, the real work happens on map. */
3479 gdk_synthesize_window_state (window,
3481 GDK_WINDOW_STATE_ICONIFIED);
3482 gdk_wmspec_change_state (TRUE, window,
3483 gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
3489 gdk_x11_window_deiconify (GdkWindow *window)
3491 if (GDK_WINDOW_DESTROYED (window) ||
3492 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3495 if (GDK_WINDOW_IS_MAPPED (window))
3497 gdk_window_show (window);
3498 gdk_wmspec_change_state (FALSE, window,
3499 gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
3504 /* Flip our client side flag, the real work happens on map. */
3505 gdk_synthesize_window_state (window,
3506 GDK_WINDOW_STATE_ICONIFIED,
3508 gdk_wmspec_change_state (FALSE, window,
3509 gdk_atom_intern_static_string ("_NET_WM_STATE_HIDDEN"),
3515 gdk_x11_window_stick (GdkWindow *window)
3517 if (GDK_WINDOW_DESTROYED (window) ||
3518 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3521 if (GDK_WINDOW_IS_MAPPED (window))
3523 /* "stick" means stick to all desktops _and_ do not scroll with the
3524 * viewport. i.e. glue to the monitor glass in all cases.
3527 XClientMessageEvent xclient;
3529 /* Request stick during viewport scroll */
3530 gdk_wmspec_change_state (TRUE, window,
3531 gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
3534 /* Request desktop 0xFFFFFFFF */
3535 memset (&xclient, 0, sizeof (xclient));
3536 xclient.type = ClientMessage;
3537 xclient.window = GDK_WINDOW_XID (window);
3538 xclient.display = GDK_WINDOW_XDISPLAY (window);
3539 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
3541 xclient.format = 32;
3543 xclient.data.l[0] = 0xFFFFFFFF;
3544 xclient.data.l[1] = 0;
3545 xclient.data.l[2] = 0;
3546 xclient.data.l[3] = 0;
3547 xclient.data.l[4] = 0;
3549 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
3550 SubstructureRedirectMask | SubstructureNotifyMask,
3551 (XEvent *)&xclient);
3555 /* Flip our client side flag, the real work happens on map. */
3556 gdk_synthesize_window_state (window,
3558 GDK_WINDOW_STATE_STICKY);
3563 gdk_x11_window_unstick (GdkWindow *window)
3565 if (GDK_WINDOW_DESTROYED (window) ||
3566 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3569 if (GDK_WINDOW_IS_MAPPED (window))
3571 /* Request unstick from viewport */
3572 gdk_wmspec_change_state (FALSE, window,
3573 gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
3576 move_to_current_desktop (window);
3580 /* Flip our client side flag, the real work happens on map. */
3581 gdk_synthesize_window_state (window,
3582 GDK_WINDOW_STATE_STICKY,
3589 gdk_x11_window_maximize (GdkWindow *window)
3591 if (GDK_WINDOW_DESTROYED (window) ||
3592 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3595 if (GDK_WINDOW_IS_MAPPED (window))
3596 gdk_wmspec_change_state (TRUE, window,
3597 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
3598 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
3600 gdk_synthesize_window_state (window,
3602 GDK_WINDOW_STATE_MAXIMIZED);
3606 gdk_x11_window_unmaximize (GdkWindow *window)
3608 if (GDK_WINDOW_DESTROYED (window) ||
3609 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3612 if (GDK_WINDOW_IS_MAPPED (window))
3613 gdk_wmspec_change_state (FALSE, window,
3614 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
3615 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
3617 gdk_synthesize_window_state (window,
3618 GDK_WINDOW_STATE_MAXIMIZED,
3623 gdk_x11_window_fullscreen (GdkWindow *window)
3625 if (GDK_WINDOW_DESTROYED (window) ||
3626 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3629 if (GDK_WINDOW_IS_MAPPED (window))
3630 gdk_wmspec_change_state (TRUE, window,
3631 gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
3635 gdk_synthesize_window_state (window,
3637 GDK_WINDOW_STATE_FULLSCREEN);
3641 gdk_x11_window_unfullscreen (GdkWindow *window)
3643 if (GDK_WINDOW_DESTROYED (window) ||
3644 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3647 if (GDK_WINDOW_IS_MAPPED (window))
3648 gdk_wmspec_change_state (FALSE, window,
3649 gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
3653 gdk_synthesize_window_state (window,
3654 GDK_WINDOW_STATE_FULLSCREEN,
3659 gdk_x11_window_set_keep_above (GdkWindow *window,
3662 g_return_if_fail (GDK_IS_WINDOW (window));
3664 if (GDK_WINDOW_DESTROYED (window) ||
3665 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3668 if (GDK_WINDOW_IS_MAPPED (window))
3671 gdk_wmspec_change_state (FALSE, window,
3672 gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
3674 gdk_wmspec_change_state (setting, window,
3675 gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
3679 gdk_synthesize_window_state (window,
3680 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3681 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3685 gdk_x11_window_set_keep_below (GdkWindow *window, gboolean setting)
3687 g_return_if_fail (GDK_IS_WINDOW (window));
3689 if (GDK_WINDOW_DESTROYED (window) ||
3690 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3693 if (GDK_WINDOW_IS_MAPPED (window))
3696 gdk_wmspec_change_state (FALSE, window,
3697 gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
3699 gdk_wmspec_change_state (setting, window,
3700 gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
3704 gdk_synthesize_window_state (window,
3705 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3706 setting ? GDK_WINDOW_STATE_BELOW : 0);
3710 gdk_x11_window_get_group (GdkWindow *window)
3712 GdkToplevelX11 *toplevel;
3714 if (GDK_WINDOW_DESTROYED (window) ||
3715 !WINDOW_IS_TOPLEVEL (window))
3718 toplevel = _gdk_x11_window_get_toplevel (window);
3720 return toplevel->group_leader;
3724 gdk_x11_window_set_group (GdkWindow *window,
3727 GdkToplevelX11 *toplevel;
3729 g_return_if_fail (GDK_IS_WINDOW (window));
3730 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
3731 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
3733 if (GDK_WINDOW_DESTROYED (window) ||
3734 (leader != NULL && GDK_WINDOW_DESTROYED (leader)) ||
3735 !WINDOW_IS_TOPLEVEL (window))
3738 toplevel = _gdk_x11_window_get_toplevel (window);
3741 leader = gdk_display_get_default_group (gdk_window_get_display (window));
3743 if (toplevel->group_leader != leader)
3745 if (toplevel->group_leader)
3746 g_object_unref (toplevel->group_leader);
3747 toplevel->group_leader = g_object_ref (leader);
3748 (_gdk_x11_window_get_toplevel (leader))->is_leader = TRUE;
3751 update_wm_hints (window, FALSE);
3754 static MotifWmHints *
3755 gdk_window_get_mwm_hints (GdkWindow *window)
3757 GdkDisplay *display;
3758 Atom hints_atom = None;
3765 if (GDK_WINDOW_DESTROYED (window))
3768 display = gdk_window_get_display (window);
3770 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
3772 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
3773 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
3774 False, AnyPropertyType, &type, &format, &nitems,
3775 &bytes_after, &data);
3780 return (MotifWmHints *)data;
3784 gdk_window_set_mwm_hints (GdkWindow *window,
3785 MotifWmHints *new_hints)
3787 GdkDisplay *display;
3788 Atom hints_atom = None;
3790 MotifWmHints *hints;
3796 if (GDK_WINDOW_DESTROYED (window))
3799 display = gdk_window_get_display (window);
3801 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
3803 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
3804 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
3805 False, AnyPropertyType, &type, &format, &nitems,
3806 &bytes_after, &data);
3812 hints = (MotifWmHints *)data;
3814 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
3816 hints->flags |= MWM_HINTS_FUNCTIONS;
3817 hints->functions = new_hints->functions;
3819 if (new_hints->flags & MWM_HINTS_DECORATIONS)
3821 hints->flags |= MWM_HINTS_DECORATIONS;
3822 hints->decorations = new_hints->decorations;
3826 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
3827 hints_atom, hints_atom, 32, PropModeReplace,
3828 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
3830 if (hints != new_hints)
3835 gdk_x11_window_set_decorations (GdkWindow *window,
3836 GdkWMDecoration decorations)
3840 if (GDK_WINDOW_DESTROYED (window) ||
3841 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3844 /* initialize to zero to avoid writing uninitialized data to socket */
3845 memset(&hints, 0, sizeof(hints));
3846 hints.flags = MWM_HINTS_DECORATIONS;
3847 hints.decorations = decorations;
3849 gdk_window_set_mwm_hints (window, &hints);
3853 gdk_x11_window_get_decorations(GdkWindow *window,
3854 GdkWMDecoration *decorations)
3856 MotifWmHints *hints;
3857 gboolean result = FALSE;
3859 if (GDK_WINDOW_DESTROYED (window) ||
3860 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3863 hints = gdk_window_get_mwm_hints (window);
3867 if (hints->flags & MWM_HINTS_DECORATIONS)
3870 *decorations = hints->decorations;
3881 gdk_x11_window_set_functions (GdkWindow *window,
3882 GdkWMFunction functions)
3886 g_return_if_fail (GDK_IS_WINDOW (window));
3888 if (GDK_WINDOW_DESTROYED (window) ||
3889 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3892 /* initialize to zero to avoid writing uninitialized data to socket */
3893 memset(&hints, 0, sizeof(hints));
3894 hints.flags = MWM_HINTS_FUNCTIONS;
3895 hints.functions = functions;
3897 gdk_window_set_mwm_hints (window, &hints);
3901 _gdk_x11_xwindow_get_shape (Display *xdisplay,
3905 cairo_region_t *shape;
3913 /* Note that XShapeGetRectangles returns NULL in two situations:
3914 * - the server doesn't support the SHAPE extension
3915 * - the shape is empty
3917 * Since we can't discriminate these here, we always return
3918 * an empty shape. It is the callers responsibility to check
3919 * whether the server supports the SHAPE extensions beforehand.
3921 xrl = XShapeGetRectangles (xdisplay, window, shape_type, &rn, &ord);
3924 return cairo_region_create (); /* Empty */
3926 if (ord != YXBanded)
3928 /* This really shouldn't happen with any xserver, as they
3929 * generally convert regions to YXBanded internally
3931 g_warning ("non YXBanded shape masks not supported");
3936 rl = g_new (GdkRectangle, rn);
3937 for (i = 0; i < rn; i++)
3941 rl[i].width = xrl[i].width;
3942 rl[i].height = xrl[i].height;
3946 shape = cairo_region_create_rectangles (rl, rn);
3953 static cairo_region_t *
3954 gdk_x11_window_get_shape (GdkWindow *window)
3956 if (!GDK_WINDOW_DESTROYED (window) &&
3957 gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
3958 return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window),
3959 GDK_WINDOW_XID (window),
3965 static cairo_region_t *
3966 gdk_x11_window_get_input_shape (GdkWindow *window)
3968 #if defined(ShapeInput)
3969 if (!GDK_WINDOW_DESTROYED (window) &&
3970 gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
3971 return _gdk_x11_xwindow_get_shape (GDK_WINDOW_XDISPLAY (window),
3972 GDK_WINDOW_XID (window),
3980 gdk_window_set_static_bit_gravity (GdkWindow *window,
3983 XSetWindowAttributes xattributes;
3984 guint xattributes_mask = 0;
3986 g_return_if_fail (GDK_IS_WINDOW (window));
3988 if (window->input_only)
3991 xattributes.bit_gravity = StaticGravity;
3992 xattributes_mask |= CWBitGravity;
3993 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
3994 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3995 GDK_WINDOW_XID (window),
3996 CWBitGravity, &xattributes);
4000 gdk_window_set_static_win_gravity (GdkWindow *window,
4003 XSetWindowAttributes xattributes;
4005 g_return_if_fail (GDK_IS_WINDOW (window));
4007 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
4009 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
4010 GDK_WINDOW_XID (window),
4011 CWWinGravity, &xattributes);
4015 gdk_window_x11_set_static_gravities (GdkWindow *window,
4016 gboolean use_static)
4020 if (!use_static == !window->guffaw_gravity)
4023 window->guffaw_gravity = use_static;
4025 if (!GDK_WINDOW_DESTROYED (window))
4027 gdk_window_set_static_bit_gravity (window, use_static);
4029 tmp_list = window->children;
4032 gdk_window_set_static_win_gravity (tmp_list->data, use_static);
4034 tmp_list = tmp_list->next;
4041 /* From the WM spec */
4042 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
4043 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
4044 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
4045 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
4046 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
4047 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
4048 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
4049 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
4050 #define _NET_WM_MOVERESIZE_MOVE 8 /* movement only */
4051 #define _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9 /* size via keyboard */
4052 #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10 /* move via keyboard */
4053 #define _NET_WM_MOVERESIZE_CANCEL 11 /* cancel operation */
4056 wmspec_send_message (GdkDisplay *display,
4063 XClientMessageEvent xclient;
4065 memset (&xclient, 0, sizeof (xclient));
4066 xclient.type = ClientMessage;
4067 xclient.window = GDK_WINDOW_XID (window);
4068 xclient.message_type =
4069 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
4070 xclient.format = 32;
4071 xclient.data.l[0] = root_x;
4072 xclient.data.l[1] = root_y;
4073 xclient.data.l[2] = action;
4074 xclient.data.l[3] = button;
4075 xclient.data.l[4] = 1; /* source indication */
4077 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
4078 SubstructureRedirectMask | SubstructureNotifyMask,
4079 (XEvent *)&xclient);
4083 handle_wmspec_button_release (GdkDisplay *display,
4086 GdkX11Display *display_x11 = GDK_X11_DISPLAY (display);
4089 #if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
4090 XIEvent *xiev = (XIEvent *) xevent->xcookie.data;
4091 XIDeviceEvent *xidev = (XIDeviceEvent *) xiev;
4093 if (xevent->xany.type == GenericEvent)
4094 window = gdk_x11_window_lookup_for_display (display, xidev->event);
4097 window = gdk_x11_window_lookup_for_display (display, xevent->xany.window);
4099 if (display_x11->wm_moveresize_button != 0 && window != NULL)
4101 if ((xevent->xany.type == ButtonRelease &&
4102 xevent->xbutton.button == display_x11->wm_moveresize_button)
4103 #if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
4105 (xevent->xany.type == GenericEvent &&
4106 xiev->evtype == XI_ButtonRelease &&
4107 xidev->detail == display_x11->wm_moveresize_button)
4111 display_x11->wm_moveresize_button = 0;
4112 wmspec_send_message (display, window, 0, 0, _NET_WM_MOVERESIZE_CANCEL, 0);
4118 wmspec_moveresize (GdkWindow *window,
4126 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
4128 /* Release passive grab */
4129 gdk_device_ungrab (device, timestamp);
4130 GDK_X11_DISPLAY (display)->wm_moveresize_button = button;
4132 wmspec_send_message (display, window, root_x, root_y, direction, button);
4136 wmspec_resize_drag (GdkWindow *window,
4146 /* Let the compiler turn a switch into a table, instead
4147 * of doing the table manually, this way is easier to verify.
4151 case GDK_WINDOW_EDGE_NORTH_WEST:
4152 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
4155 case GDK_WINDOW_EDGE_NORTH:
4156 direction = _NET_WM_MOVERESIZE_SIZE_TOP;
4159 case GDK_WINDOW_EDGE_NORTH_EAST:
4160 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
4163 case GDK_WINDOW_EDGE_WEST:
4164 direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
4167 case GDK_WINDOW_EDGE_EAST:
4168 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
4171 case GDK_WINDOW_EDGE_SOUTH_WEST:
4172 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
4175 case GDK_WINDOW_EDGE_SOUTH:
4176 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
4179 case GDK_WINDOW_EDGE_SOUTH_EAST:
4180 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
4184 g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
4189 wmspec_moveresize (window, direction, device, button, root_x, root_y, timestamp);
4192 typedef struct _MoveResizeData MoveResizeData;
4194 struct _MoveResizeData
4196 GdkDisplay *display;
4198 GdkWindow *moveresize_window;
4199 GdkWindow *moveresize_emulation_window;
4201 GdkWindowEdge resize_edge;
4203 gint moveresize_button;
4206 gint moveresize_orig_x;
4207 gint moveresize_orig_y;
4208 gint moveresize_orig_width;
4209 gint moveresize_orig_height;
4210 GdkWindowHints moveresize_geom_mask;
4211 GdkGeometry moveresize_geometry;
4212 Time moveresize_process_time;
4213 XEvent *moveresize_pending_event;
4216 static MoveResizeData *
4217 get_move_resize_data (GdkDisplay *display,
4220 MoveResizeData *mv_resize;
4221 static GQuark move_resize_quark = 0;
4223 if (!move_resize_quark)
4224 move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize");
4226 mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark);
4228 if (!mv_resize && create)
4230 mv_resize = g_new0 (MoveResizeData, 1);
4231 mv_resize->display = display;
4233 g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize);
4240 update_pos (MoveResizeData *mv_resize,
4246 dx = new_root_x - mv_resize->moveresize_x;
4247 dy = new_root_y - mv_resize->moveresize_y;
4249 if (mv_resize->is_resize)
4253 x = mv_resize->moveresize_orig_x;
4254 y = mv_resize->moveresize_orig_y;
4256 w = mv_resize->moveresize_orig_width;
4257 h = mv_resize->moveresize_orig_height;
4259 switch (mv_resize->resize_edge)
4261 case GDK_WINDOW_EDGE_NORTH_WEST:
4267 case GDK_WINDOW_EDGE_NORTH:
4271 case GDK_WINDOW_EDGE_NORTH_EAST:
4276 case GDK_WINDOW_EDGE_SOUTH_WEST:
4281 case GDK_WINDOW_EDGE_SOUTH_EAST:
4285 case GDK_WINDOW_EDGE_SOUTH:
4288 case GDK_WINDOW_EDGE_EAST:
4291 case GDK_WINDOW_EDGE_WEST:
4302 if (mv_resize->moveresize_geom_mask)
4304 gdk_window_constrain_size (&mv_resize->moveresize_geometry,
4305 mv_resize->moveresize_geom_mask,
4309 gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
4315 x = mv_resize->moveresize_orig_x + dx;
4316 y = mv_resize->moveresize_orig_y + dy;
4318 gdk_window_move (mv_resize->moveresize_window, x, y);
4323 finish_drag (MoveResizeData *mv_resize)
4325 gdk_window_destroy (mv_resize->moveresize_emulation_window);
4326 mv_resize->moveresize_emulation_window = NULL;
4327 g_object_unref (mv_resize->moveresize_window);
4328 mv_resize->moveresize_window = NULL;
4330 if (mv_resize->moveresize_pending_event)
4332 g_free (mv_resize->moveresize_pending_event);
4333 mv_resize->moveresize_pending_event = NULL;
4338 lookahead_motion_predicate (Display *xdisplay,
4342 gboolean *seen_release = (gboolean *)arg;
4343 GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
4344 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
4349 switch (event->xany.type)
4352 *seen_release = TRUE;
4355 mv_resize->moveresize_process_time = event->xmotion.time;
4365 moveresize_lookahead (MoveResizeData *mv_resize,
4369 gboolean seen_release = FALSE;
4371 if (mv_resize->moveresize_process_time)
4373 if (event->xmotion.time == mv_resize->moveresize_process_time)
4375 mv_resize->moveresize_process_time = 0;
4382 XCheckIfEvent (event->xany.display, &tmp_event,
4383 lookahead_motion_predicate, (XPointer) & seen_release);
4385 return mv_resize->moveresize_process_time == 0;
4389 _gdk_x11_moveresize_handle_event (XEvent *event)
4391 guint button_mask = 0;
4392 GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
4393 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
4395 if (!mv_resize || !mv_resize->moveresize_window)
4397 handle_wmspec_button_release (display, event);
4401 button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
4403 switch (event->xany.type)
4406 if (mv_resize->moveresize_window->resize_count > 0)
4408 if (mv_resize->moveresize_pending_event)
4409 *mv_resize->moveresize_pending_event = *event;
4411 mv_resize->moveresize_pending_event =
4412 g_memdup (event, sizeof (XEvent));
4416 if (!moveresize_lookahead (mv_resize, event))
4419 update_pos (mv_resize,
4420 event->xmotion.x_root,
4421 event->xmotion.y_root);
4423 /* This should never be triggered in normal cases, but in the
4424 * case where the drag started without an implicit grab being
4425 * in effect, we could miss the release if it occurs before
4426 * we grab the pointer; this ensures that we will never
4427 * get a permanently stuck grab.
4429 if ((event->xmotion.state & button_mask) == 0)
4430 finish_drag (mv_resize);
4434 update_pos (mv_resize,
4435 event->xbutton.x_root,
4436 event->xbutton.y_root);
4438 if (event->xbutton.button == mv_resize->moveresize_button)
4439 finish_drag (mv_resize);
4442 #if defined (HAVE_XGENERICEVENTS) && defined (XINPUT_2)
4445 /* we just assume this is an XI2 event */
4446 XIEvent *ev = (XIEvent *) event->xcookie.data;
4447 XIDeviceEvent *xev = (XIDeviceEvent *)ev;
4452 update_pos (mv_resize, xev->root_x, xev->root_y);
4453 state = _gdk_x11_device_xi2_translate_state (&xev->mods, &xev->buttons, &xev->group);
4454 if ((state & button_mask) == 0)
4455 finish_drag (mv_resize);
4458 case XI_ButtonRelease:
4459 update_pos (mv_resize, xev->root_x, xev->root_y);
4460 if (xev->detail == mv_resize->moveresize_button)
4461 finish_drag (mv_resize);
4473 _gdk_x11_moveresize_configure_done (GdkDisplay *display,
4477 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
4479 if (!mv_resize || window != mv_resize->moveresize_window)
4482 if (mv_resize->moveresize_pending_event)
4484 tmp_event = mv_resize->moveresize_pending_event;
4485 mv_resize->moveresize_pending_event = NULL;
4486 _gdk_x11_moveresize_handle_event (tmp_event);
4494 create_moveresize_window (MoveResizeData *mv_resize,
4497 GdkWindowAttr attributes;
4498 gint attributes_mask;
4499 GdkGrabStatus status;
4501 g_assert (mv_resize->moveresize_emulation_window == NULL);
4503 attributes.x = -100;
4504 attributes.y = -100;
4505 attributes.width = 10;
4506 attributes.height = 10;
4507 attributes.window_type = GDK_WINDOW_TEMP;
4508 attributes.wclass = GDK_INPUT_ONLY;
4509 attributes.override_redirect = TRUE;
4510 attributes.event_mask = 0;
4512 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
4514 mv_resize->moveresize_emulation_window =
4515 gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)),
4519 gdk_window_show (mv_resize->moveresize_emulation_window);
4521 status = gdk_device_grab (mv_resize->device,
4522 mv_resize->moveresize_emulation_window,
4525 GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
4529 if (status != GDK_GRAB_SUCCESS)
4531 /* If this fails, some other client has grabbed the window
4534 finish_drag (mv_resize);
4537 mv_resize->moveresize_process_time = 0;
4541 Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
4542 so that calling XMoveWindow with these coordinates will not move the
4544 Note that this depends on the WM to implement ICCCM-compliant reference
4548 calculate_unmoving_origin (MoveResizeData *mv_resize)
4553 if (mv_resize->moveresize_geom_mask & GDK_HINT_WIN_GRAVITY &&
4554 mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC)
4556 gdk_window_get_origin (mv_resize->moveresize_window,
4557 &mv_resize->moveresize_orig_x,
4558 &mv_resize->moveresize_orig_y);
4562 gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
4563 gdk_window_get_geometry (mv_resize->moveresize_window,
4564 NULL, NULL, &width, &height);
4566 switch (mv_resize->moveresize_geometry.win_gravity)
4568 case GDK_GRAVITY_NORTH_WEST:
4569 mv_resize->moveresize_orig_x = rect.x;
4570 mv_resize->moveresize_orig_y = rect.y;
4572 case GDK_GRAVITY_NORTH:
4573 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
4574 mv_resize->moveresize_orig_y = rect.y;
4576 case GDK_GRAVITY_NORTH_EAST:
4577 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
4578 mv_resize->moveresize_orig_y = rect.y;
4580 case GDK_GRAVITY_WEST:
4581 mv_resize->moveresize_orig_x = rect.x;
4582 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
4584 case GDK_GRAVITY_CENTER:
4585 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
4586 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
4588 case GDK_GRAVITY_EAST:
4589 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
4590 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
4592 case GDK_GRAVITY_SOUTH_WEST:
4593 mv_resize->moveresize_orig_x = rect.x;
4594 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
4596 case GDK_GRAVITY_SOUTH:
4597 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
4598 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
4600 case GDK_GRAVITY_SOUTH_EAST:
4601 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
4602 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
4605 mv_resize->moveresize_orig_x = rect.x;
4606 mv_resize->moveresize_orig_y = rect.y;
4613 emulate_resize_drag (GdkWindow *window,
4621 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
4623 mv_resize->is_resize = TRUE;
4624 mv_resize->moveresize_button = button;
4625 mv_resize->resize_edge = edge;
4626 mv_resize->device = device;
4627 mv_resize->moveresize_x = root_x;
4628 mv_resize->moveresize_y = root_y;
4629 mv_resize->moveresize_window = g_object_ref (window);
4631 mv_resize->moveresize_orig_width = gdk_window_get_width (window);
4632 mv_resize->moveresize_orig_height = gdk_window_get_height (window);
4634 mv_resize->moveresize_geom_mask = 0;
4635 gdk_window_get_geometry_hints (window,
4636 &mv_resize->moveresize_geometry,
4637 &mv_resize->moveresize_geom_mask);
4639 calculate_unmoving_origin (mv_resize);
4641 create_moveresize_window (mv_resize, timestamp);
4645 emulate_move_drag (GdkWindow *window,
4652 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
4654 mv_resize->is_resize = FALSE;
4655 mv_resize->device = device;
4656 mv_resize->moveresize_button = button;
4657 mv_resize->moveresize_x = root_x;
4658 mv_resize->moveresize_y = root_y;
4660 mv_resize->moveresize_window = g_object_ref (window);
4662 calculate_unmoving_origin (mv_resize);
4664 create_moveresize_window (mv_resize, timestamp);
4668 gdk_x11_window_begin_resize_drag (GdkWindow *window,
4676 if (GDK_WINDOW_DESTROYED (window) ||
4677 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4680 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
4681 gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
4682 wmspec_resize_drag (window, edge, device, button, root_x, root_y, timestamp);
4684 emulate_resize_drag (window, edge, device, button, root_x, root_y, timestamp);
4688 gdk_x11_window_begin_move_drag (GdkWindow *window,
4695 if (GDK_WINDOW_DESTROYED (window) ||
4696 !WINDOW_IS_TOPLEVEL (window))
4699 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
4700 gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
4701 wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE,
4702 device, button, root_x, root_y, timestamp);
4704 emulate_move_drag (window, device, button, root_x, root_y, timestamp);
4708 gdk_x11_window_enable_synchronized_configure (GdkWindow *window)
4710 GdkWindowImplX11 *impl;
4712 if (!GDK_IS_WINDOW_IMPL_X11 (window->impl))
4715 impl = GDK_WINDOW_IMPL_X11 (window->impl);
4717 if (!impl->use_synchronized_configure)
4719 /* This basically means you want to do fancy X specific stuff, so
4720 ensure we have a native window */
4721 gdk_window_ensure_native (window);
4723 impl->use_synchronized_configure = TRUE;
4724 ensure_sync_counter (window);
4729 gdk_x11_window_configure_finished (GdkWindow *window)
4731 GdkWindowImplX11 *impl;
4733 if (!WINDOW_IS_TOPLEVEL (window))
4736 impl = GDK_WINDOW_IMPL_X11 (window->impl);
4737 if (!impl->use_synchronized_configure)
4741 if (!GDK_WINDOW_DESTROYED (window))
4743 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
4744 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
4746 if (toplevel && toplevel->update_counter != None &&
4747 GDK_X11_DISPLAY (display)->use_sync &&
4748 !XSyncValueIsZero (toplevel->current_counter_value))
4750 XSyncSetCounter (GDK_WINDOW_XDISPLAY (window),
4751 toplevel->update_counter,
4752 toplevel->current_counter_value);
4754 XSyncIntToValue (&toplevel->current_counter_value, 0);
4761 gdk_x11_window_beep (GdkWindow *window)
4763 GdkDisplay *display;
4765 display = GDK_WINDOW_DISPLAY (window);
4768 if (GDK_X11_DISPLAY (display)->use_xkb)
4770 XkbBell (GDK_DISPLAY_XDISPLAY (display),
4771 GDK_WINDOW_XID (window),
4782 gdk_x11_window_set_opacity (GdkWindow *window,
4785 GdkDisplay *display;
4788 g_return_if_fail (GDK_IS_WINDOW (window));
4790 if (GDK_WINDOW_DESTROYED (window) ||
4791 !WINDOW_IS_TOPLEVEL (window))
4794 display = gdk_window_get_display (window);
4798 else if (opacity > 1)
4801 cardinal = opacity * 0xffffffff;
4803 if (cardinal == 0xffffffff)
4804 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
4805 GDK_WINDOW_XID (window),
4806 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_OPACITY"));
4808 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
4809 GDK_WINDOW_XID (window),
4810 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_OPACITY"),
4813 (guchar *) &cardinal, 1);
4817 gdk_x11_window_set_composited (GdkWindow *window,
4818 gboolean composited)
4820 #if defined(HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES)
4821 GdkWindowImplX11 *impl;
4822 GdkDisplay *display;
4826 impl = GDK_WINDOW_IMPL_X11 (window->impl);
4828 display = gdk_window_get_display (window);
4829 dpy = GDK_DISPLAY_XDISPLAY (display);
4830 xid = GDK_WINDOW_XID (window);
4834 XCompositeRedirectWindow (dpy, xid, CompositeRedirectManual);
4835 impl->damage = XDamageCreate (dpy, xid, XDamageReportBoundingBox);
4839 XCompositeUnredirectWindow (dpy, xid, CompositeRedirectManual);
4840 XDamageDestroy (dpy, impl->damage);
4841 impl->damage = None;
4847 gdk_x11_window_process_updates_recurse (GdkWindow *window,
4848 cairo_region_t *region)
4850 _gdk_window_process_updates_recurse (window, region);
4854 _gdk_x11_display_before_process_all_updates (GdkDisplay *display)
4859 _gdk_x11_display_after_process_all_updates (GdkDisplay *display)
4861 /* Sync after all drawing, otherwise the client can get "ahead" of
4862 the server rendering during animations, such that we fill up
4863 the Xserver pipes with sync rendering ops not letting other
4864 clients (including the VM) do anything. */
4865 XSync (GDK_DISPLAY_XDISPLAY (display), FALSE);
4869 timestamp_predicate (Display *display,
4873 Window xwindow = GPOINTER_TO_UINT (arg);
4874 GdkDisplay *gdk_display = gdk_x11_lookup_xdisplay (display);
4876 if (xevent->type == PropertyNotify &&
4877 xevent->xproperty.window == xwindow &&
4878 xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
4879 "GDK_TIMESTAMP_PROP"))
4886 * gdk_x11_get_server_time:
4887 * @window: (type GdkX11Window): a #GdkWindow, used for communication
4888 * with the server. The window must have
4889 * GDK_PROPERTY_CHANGE_MASK in its events mask or a hang will
4892 * Routine to get the current X server time stamp.
4894 * Return value: the time stamp.
4897 gdk_x11_get_server_time (GdkWindow *window)
4903 Atom timestamp_prop_atom;
4905 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
4906 g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0);
4908 xdisplay = GDK_WINDOW_XDISPLAY (window);
4909 xwindow = GDK_WINDOW_XID (window);
4910 timestamp_prop_atom =
4911 gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
4912 "GDK_TIMESTAMP_PROP");
4914 XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
4915 timestamp_prop_atom,
4916 8, PropModeReplace, &c, 1);
4918 XIfEvent (xdisplay, &xevent,
4919 timestamp_predicate, GUINT_TO_POINTER(xwindow));
4921 return xevent.xproperty.time;
4925 * gdk_x11_window_get_xid:
4926 * @window: (type GdkX11Window): a native #GdkWindow.
4928 * Returns the X resource (window) belonging to a #GdkWindow.
4930 * Return value: the ID of @drawable's X resource.
4933 gdk_x11_window_get_xid (GdkWindow *window)
4935 /* Try to ensure the window has a native window */
4936 if (!_gdk_window_has_impl (window))
4938 gdk_window_ensure_native (window);
4940 /* We sync here to ensure the window is created in the Xserver when
4941 * this function returns. This is required because the returned XID
4942 * for this window must be valid immediately, even with another
4943 * connection to the Xserver */
4944 gdk_display_sync (gdk_window_get_display (window));
4947 if (!GDK_WINDOW_IS_X11 (window))
4949 g_warning (G_STRLOC " drawable is not a native X11 window");
4953 return GDK_WINDOW_IMPL_X11 (window->impl)->xid;
4956 extern GdkDragContext * _gdk_x11_window_drag_begin (GdkWindow *window,
4961 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
4963 GObjectClass *object_class = G_OBJECT_CLASS (klass);
4964 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
4966 object_class->finalize = gdk_window_impl_x11_finalize;
4968 impl_class->ref_cairo_surface = gdk_x11_ref_cairo_surface;
4969 impl_class->show = gdk_window_x11_show;
4970 impl_class->hide = gdk_window_x11_hide;
4971 impl_class->withdraw = gdk_window_x11_withdraw;
4972 impl_class->set_events = gdk_window_x11_set_events;
4973 impl_class->get_events = gdk_window_x11_get_events;
4974 impl_class->raise = gdk_window_x11_raise;
4975 impl_class->lower = gdk_window_x11_lower;
4976 impl_class->restack_under = gdk_window_x11_restack_under;
4977 impl_class->restack_toplevel = gdk_window_x11_restack_toplevel;
4978 impl_class->move_resize = gdk_window_x11_move_resize;
4979 impl_class->set_background = gdk_window_x11_set_background;
4980 impl_class->reparent = gdk_window_x11_reparent;
4981 impl_class->set_device_cursor = gdk_window_x11_set_device_cursor;
4982 impl_class->get_geometry = gdk_window_x11_get_geometry;
4983 impl_class->get_root_coords = gdk_window_x11_get_root_coords;
4984 impl_class->get_device_state = gdk_window_x11_get_device_state;
4985 impl_class->shape_combine_region = gdk_window_x11_shape_combine_region;
4986 impl_class->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
4987 impl_class->set_static_gravities = gdk_window_x11_set_static_gravities;
4988 impl_class->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
4989 impl_class->translate = _gdk_x11_window_translate;
4990 impl_class->destroy = gdk_x11_window_destroy;
4991 impl_class->destroy_foreign = gdk_x11_window_destroy_foreign;
4992 impl_class->resize_cairo_surface = gdk_window_x11_resize_cairo_surface;
4993 impl_class->get_shape = gdk_x11_window_get_shape;
4994 impl_class->get_input_shape = gdk_x11_window_get_input_shape;
4995 impl_class->beep = gdk_x11_window_beep;
4997 impl_class->focus = gdk_x11_window_focus;
4998 impl_class->set_type_hint = gdk_x11_window_set_type_hint;
4999 impl_class->get_type_hint = gdk_x11_window_get_type_hint;
5000 impl_class->set_modal_hint = gdk_x11_window_set_modal_hint;
5001 impl_class->set_skip_taskbar_hint = gdk_x11_window_set_skip_taskbar_hint;
5002 impl_class->set_skip_pager_hint = gdk_x11_window_set_skip_pager_hint;
5003 impl_class->set_urgency_hint = gdk_x11_window_set_urgency_hint;
5004 impl_class->set_geometry_hints = gdk_x11_window_set_geometry_hints;
5005 impl_class->set_title = gdk_x11_window_set_title;
5006 impl_class->set_role = gdk_x11_window_set_role;
5007 impl_class->set_startup_id = gdk_x11_window_set_startup_id;
5008 impl_class->set_transient_for = gdk_x11_window_set_transient_for;
5009 impl_class->get_root_origin = gdk_x11_window_get_root_origin;
5010 impl_class->get_frame_extents = gdk_x11_window_get_frame_extents;
5011 impl_class->set_override_redirect = gdk_x11_window_set_override_redirect;
5012 impl_class->set_accept_focus = gdk_x11_window_set_accept_focus;
5013 impl_class->set_focus_on_map = gdk_x11_window_set_focus_on_map;
5014 impl_class->set_icon_list = gdk_x11_window_set_icon_list;
5015 impl_class->set_icon_name = gdk_x11_window_set_icon_name;
5016 impl_class->iconify = gdk_x11_window_iconify;
5017 impl_class->deiconify = gdk_x11_window_deiconify;
5018 impl_class->stick = gdk_x11_window_stick;
5019 impl_class->unstick = gdk_x11_window_unstick;
5020 impl_class->maximize = gdk_x11_window_maximize;
5021 impl_class->unmaximize = gdk_x11_window_unmaximize;
5022 impl_class->fullscreen = gdk_x11_window_fullscreen;
5023 impl_class->unfullscreen = gdk_x11_window_unfullscreen;
5024 impl_class->set_keep_above = gdk_x11_window_set_keep_above;
5025 impl_class->set_keep_below = gdk_x11_window_set_keep_below;
5026 impl_class->get_group = gdk_x11_window_get_group;
5027 impl_class->set_group = gdk_x11_window_set_group;
5028 impl_class->set_decorations = gdk_x11_window_set_decorations;
5029 impl_class->get_decorations = gdk_x11_window_get_decorations;
5030 impl_class->set_functions = gdk_x11_window_set_functions;
5031 impl_class->set_functions = gdk_x11_window_set_functions;
5032 impl_class->begin_resize_drag = gdk_x11_window_begin_resize_drag;
5033 impl_class->begin_move_drag = gdk_x11_window_begin_move_drag;
5034 impl_class->enable_synchronized_configure = gdk_x11_window_enable_synchronized_configure;
5035 impl_class->configure_finished = gdk_x11_window_configure_finished;
5036 impl_class->set_opacity = gdk_x11_window_set_opacity;
5037 impl_class->set_composited = gdk_x11_window_set_composited;
5038 impl_class->destroy_notify = gdk_x11_window_destroy_notify;
5039 impl_class->get_drag_protocol = gdk_x11_window_get_drag_protocol;
5040 impl_class->register_dnd = _gdk_x11_window_register_dnd;
5041 impl_class->drag_begin = _gdk_x11_window_drag_begin;
5042 impl_class->process_updates_recurse = gdk_x11_window_process_updates_recurse;
5043 impl_class->sync_rendering = _gdk_x11_window_sync_rendering;
5044 impl_class->simulate_key = _gdk_x11_window_simulate_key;
5045 impl_class->simulate_button = _gdk_x11_window_simulate_button;
5046 impl_class->get_property = _gdk_x11_window_get_property;
5047 impl_class->change_property = _gdk_x11_window_change_property;
5048 impl_class->delete_property = _gdk_x11_window_delete_property;