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)
4864 timestamp_predicate (Display *display,
4868 Window xwindow = GPOINTER_TO_UINT (arg);
4869 GdkDisplay *gdk_display = gdk_x11_lookup_xdisplay (display);
4871 if (xevent->type == PropertyNotify &&
4872 xevent->xproperty.window == xwindow &&
4873 xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
4874 "GDK_TIMESTAMP_PROP"))
4881 * gdk_x11_get_server_time:
4882 * @window: (type GdkX11Window): a #GdkWindow, used for communication
4883 * with the server. The window must have
4884 * GDK_PROPERTY_CHANGE_MASK in its events mask or a hang will
4887 * Routine to get the current X server time stamp.
4889 * Return value: the time stamp.
4892 gdk_x11_get_server_time (GdkWindow *window)
4898 Atom timestamp_prop_atom;
4900 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
4901 g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0);
4903 xdisplay = GDK_WINDOW_XDISPLAY (window);
4904 xwindow = GDK_WINDOW_XID (window);
4905 timestamp_prop_atom =
4906 gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
4907 "GDK_TIMESTAMP_PROP");
4909 XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
4910 timestamp_prop_atom,
4911 8, PropModeReplace, &c, 1);
4913 XIfEvent (xdisplay, &xevent,
4914 timestamp_predicate, GUINT_TO_POINTER(xwindow));
4916 return xevent.xproperty.time;
4920 * gdk_x11_window_get_xid:
4921 * @window: (type GdkX11Window): a native #GdkWindow.
4923 * Returns the X resource (window) belonging to a #GdkWindow.
4925 * Return value: the ID of @drawable's X resource.
4928 gdk_x11_window_get_xid (GdkWindow *window)
4930 /* Try to ensure the window has a native window */
4931 if (!_gdk_window_has_impl (window))
4933 gdk_window_ensure_native (window);
4935 /* We sync here to ensure the window is created in the Xserver when
4936 * this function returns. This is required because the returned XID
4937 * for this window must be valid immediately, even with another
4938 * connection to the Xserver */
4939 gdk_display_sync (gdk_window_get_display (window));
4942 if (!GDK_WINDOW_IS_X11 (window))
4944 g_warning (G_STRLOC " drawable is not a native X11 window");
4948 return GDK_WINDOW_IMPL_X11 (window->impl)->xid;
4951 extern GdkDragContext * _gdk_x11_window_drag_begin (GdkWindow *window,
4956 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
4958 GObjectClass *object_class = G_OBJECT_CLASS (klass);
4959 GdkWindowImplClass *impl_class = GDK_WINDOW_IMPL_CLASS (klass);
4961 object_class->finalize = gdk_window_impl_x11_finalize;
4963 impl_class->ref_cairo_surface = gdk_x11_ref_cairo_surface;
4964 impl_class->show = gdk_window_x11_show;
4965 impl_class->hide = gdk_window_x11_hide;
4966 impl_class->withdraw = gdk_window_x11_withdraw;
4967 impl_class->set_events = gdk_window_x11_set_events;
4968 impl_class->get_events = gdk_window_x11_get_events;
4969 impl_class->raise = gdk_window_x11_raise;
4970 impl_class->lower = gdk_window_x11_lower;
4971 impl_class->restack_under = gdk_window_x11_restack_under;
4972 impl_class->restack_toplevel = gdk_window_x11_restack_toplevel;
4973 impl_class->move_resize = gdk_window_x11_move_resize;
4974 impl_class->set_background = gdk_window_x11_set_background;
4975 impl_class->reparent = gdk_window_x11_reparent;
4976 impl_class->set_device_cursor = gdk_window_x11_set_device_cursor;
4977 impl_class->get_geometry = gdk_window_x11_get_geometry;
4978 impl_class->get_root_coords = gdk_window_x11_get_root_coords;
4979 impl_class->get_device_state = gdk_window_x11_get_device_state;
4980 impl_class->shape_combine_region = gdk_window_x11_shape_combine_region;
4981 impl_class->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
4982 impl_class->set_static_gravities = gdk_window_x11_set_static_gravities;
4983 impl_class->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
4984 impl_class->translate = _gdk_x11_window_translate;
4985 impl_class->destroy = gdk_x11_window_destroy;
4986 impl_class->destroy_foreign = gdk_x11_window_destroy_foreign;
4987 impl_class->resize_cairo_surface = gdk_window_x11_resize_cairo_surface;
4988 impl_class->get_shape = gdk_x11_window_get_shape;
4989 impl_class->get_input_shape = gdk_x11_window_get_input_shape;
4990 impl_class->beep = gdk_x11_window_beep;
4992 impl_class->focus = gdk_x11_window_focus;
4993 impl_class->set_type_hint = gdk_x11_window_set_type_hint;
4994 impl_class->get_type_hint = gdk_x11_window_get_type_hint;
4995 impl_class->set_modal_hint = gdk_x11_window_set_modal_hint;
4996 impl_class->set_skip_taskbar_hint = gdk_x11_window_set_skip_taskbar_hint;
4997 impl_class->set_skip_pager_hint = gdk_x11_window_set_skip_pager_hint;
4998 impl_class->set_urgency_hint = gdk_x11_window_set_urgency_hint;
4999 impl_class->set_geometry_hints = gdk_x11_window_set_geometry_hints;
5000 impl_class->set_title = gdk_x11_window_set_title;
5001 impl_class->set_role = gdk_x11_window_set_role;
5002 impl_class->set_startup_id = gdk_x11_window_set_startup_id;
5003 impl_class->set_transient_for = gdk_x11_window_set_transient_for;
5004 impl_class->get_root_origin = gdk_x11_window_get_root_origin;
5005 impl_class->get_frame_extents = gdk_x11_window_get_frame_extents;
5006 impl_class->set_override_redirect = gdk_x11_window_set_override_redirect;
5007 impl_class->set_accept_focus = gdk_x11_window_set_accept_focus;
5008 impl_class->set_focus_on_map = gdk_x11_window_set_focus_on_map;
5009 impl_class->set_icon_list = gdk_x11_window_set_icon_list;
5010 impl_class->set_icon_name = gdk_x11_window_set_icon_name;
5011 impl_class->iconify = gdk_x11_window_iconify;
5012 impl_class->deiconify = gdk_x11_window_deiconify;
5013 impl_class->stick = gdk_x11_window_stick;
5014 impl_class->unstick = gdk_x11_window_unstick;
5015 impl_class->maximize = gdk_x11_window_maximize;
5016 impl_class->unmaximize = gdk_x11_window_unmaximize;
5017 impl_class->fullscreen = gdk_x11_window_fullscreen;
5018 impl_class->unfullscreen = gdk_x11_window_unfullscreen;
5019 impl_class->set_keep_above = gdk_x11_window_set_keep_above;
5020 impl_class->set_keep_below = gdk_x11_window_set_keep_below;
5021 impl_class->get_group = gdk_x11_window_get_group;
5022 impl_class->set_group = gdk_x11_window_set_group;
5023 impl_class->set_decorations = gdk_x11_window_set_decorations;
5024 impl_class->get_decorations = gdk_x11_window_get_decorations;
5025 impl_class->set_functions = gdk_x11_window_set_functions;
5026 impl_class->set_functions = gdk_x11_window_set_functions;
5027 impl_class->begin_resize_drag = gdk_x11_window_begin_resize_drag;
5028 impl_class->begin_move_drag = gdk_x11_window_begin_move_drag;
5029 impl_class->enable_synchronized_configure = gdk_x11_window_enable_synchronized_configure;
5030 impl_class->configure_finished = gdk_x11_window_configure_finished;
5031 impl_class->set_opacity = gdk_x11_window_set_opacity;
5032 impl_class->set_composited = gdk_x11_window_set_composited;
5033 impl_class->destroy_notify = gdk_x11_window_destroy_notify;
5034 impl_class->get_drag_protocol = gdk_x11_window_get_drag_protocol;
5035 impl_class->register_dnd = _gdk_x11_window_register_dnd;
5036 impl_class->drag_begin = _gdk_x11_window_drag_begin;
5037 impl_class->process_updates_recurse = gdk_x11_window_process_updates_recurse;
5038 impl_class->sync_rendering = _gdk_x11_window_sync_rendering;
5039 impl_class->simulate_key = _gdk_x11_window_simulate_key;
5040 impl_class->simulate_button = _gdk_x11_window_simulate_button;
5041 impl_class->get_property = _gdk_x11_window_get_property;
5042 impl_class->change_property = _gdk_x11_window_change_property;
5043 impl_class->delete_property = _gdk_x11_window_delete_property;