1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-2007 Peter Mattis, Spencer Kimball,
3 * Josh MacDonald, Ryan Lortie
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
23 * file for a list of people on the GTK+ Team. See the ChangeLog
24 * files for a list of changes. These files are distributed with
25 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include <X11/Xutil.h>
32 #include <X11/Xatom.h>
35 #include <X11/XKBlib.h>
38 #include <netinet/in.h>
44 #include "gdkwindow.h"
45 #include "gdkwindowimpl.h"
47 #include "gdkdisplay-x11.h"
48 #include "gdkprivate-x11.h"
49 #include "gdkinternals.h"
51 #include "gdkwindow-x11.h"
52 #include "gdkdeviceprivate.h"
53 #include "gdkeventsource.h"
61 #include <X11/extensions/shape.h>
63 #ifdef HAVE_XCOMPOSITE
64 #include <X11/extensions/Xcomposite.h>
68 #include <X11/extensions/Xfixes.h>
72 #include <X11/extensions/Xdamage.h>
75 const int _gdk_event_mask_table[21] =
79 PointerMotionHintMask,
96 SubstructureNotifyMask,
97 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
99 const int _gdk_nenvent_masks = sizeof (_gdk_event_mask_table) / sizeof (int);
101 /* Forward declarations */
102 static void gdk_window_set_static_win_gravity (GdkWindow *window,
104 static gboolean gdk_window_icon_name_set (GdkWindow *window);
105 static void gdk_window_add_colormap_windows (GdkWindow *window);
106 static void set_wm_name (GdkDisplay *display,
109 static void move_to_current_desktop (GdkWindow *window);
111 static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
112 static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
114 static void gdk_window_impl_x11_finalize (GObject *object);
115 static void gdk_window_impl_iface_init (GdkWindowImplIface *iface);
117 #define WINDOW_IS_TOPLEVEL_OR_FOREIGN(window) \
118 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
119 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
121 #define WINDOW_IS_TOPLEVEL(window) \
122 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
123 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN && \
124 GDK_WINDOW_TYPE (window) != GDK_WINDOW_OFFSCREEN)
126 /* Return whether time1 is considered later than time2 as far as xserver
127 * time is concerned. Accounts for wraparound.
129 #define XSERVER_TIME_IS_LATER(time1, time2) \
130 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
131 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
134 G_DEFINE_TYPE_WITH_CODE (GdkWindowImplX11,
136 GDK_TYPE_DRAWABLE_IMPL_X11,
137 G_IMPLEMENT_INTERFACE (GDK_TYPE_WINDOW_IMPL,
138 gdk_window_impl_iface_init));
141 _gdk_window_impl_get_type (void)
143 return gdk_window_impl_x11_get_type ();
147 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
149 impl->toplevel_window_type = -1;
150 impl->device_cursor = g_hash_table_new_full (NULL, NULL, NULL,
151 (GDestroyNotify) gdk_cursor_unref);
155 _gdk_x11_window_get_toplevel (GdkWindow *window)
157 GdkWindowObject *private;
158 GdkWindowImplX11 *impl;
160 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
162 if (!WINDOW_IS_TOPLEVEL (window))
165 private = (GdkWindowObject *)window;
166 impl = GDK_WINDOW_IMPL_X11 (private->impl);
169 impl->toplevel = g_new0 (GdkToplevelX11, 1);
171 return impl->toplevel;
175 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
177 GObjectClass *object_class = G_OBJECT_CLASS (klass);
178 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
180 object_class->finalize = gdk_window_impl_x11_finalize;
182 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
183 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
187 gdk_window_impl_x11_finalize (GObject *object)
189 GdkWindowObject *wrapper;
190 GdkDrawableImplX11 *draw_impl;
191 GdkWindowImplX11 *window_impl;
193 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
195 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
196 window_impl = GDK_WINDOW_IMPL_X11 (object);
198 wrapper = (GdkWindowObject*) draw_impl->wrapper;
200 _gdk_xgrab_check_destroy (GDK_WINDOW (wrapper));
202 if (!GDK_WINDOW_DESTROYED (wrapper))
204 GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
206 _gdk_xid_table_remove (display, draw_impl->xid);
207 if (window_impl->toplevel && window_impl->toplevel->focus_window)
208 _gdk_xid_table_remove (display, window_impl->toplevel->focus_window);
211 g_free (window_impl->toplevel);
213 if (window_impl->cursor)
214 gdk_cursor_unref (window_impl->cursor);
216 g_hash_table_destroy (window_impl->device_cursor);
218 G_OBJECT_CLASS (gdk_window_impl_x11_parent_class)->finalize (object);
222 tmp_unset_bg (GdkWindow *window)
224 GdkWindowImplX11 *impl;
225 GdkWindowObject *obj;
227 obj = (GdkWindowObject *) window;
228 impl = GDK_WINDOW_IMPL_X11 (obj->impl);
232 if (obj->bg_pixmap != GDK_NO_BG)
233 XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
234 GDK_DRAWABLE_XID (window), None);
238 tmp_reset_bg (GdkWindow *window)
240 GdkWindowImplX11 *impl;
241 GdkWindowObject *obj;
243 obj = (GdkWindowObject *) window;
244 impl = GDK_WINDOW_IMPL_X11 (obj->impl);
248 if (obj->bg_pixmap == GDK_NO_BG)
255 if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
256 xpixmap = ParentRelative;
258 xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
260 XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
261 GDK_DRAWABLE_XID (window), xpixmap);
265 XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
266 GDK_DRAWABLE_XID (window),
267 obj->bg_color.pixel);
271 /* Unsetting and resetting window backgrounds.
273 * In many cases it is possible to avoid flicker by unsetting the
274 * background of windows. For example if the background of the
275 * parent window is unset when a window is unmapped, a brief flicker
276 * of background painting is avoided.
279 _gdk_x11_window_tmp_unset_bg (GdkWindow *window,
282 GdkWindowObject *private;
284 g_return_if_fail (GDK_IS_WINDOW (window));
286 private = (GdkWindowObject *)window;
288 if (private->input_only || private->destroyed ||
289 (private->window_type != GDK_WINDOW_ROOT &&
290 !GDK_WINDOW_IS_MAPPED (window)))
293 if (_gdk_window_has_impl (window) &&
294 GDK_WINDOW_IS_X11 (window) &&
295 private->window_type != GDK_WINDOW_ROOT &&
296 private->window_type != GDK_WINDOW_FOREIGN)
297 tmp_unset_bg (window);
303 for (l = private->children; l != NULL; l = l->next)
304 _gdk_x11_window_tmp_unset_bg (l->data, TRUE);
309 _gdk_x11_window_tmp_unset_parent_bg (GdkWindow *window)
311 GdkWindowObject *private;
312 private = (GdkWindowObject*) window;
314 if (GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_ROOT)
317 window = _gdk_window_get_impl_window ((GdkWindow *)private->parent);
318 _gdk_x11_window_tmp_unset_bg (window, FALSE);
322 _gdk_x11_window_tmp_reset_bg (GdkWindow *window,
325 GdkWindowObject *private;
327 g_return_if_fail (GDK_IS_WINDOW (window));
329 private = (GdkWindowObject *)window;
331 if (private->input_only || private->destroyed ||
332 (private->window_type != GDK_WINDOW_ROOT &&
333 !GDK_WINDOW_IS_MAPPED (window)))
337 if (_gdk_window_has_impl (window) &&
338 GDK_WINDOW_IS_X11 (window) &&
339 private->window_type != GDK_WINDOW_ROOT &&
340 private->window_type != GDK_WINDOW_FOREIGN)
341 tmp_reset_bg (window);
347 for (l = private->children; l != NULL; l = l->next)
348 _gdk_x11_window_tmp_reset_bg (l->data, TRUE);
353 _gdk_x11_window_tmp_reset_parent_bg (GdkWindow *window)
355 GdkWindowObject *private;
356 private = (GdkWindowObject*) window;
358 if (GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_ROOT)
361 window = _gdk_window_get_impl_window ((GdkWindow *)private->parent);
363 _gdk_x11_window_tmp_reset_bg (window, FALSE);
367 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
369 GdkDrawableImplX11 *drawable_impl;
371 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
373 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
375 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
376 drawable_impl->colormap == NULL)
378 XWindowAttributes window_attributes;
381 XGetWindowAttributes (GDK_SCREEN_XDISPLAY (drawable_impl->screen),
385 visual = gdk_x11_screen_lookup_visual (drawable_impl->screen,
386 window_attributes.visual->visualid);
387 drawable_impl->colormap = gdk_x11_colormap_foreign_new (visual,
388 window_attributes.colormap);
391 return drawable_impl->colormap;
395 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
398 GdkDrawableImplX11 *draw_impl;
400 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
402 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
404 if (cmap && GDK_WINDOW_DESTROYED (draw_impl->wrapper))
408 GDK_DRAWABLE_CLASS (gdk_window_impl_x11_parent_class)->set_colormap (drawable, cmap);
412 XSetWindowColormap (GDK_SCREEN_XDISPLAY (draw_impl->screen),
414 GDK_COLORMAP_XCOLORMAP (cmap));
416 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
418 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
424 _gdk_windowing_window_init (GdkScreen * screen)
426 GdkWindowObject *private;
427 GdkDrawableImplX11 *draw_impl;
428 GdkScreenX11 *screen_x11;
430 screen_x11 = GDK_SCREEN_X11 (screen);
432 g_assert (screen_x11->root_window == NULL);
434 gdk_screen_set_default_colormap (screen,
435 gdk_screen_get_system_colormap (screen));
437 screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
439 private = (GdkWindowObject *) screen_x11->root_window;
440 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
441 private->impl_window = private;
443 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
445 draw_impl->screen = screen;
446 draw_impl->xid = screen_x11->xroot_window;
447 draw_impl->wrapper = GDK_DRAWABLE (private);
448 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
449 g_object_ref (draw_impl->colormap);
451 private->window_type = GDK_WINDOW_ROOT;
452 private->depth = DefaultDepthOfScreen (screen_x11->xscreen);
458 private->width = WidthOfScreen (screen_x11->xscreen);
459 private->height = HeightOfScreen (screen_x11->xscreen);
460 private->viewable = TRUE;
462 /* see init_randr_support() in gdkscreen-x11.c */
463 private->event_mask = GDK_STRUCTURE_MASK;
465 _gdk_window_update_size (screen_x11->root_window);
467 _gdk_xid_table_insert (screen_x11->display,
468 &screen_x11->xroot_window,
469 screen_x11->root_window);
473 set_wm_protocols (GdkWindow *window)
475 GdkDisplay *display = gdk_drawable_get_display (window);
479 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
480 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
481 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
484 if (GDK_DISPLAY_X11 (display)->use_sync)
485 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
488 XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
492 get_default_title (void)
496 title = g_get_application_name ();
498 title = g_get_prgname ();
506 check_leader_window_title (GdkDisplay *display)
508 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
510 if (display_x11->leader_window && !display_x11->leader_window_title_set)
512 set_wm_name (display,
513 display_x11->leader_window,
514 get_default_title ());
516 display_x11->leader_window_title_set = TRUE;
521 create_focus_window (GdkDisplay *display,
524 GdkDisplayX11 *display_x11;
525 GdkEventMask event_mask;
529 xdisplay = GDK_DISPLAY_XDISPLAY (display);
530 display_x11 = GDK_DISPLAY_X11 (display);
532 focus_window = XCreateSimpleWindow (xdisplay, parent,
536 /* FIXME: probably better to actually track the requested event mask for the toplevel
538 event_mask = (GDK_KEY_PRESS_MASK |
539 GDK_KEY_RELEASE_MASK |
540 GDK_FOCUS_CHANGE_MASK);
542 gdk_event_source_select_events ((GdkEventSource *) display_x11->event_source,
546 XMapWindow (xdisplay, focus_window);
552 ensure_sync_counter (GdkWindow *window)
555 if (!GDK_WINDOW_DESTROYED (window))
557 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
558 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
559 GdkWindowObject *private = (GdkWindowObject *)window;
560 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
562 if (toplevel && impl->use_synchronized_configure &&
563 toplevel->update_counter == None &&
564 GDK_DISPLAY_X11 (display)->use_sync)
566 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
570 XSyncIntToValue (&value, 0);
572 toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
574 atom = gdk_x11_get_xatom_by_name_for_display (display,
575 "_NET_WM_SYNC_REQUEST_COUNTER");
577 XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
580 (guchar *)&toplevel->update_counter, 1);
582 XSyncIntToValue (&toplevel->current_counter_value, 0);
589 setup_toplevel_window (GdkWindow *window,
592 GdkWindowObject *obj = (GdkWindowObject *)window;
593 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
594 GdkDisplay *display = gdk_drawable_get_display (window);
595 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
596 XID xid = GDK_WINDOW_XID (window);
597 XID xparent = GDK_WINDOW_XID (parent);
598 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (parent));
599 XSizeHints size_hints;
601 Window leader_window;
603 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
604 XSetTransientForHint (xdisplay, xid, xparent);
606 set_wm_protocols (window);
608 if (!obj->input_only)
610 /* The focus window is off the visible area, and serves to receive key
611 * press events so they don't get sent to child windows.
613 toplevel->focus_window = create_focus_window (display, xid);
614 _gdk_xid_table_insert (screen_x11->display, &toplevel->focus_window, window);
617 check_leader_window_title (screen_x11->display);
619 /* FIXME: Is there any point in doing this? Do any WM's pay
620 * attention to PSize, and even if they do, is this the
623 size_hints.flags = PSize;
624 size_hints.width = obj->width;
625 size_hints.height = obj->height;
627 XSetWMNormalHints (xdisplay, xid, &size_hints);
629 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
630 XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
633 XChangeProperty (xdisplay, xid,
634 gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_PID"),
639 leader_window = GDK_DISPLAY_X11 (screen_x11->display)->leader_window;
642 XChangeProperty (xdisplay, xid,
643 gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"),
644 XA_WINDOW, 32, PropModeReplace,
645 (guchar *) &leader_window, 1);
647 if (toplevel->focus_window != None)
648 XChangeProperty (xdisplay, xid,
649 gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_USER_TIME_WINDOW"),
650 XA_WINDOW, 32, PropModeReplace,
651 (guchar *) &toplevel->focus_window, 1);
653 if (!obj->focus_on_map)
654 gdk_x11_window_set_user_time (window, 0);
655 else if (GDK_DISPLAY_X11 (screen_x11->display)->user_time != 0)
656 gdk_x11_window_set_user_time (window, GDK_DISPLAY_X11 (screen_x11->display)->user_time);
658 ensure_sync_counter (window);
662 _gdk_window_impl_new (GdkWindow *window,
663 GdkWindow *real_parent,
666 GdkEventMask event_mask,
667 GdkWindowAttr *attributes,
668 gint attributes_mask)
670 GdkWindowObject *private;
671 GdkWindowImplX11 *impl;
672 GdkDrawableImplX11 *draw_impl;
673 GdkScreenX11 *screen_x11;
674 GdkDisplayX11 *display_x11;
681 XSetWindowAttributes xattributes;
682 long xattributes_mask;
683 XClassHint *class_hint;
688 private = (GdkWindowObject *) window;
690 screen_x11 = GDK_SCREEN_X11 (screen);
691 xparent = GDK_WINDOW_XID (real_parent);
692 display_x11 = GDK_DISPLAY_X11 (GDK_SCREEN_DISPLAY (screen));
694 impl = g_object_new (_gdk_window_impl_get_type (), NULL);
695 private->impl = (GdkDrawable *)impl;
696 draw_impl = GDK_DRAWABLE_IMPL_X11 (impl);
697 draw_impl->wrapper = GDK_DRAWABLE (window);
699 draw_impl->screen = screen;
700 xdisplay = screen_x11->xdisplay;
702 xattributes_mask = 0;
704 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
706 if (attributes_mask & GDK_WA_NOREDIR)
708 xattributes.override_redirect =
709 (attributes->override_redirect == FALSE)?False:True;
710 xattributes_mask |= CWOverrideRedirect;
713 xattributes.override_redirect = False;
715 impl->override_redirect = xattributes.override_redirect;
717 if (private->parent && private->parent->guffaw_gravity)
719 xattributes.win_gravity = StaticGravity;
720 xattributes_mask |= CWWinGravity;
724 switch (private->window_type)
726 case GDK_WINDOW_TOPLEVEL:
727 case GDK_WINDOW_DIALOG:
728 case GDK_WINDOW_TEMP:
729 if (GDK_WINDOW_TYPE (private->parent) != GDK_WINDOW_ROOT)
731 /* The common code warns for this case */
732 xparent = GDK_SCREEN_XROOTWIN (screen);
736 if (!private->input_only)
740 if (attributes_mask & GDK_WA_COLORMAP)
742 draw_impl->colormap = attributes->colormap;
743 g_object_ref (attributes->colormap);
747 if ((((GdkVisualPrivate *)gdk_screen_get_system_visual (screen))->xvisual) == xvisual)
749 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
750 g_object_ref (draw_impl->colormap);
754 draw_impl->colormap = gdk_colormap_new (visual, FALSE);
758 xattributes.background_pixel = private->bg_color.pixel;
760 xattributes.border_pixel = BlackPixel (xdisplay, screen_x11->screen_num);
761 xattributes_mask |= CWBorderPixel | CWBackPixel;
763 if (private->guffaw_gravity)
764 xattributes.bit_gravity = StaticGravity;
766 xattributes.bit_gravity = NorthWestGravity;
768 xattributes_mask |= CWBitGravity;
770 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
771 xattributes_mask |= CWColormap;
773 if (private->window_type == GDK_WINDOW_TEMP)
775 xattributes.save_under = True;
776 xattributes.override_redirect = True;
777 xattributes.cursor = None;
778 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
780 impl->override_redirect = TRUE;
786 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
787 g_object_ref (draw_impl->colormap);
790 if (private->width > 65535 ||
791 private->height > 65535)
793 g_warning ("Native Windows wider or taller than 65535 pixels are not supported");
795 if (private->width > 65535)
796 private->width = 65535;
797 if (private->height > 65535)
798 private->height = 65535;
801 xid = draw_impl->xid = XCreateWindow (xdisplay, xparent,
802 private->x + private->parent->abs_x,
803 private->y + private->parent->abs_y,
804 private->width, private->height,
805 0, private->depth, class, xvisual,
806 xattributes_mask, &xattributes);
808 g_object_ref (window);
809 _gdk_xid_table_insert (screen_x11->display, &draw_impl->xid, window);
811 switch (GDK_WINDOW_TYPE (private))
813 case GDK_WINDOW_DIALOG:
814 case GDK_WINDOW_TOPLEVEL:
815 case GDK_WINDOW_TEMP:
816 if (attributes_mask & GDK_WA_TITLE)
817 title = attributes->title;
819 title = get_default_title ();
821 gdk_window_set_title (window, title);
823 if (attributes_mask & GDK_WA_WMCLASS)
825 class_hint = XAllocClassHint ();
826 class_hint->res_name = attributes->wmclass_name;
827 class_hint->res_class = attributes->wmclass_class;
828 XSetClassHint (xdisplay, xid, class_hint);
832 setup_toplevel_window (window, (GdkWindow *)private->parent);
835 case GDK_WINDOW_CHILD:
836 if (!private->input_only &&
837 (draw_impl->colormap != gdk_screen_get_system_colormap (screen)) &&
838 (draw_impl->colormap != gdk_drawable_get_colormap (gdk_window_get_toplevel (window))))
840 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
841 gdk_window_add_colormap_windows (window);
849 if (attributes_mask & GDK_WA_TYPE_HINT)
850 gdk_window_set_type_hint (window, attributes->type_hint);
852 gdk_event_source_select_events ((GdkEventSource *) display_x11->event_source,
853 GDK_WINDOW_XWINDOW (window), event_mask,
854 StructureNotifyMask | PropertyChangeMask);
858 x_event_mask_to_gdk_event_mask (long mask)
860 GdkEventMask event_mask = 0;
863 for (i = 0; i < _gdk_nenvent_masks; i++)
865 if (mask & _gdk_event_mask_table[i])
866 event_mask |= 1 << (i + 1);
873 * gdk_window_foreign_new_for_display:
874 * @display: the #GdkDisplay where the window handle comes from.
875 * @anid: a native window handle.
877 * Wraps a native window in a #GdkWindow.
878 * This may fail if the window has been destroyed. If the window
879 * was already known to GDK, a new reference to the existing
880 * #GdkWindow is returned.
882 * For example in the X backend, a native window handle is an Xlib
885 * Return value: a #GdkWindow wrapper for the native window or
886 * %NULL if the window has been destroyed. The wrapper will be
887 * newly created, if one doesn't exist already.
892 gdk_window_foreign_new_for_display (GdkDisplay *display,
893 GdkNativeWindow anid)
896 GdkWindowObject *private;
897 GdkWindowImplX11 *impl;
898 GdkDrawableImplX11 *draw_impl;
899 GdkDisplayX11 *display_x11;
900 XWindowAttributes attrs;
902 Window *children = NULL;
906 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
908 display_x11 = GDK_DISPLAY_X11 (display);
910 if ((window = gdk_xid_table_lookup_for_display (display, anid)) != NULL)
911 return g_object_ref (window);
913 gdk_error_trap_push ();
914 result = XGetWindowAttributes (display_x11->xdisplay, anid, &attrs);
915 if (gdk_error_trap_pop () || !result)
918 /* FIXME: This is pretty expensive. Maybe the caller should supply
920 gdk_error_trap_push ();
921 result = XQueryTree (display_x11->xdisplay, anid, &root, &parent, &children, &nchildren);
922 if (gdk_error_trap_pop () || !result)
928 window = g_object_new (GDK_TYPE_WINDOW, NULL);
930 private = (GdkWindowObject *) window;
931 private->impl = g_object_new (_gdk_window_impl_get_type (), NULL);
932 private->impl_window = private;
934 impl = GDK_WINDOW_IMPL_X11 (private->impl);
935 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
936 draw_impl->wrapper = GDK_DRAWABLE (window);
937 draw_impl->screen = _gdk_x11_display_screen_for_xrootwin (display, root);
939 private->parent = gdk_xid_table_lookup_for_display (display, parent);
941 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
942 private->parent = (GdkWindowObject *) gdk_screen_get_root_window (draw_impl->screen);
944 private->parent->children = g_list_prepend (private->parent->children, window);
946 draw_impl->xid = anid;
948 private->x = attrs.x;
949 private->y = attrs.y;
950 private->width = attrs.width;
951 private->height = attrs.height;
952 private->window_type = GDK_WINDOW_FOREIGN;
953 private->destroyed = FALSE;
955 private->event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
957 if (attrs.map_state == IsUnmapped)
958 private->state = GDK_WINDOW_STATE_WITHDRAWN;
961 private->viewable = TRUE;
963 private->depth = attrs.depth;
965 g_object_ref (window);
966 _gdk_xid_table_insert (display, &GDK_WINDOW_XID (window), window);
968 /* Update the clip region, etc */
969 _gdk_window_update_size (window);
975 * gdk_window_lookup_for_display:
976 * @display: the #GdkDisplay corresponding to the window handle
977 * @anid: a native window handle.
979 * Looks up the #GdkWindow that wraps the given native window handle.
981 * For example in the X backend, a native window handle is an Xlib
984 * Return value: the #GdkWindow wrapper for the native window,
985 * or %NULL if there is none.
990 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
992 return (GdkWindow*) gdk_xid_table_lookup_for_display (display, anid);
997 * @anid: a native window handle.
999 * Looks up the #GdkWindow that wraps the given native window handle.
1001 * For example in the X backend, a native window handle is an Xlib
1004 * Return value: the #GdkWindow wrapper for the native window,
1005 * or %NULL if there is none.
1008 gdk_window_lookup (GdkNativeWindow anid)
1010 return (GdkWindow*) gdk_xid_table_lookup (anid);
1014 gdk_toplevel_x11_free_contents (GdkDisplay *display,
1015 GdkToplevelX11 *toplevel)
1017 if (toplevel->icon_window)
1019 g_object_unref (toplevel->icon_window);
1020 toplevel->icon_window = NULL;
1022 if (toplevel->icon_pixmap)
1024 g_object_unref (toplevel->icon_pixmap);
1025 toplevel->icon_pixmap = NULL;
1027 if (toplevel->icon_mask)
1029 g_object_unref (toplevel->icon_mask);
1030 toplevel->icon_mask = NULL;
1032 if (toplevel->group_leader)
1034 g_object_unref (toplevel->group_leader);
1035 toplevel->group_leader = NULL;
1038 if (toplevel->update_counter != None)
1040 XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display),
1041 toplevel->update_counter);
1042 toplevel->update_counter = None;
1044 XSyncIntToValue (&toplevel->current_counter_value, 0);
1050 _gdk_x11_window_destroy (GdkWindow *window,
1052 gboolean foreign_destroy)
1054 GdkWindowObject *private = (GdkWindowObject *)window;
1055 GdkToplevelX11 *toplevel;
1057 g_return_if_fail (GDK_IS_WINDOW (window));
1059 _gdk_selection_window_destroyed (window);
1061 toplevel = _gdk_x11_window_get_toplevel (window);
1063 gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
1065 _gdk_x11_drawable_finish (private->impl);
1067 if (!recursing && !foreign_destroy)
1069 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1074 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
1076 /* It's somebody else's window, but in our hierarchy,
1077 * so reparent it to the root window, and then send
1078 * it a delete event, as if we were a WM
1080 XClientMessageEvent xclient;
1082 gdk_error_trap_push ();
1083 gdk_window_hide (window);
1084 gdk_window_reparent (window, NULL, 0, 0);
1086 memset (&xclient, 0, sizeof (xclient));
1087 xclient.type = ClientMessage;
1088 xclient.window = GDK_WINDOW_XID (window);
1089 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
1091 xclient.format = 32;
1092 xclient.data.l[0] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
1093 "WM_DELETE_WINDOW");
1094 xclient.data.l[1] = CurrentTime;
1095 xclient.data.l[2] = 0;
1096 xclient.data.l[3] = 0;
1097 xclient.data.l[4] = 0;
1099 XSendEvent (GDK_WINDOW_XDISPLAY (window),
1100 GDK_WINDOW_XID (window),
1101 False, 0, (XEvent *)&xclient);
1102 gdk_display_sync (GDK_WINDOW_DISPLAY (window));
1103 gdk_error_trap_pop ();
1107 get_root (GdkWindow *window)
1109 GdkScreen *screen = gdk_drawable_get_screen (window);
1111 return gdk_screen_get_root_window (screen);
1114 /* This function is called when the XWindow is really gone.
1117 gdk_window_destroy_notify (GdkWindow *window)
1119 GdkWindowImplX11 *window_impl;
1121 window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
1123 if (!GDK_WINDOW_DESTROYED (window))
1125 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
1126 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
1128 _gdk_window_destroy (window, TRUE);
1131 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), GDK_WINDOW_XID (window));
1132 if (window_impl->toplevel && window_impl->toplevel->focus_window)
1133 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), window_impl->toplevel->focus_window);
1135 _gdk_xgrab_check_destroy (window);
1137 g_object_unref (window);
1141 update_wm_hints (GdkWindow *window,
1144 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
1145 GdkWindowObject *private = (GdkWindowObject *)window;
1146 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1150 !toplevel->is_leader &&
1151 private->state & GDK_WINDOW_STATE_WITHDRAWN)
1154 wm_hints.flags = StateHint | InputHint;
1155 wm_hints.input = private->accept_focus ? True : False;
1156 wm_hints.initial_state = NormalState;
1158 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1160 wm_hints.flags |= StateHint;
1161 wm_hints.initial_state = IconicState;
1164 if (toplevel->icon_window && !GDK_WINDOW_DESTROYED (toplevel->icon_window))
1166 wm_hints.flags |= IconWindowHint;
1167 wm_hints.icon_window = GDK_WINDOW_XID (toplevel->icon_window);
1170 if (toplevel->icon_pixmap)
1172 wm_hints.flags |= IconPixmapHint;
1173 wm_hints.icon_pixmap = GDK_PIXMAP_XID (toplevel->icon_pixmap);
1176 if (toplevel->icon_mask)
1178 wm_hints.flags |= IconMaskHint;
1179 wm_hints.icon_mask = GDK_PIXMAP_XID (toplevel->icon_mask);
1182 wm_hints.flags |= WindowGroupHint;
1183 if (toplevel->group_leader && !GDK_WINDOW_DESTROYED (toplevel->group_leader))
1185 wm_hints.flags |= WindowGroupHint;
1186 wm_hints.window_group = GDK_WINDOW_XID (toplevel->group_leader);
1189 wm_hints.window_group = GDK_DISPLAY_X11 (display)->leader_window;
1191 if (toplevel->urgency_hint)
1192 wm_hints.flags |= XUrgencyHint;
1194 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1195 GDK_WINDOW_XID (window),
1200 set_initial_hints (GdkWindow *window)
1202 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1203 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1204 Window xwindow = GDK_WINDOW_XID (window);
1205 GdkWindowObject *private;
1206 GdkToplevelX11 *toplevel;
1210 private = (GdkWindowObject*) window;
1211 toplevel = _gdk_x11_window_get_toplevel (window);
1216 update_wm_hints (window, TRUE);
1218 /* We set the spec hints regardless of whether the spec is supported,
1219 * since it can't hurt and it's kind of expensive to check whether
1225 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1227 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1228 "_NET_WM_STATE_MAXIMIZED_VERT");
1230 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1231 "_NET_WM_STATE_MAXIMIZED_HORZ");
1233 toplevel->have_maxhorz = toplevel->have_maxvert = TRUE;
1236 if (private->state & GDK_WINDOW_STATE_ABOVE)
1238 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1239 "_NET_WM_STATE_ABOVE");
1243 if (private->state & GDK_WINDOW_STATE_BELOW)
1245 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1246 "_NET_WM_STATE_BELOW");
1250 if (private->state & GDK_WINDOW_STATE_STICKY)
1252 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1253 "_NET_WM_STATE_STICKY");
1255 toplevel->have_sticky = TRUE;
1258 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1260 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1261 "_NET_WM_STATE_FULLSCREEN");
1263 toplevel->have_fullscreen = TRUE;
1266 if (private->modal_hint)
1268 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1269 "_NET_WM_STATE_MODAL");
1273 if (toplevel->skip_taskbar_hint)
1275 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1276 "_NET_WM_STATE_SKIP_TASKBAR");
1280 if (toplevel->skip_pager_hint)
1282 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1283 "_NET_WM_STATE_SKIP_PAGER");
1289 XChangeProperty (xdisplay,
1291 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
1292 XA_ATOM, 32, PropModeReplace,
1293 (guchar*) atoms, i);
1297 XDeleteProperty (xdisplay,
1299 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"));
1302 if (private->state & GDK_WINDOW_STATE_STICKY)
1304 atoms[0] = 0xFFFFFFFF;
1305 XChangeProperty (xdisplay,
1307 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
1308 XA_CARDINAL, 32, PropModeReplace,
1309 (guchar*) atoms, 1);
1310 toplevel->on_all_desktops = TRUE;
1314 XDeleteProperty (xdisplay,
1316 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"));
1319 toplevel->map_serial = NextRequest (xdisplay);
1323 gdk_window_x11_show (GdkWindow *window, gboolean already_mapped)
1325 GdkWindowObject *private = (GdkWindowObject*) window;
1326 GdkDisplay *display;
1327 GdkDisplayX11 *display_x11;
1328 GdkToplevelX11 *toplevel;
1329 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1330 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
1331 Window xwindow = GDK_WINDOW_XID (window);
1334 if (!already_mapped)
1335 set_initial_hints (window);
1337 if (WINDOW_IS_TOPLEVEL (window))
1339 display = gdk_drawable_get_display (window);
1340 display_x11 = GDK_DISPLAY_X11 (display);
1341 toplevel = _gdk_x11_window_get_toplevel (window);
1343 if (toplevel->user_time != 0 &&
1344 display_x11->user_time != 0 &&
1345 XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time))
1346 gdk_x11_window_set_user_time (window, display_x11->user_time);
1349 unset_bg = !private->input_only &&
1350 (private->window_type == GDK_WINDOW_CHILD ||
1351 impl->override_redirect) &&
1352 gdk_window_is_viewable (window);
1355 _gdk_x11_window_tmp_unset_bg (window, TRUE);
1357 XMapWindow (xdisplay, xwindow);
1360 _gdk_x11_window_tmp_reset_bg (window, TRUE);
1364 pre_unmap (GdkWindow *window)
1366 GdkWindow *start_window = NULL;
1367 GdkWindowObject *private = (GdkWindowObject *)window;
1369 if (private->input_only)
1372 if (private->window_type == GDK_WINDOW_CHILD)
1373 start_window = _gdk_window_get_impl_window ((GdkWindow *)private->parent);
1374 else if (private->window_type == GDK_WINDOW_TEMP)
1375 start_window = get_root (window);
1378 _gdk_x11_window_tmp_unset_bg (start_window, TRUE);
1382 post_unmap (GdkWindow *window)
1384 GdkWindow *start_window = NULL;
1385 GdkWindowObject *private = (GdkWindowObject *)window;
1387 if (private->input_only)
1390 if (private->window_type == GDK_WINDOW_CHILD)
1391 start_window = _gdk_window_get_impl_window ((GdkWindow *)private->parent);
1392 else if (private->window_type == GDK_WINDOW_TEMP)
1393 start_window = get_root (window);
1397 _gdk_x11_window_tmp_reset_bg (start_window, TRUE);
1399 if (private->window_type == GDK_WINDOW_CHILD && private->parent)
1401 GdkRectangle invalid_rect;
1403 gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
1404 gdk_drawable_get_size (GDK_DRAWABLE (window),
1405 &invalid_rect.width, &invalid_rect.height);
1406 gdk_window_invalidate_rect ((GdkWindow *)private->parent,
1407 &invalid_rect, TRUE);
1413 gdk_window_x11_hide (GdkWindow *window)
1415 GdkWindowObject *private;
1417 private = (GdkWindowObject*) window;
1419 /* We'll get the unmap notify eventually, and handle it then,
1420 * but checking here makes things more consistent if we are
1421 * just doing stuff ourself.
1423 _gdk_xgrab_check_unmap (window,
1424 NextRequest (GDK_WINDOW_XDISPLAY (window)));
1426 /* You can't simply unmap toplevel windows. */
1427 switch (private->window_type)
1429 case GDK_WINDOW_TOPLEVEL:
1430 case GDK_WINDOW_DIALOG:
1431 case GDK_WINDOW_TEMP: /* ? */
1432 gdk_window_withdraw (window);
1435 case GDK_WINDOW_FOREIGN:
1436 case GDK_WINDOW_ROOT:
1437 case GDK_WINDOW_CHILD:
1441 _gdk_window_clear_update_area (window);
1444 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
1445 GDK_WINDOW_XID (window));
1446 post_unmap (window);
1450 gdk_window_x11_withdraw (GdkWindow *window)
1452 GdkWindowObject *private;
1454 private = (GdkWindowObject*) window;
1455 if (!private->destroyed)
1457 if (GDK_WINDOW_IS_MAPPED (window))
1458 gdk_synthesize_window_state (window,
1460 GDK_WINDOW_STATE_WITHDRAWN);
1462 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1466 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
1467 GDK_WINDOW_XID (window), 0);
1469 post_unmap (window);
1474 window_x11_move (GdkWindow *window,
1478 GdkWindowObject *private = (GdkWindowObject *) window;
1479 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1481 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1483 _gdk_window_move_resize_child (window,
1485 private->width, private->height);
1489 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
1490 GDK_WINDOW_XID (window),
1493 if (impl->override_redirect)
1502 window_x11_resize (GdkWindow *window,
1506 GdkWindowObject *private = (GdkWindowObject *) window;
1514 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1516 _gdk_window_move_resize_child (window,
1517 private->x, private->y,
1522 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1524 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
1525 GDK_WINDOW_XID (window),
1528 if (impl->override_redirect)
1530 private->width = width;
1531 private->height = height;
1532 _gdk_x11_drawable_update_size (private->impl);
1536 if (width != private->width || height != private->height)
1537 private->resize_count += 1;
1541 _gdk_x11_drawable_update_size (private->impl);
1545 window_x11_move_resize (GdkWindow *window,
1551 GdkWindowObject *private = (GdkWindowObject *) window;;
1559 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1561 _gdk_window_move_resize_child (window, x, y, width, height);
1562 _gdk_x11_drawable_update_size (private->impl);
1566 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1568 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
1569 GDK_WINDOW_XID (window),
1570 x, y, width, height);
1572 if (impl->override_redirect)
1577 private->width = width;
1578 private->height = height;
1580 _gdk_x11_drawable_update_size (private->impl);
1584 if (width != private->width || height != private->height)
1585 private->resize_count += 1;
1591 gdk_window_x11_move_resize (GdkWindow *window,
1598 if (with_move && (width < 0 && height < 0))
1599 window_x11_move (window, x, y);
1603 window_x11_move_resize (window, x, y, width, height);
1605 window_x11_resize (window, width, height);
1610 gdk_window_x11_reparent (GdkWindow *window,
1611 GdkWindow *new_parent,
1615 GdkWindowObject *window_private;
1616 GdkWindowObject *parent_private;
1617 GdkWindowImplX11 *impl;
1619 window_private = (GdkWindowObject*) window;
1620 parent_private = (GdkWindowObject*) new_parent;
1621 impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
1623 _gdk_x11_window_tmp_unset_bg (window, TRUE);
1624 _gdk_x11_window_tmp_unset_parent_bg (window);
1625 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1626 GDK_WINDOW_XID (window),
1627 GDK_WINDOW_XID (new_parent),
1628 parent_private->abs_x + x, parent_private->abs_y + y);
1629 _gdk_x11_window_tmp_reset_parent_bg (window);
1630 _gdk_x11_window_tmp_reset_bg (window, TRUE);
1632 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1633 new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1635 window_private->parent = parent_private;
1637 /* Switch the window type as appropriate */
1639 switch (GDK_WINDOW_TYPE (new_parent))
1641 case GDK_WINDOW_ROOT:
1642 case GDK_WINDOW_FOREIGN:
1643 /* Reparenting to toplevel */
1645 if (!WINDOW_IS_TOPLEVEL (window) &&
1646 GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1648 /* This is also done in common code at a later stage, but we
1649 need it in setup_toplevel, so do it here too */
1650 if (window_private->toplevel_window_type != -1)
1651 GDK_WINDOW_TYPE (window) = window_private->toplevel_window_type;
1652 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1653 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1655 /* Wasn't a toplevel, set up */
1656 setup_toplevel_window (window, new_parent);
1661 case GDK_WINDOW_TOPLEVEL:
1662 case GDK_WINDOW_CHILD:
1663 case GDK_WINDOW_DIALOG:
1664 case GDK_WINDOW_TEMP:
1665 if (WINDOW_IS_TOPLEVEL (window) &&
1668 if (impl->toplevel->focus_window)
1670 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window);
1671 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
1674 gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window),
1676 g_free (impl->toplevel);
1677 impl->toplevel = NULL;
1685 gdk_window_x11_clear_region (GdkWindow *window,
1686 cairo_region_t *region,
1687 gboolean send_expose)
1689 cairo_rectangle_int_t rect;
1692 n_rects = cairo_region_num_rectangles (region);
1694 for (i = 0; i < n_rects; i++)
1696 cairo_region_get_rectangle (region, i, &rect);
1697 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1699 rect.width, rect.height,
1705 gdk_window_x11_raise (GdkWindow *window)
1707 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1711 gdk_window_x11_restack_under (GdkWindow *window,
1712 GList *native_siblings /* in requested order, first is bottom-most */)
1718 n_windows = g_list_length (native_siblings) + 1;
1719 windows = g_new (Window, n_windows);
1721 windows[0] = GDK_WINDOW_XID (window);
1722 /* Reverse order, as input order is bottom-most first */
1724 for (l = native_siblings; l != NULL; l = l->next)
1725 windows[i--] = GDK_WINDOW_XID (l->data);
1727 XRestackWindows (GDK_WINDOW_XDISPLAY (window), windows, n_windows);
1733 gdk_window_x11_restack_toplevel (GdkWindow *window,
1737 XWindowChanges changes;
1739 changes.sibling = GDK_WINDOW_XID (sibling);
1740 changes.stack_mode = above ? Above : Below;
1741 XReconfigureWMWindow (GDK_WINDOW_XDISPLAY (window),
1742 GDK_WINDOW_XID (window),
1743 gdk_screen_get_number (GDK_WINDOW_SCREEN (window)),
1744 CWStackMode | CWSibling, &changes);
1748 gdk_window_x11_lower (GdkWindow *window)
1750 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1754 * gdk_x11_window_move_to_current_desktop:
1755 * @window: a #GdkWindow
1757 * Moves the window to the correct workspace when running under a
1758 * window manager that supports multiple workspaces, as described
1759 * in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
1760 * Window Manager Hints</ulink>. Will not do anything if the
1761 * window is already on all workspaces.
1766 gdk_x11_window_move_to_current_desktop (GdkWindow *window)
1768 GdkToplevelX11 *toplevel;
1770 g_return_if_fail (GDK_IS_WINDOW (window));
1771 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1773 toplevel = _gdk_x11_window_get_toplevel (window);
1775 if (toplevel->on_all_desktops)
1778 move_to_current_desktop (window);
1782 move_to_current_desktop (GdkWindow *window)
1784 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
1785 gdk_atom_intern_static_string ("_NET_WM_DESKTOP")))
1792 gulong *current_desktop;
1793 GdkDisplay *display;
1795 display = gdk_drawable_get_display (window);
1797 /* Get current desktop, then set it; this is a race, but not
1798 * one that matters much in practice.
1800 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
1801 GDK_WINDOW_XROOTWIN (window),
1802 gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
1804 False, XA_CARDINAL, &type, &format, &nitems,
1805 &bytes_after, &data);
1807 if (type == XA_CARDINAL)
1809 XClientMessageEvent xclient;
1810 current_desktop = (gulong *)data;
1812 memset (&xclient, 0, sizeof (xclient));
1813 xclient.type = ClientMessage;
1815 xclient.send_event = True;
1816 xclient.window = GDK_WINDOW_XWINDOW (window);
1817 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
1818 xclient.format = 32;
1820 xclient.data.l[0] = *current_desktop;
1821 xclient.data.l[1] = 0;
1822 xclient.data.l[2] = 0;
1823 xclient.data.l[3] = 0;
1824 xclient.data.l[4] = 0;
1826 XSendEvent (GDK_DISPLAY_XDISPLAY (display),
1827 GDK_WINDOW_XROOTWIN (window),
1829 SubstructureRedirectMask | SubstructureNotifyMask,
1830 (XEvent *)&xclient);
1832 XFree (current_desktop);
1839 * @window: a #GdkWindow
1840 * @timestamp: timestamp of the event triggering the window focus
1842 * Sets keyboard focus to @window. In most cases, gtk_window_present()
1843 * should be used on a #GtkWindow, rather than calling this function.
1847 gdk_window_focus (GdkWindow *window,
1850 GdkDisplay *display;
1852 g_return_if_fail (GDK_IS_WINDOW (window));
1854 if (GDK_WINDOW_DESTROYED (window) ||
1855 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1858 display = GDK_WINDOW_DISPLAY (window);
1860 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
1861 gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
1863 XClientMessageEvent xclient;
1865 memset (&xclient, 0, sizeof (xclient));
1866 xclient.type = ClientMessage;
1867 xclient.window = GDK_WINDOW_XWINDOW (window);
1868 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
1869 "_NET_ACTIVE_WINDOW");
1870 xclient.format = 32;
1871 xclient.data.l[0] = 1; /* requestor type; we're an app */
1872 xclient.data.l[1] = timestamp;
1873 xclient.data.l[2] = None; /* currently active window */
1874 xclient.data.l[3] = 0;
1875 xclient.data.l[4] = 0;
1877 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
1878 SubstructureRedirectMask | SubstructureNotifyMask,
1879 (XEvent *)&xclient);
1883 XRaiseWindow (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window));
1885 /* There is no way of knowing reliably whether we are viewable;
1886 * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
1888 _gdk_x11_set_input_focus_safe (display, GDK_WINDOW_XID (window),
1895 * gdk_window_set_type_hint:
1896 * @window: A toplevel #GdkWindow
1897 * @hint: A hint of the function this window will have
1899 * The application can use this call to provide a hint to the window
1900 * manager about the functionality of a window. The window manager
1901 * can use this information when determining the decoration and behaviour
1904 * The hint must be set before the window is mapped.
1907 gdk_window_set_type_hint (GdkWindow *window,
1908 GdkWindowTypeHint hint)
1910 GdkDisplay *display;
1913 if (GDK_WINDOW_DESTROYED (window) ||
1914 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1917 display = gdk_drawable_get_display (window);
1921 case GDK_WINDOW_TYPE_HINT_DIALOG:
1922 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
1924 case GDK_WINDOW_TYPE_HINT_MENU:
1925 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU");
1927 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1928 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR");
1930 case GDK_WINDOW_TYPE_HINT_UTILITY:
1931 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
1933 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1934 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
1936 case GDK_WINDOW_TYPE_HINT_DOCK:
1937 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
1939 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1940 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
1942 case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
1943 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
1945 case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
1946 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
1948 case GDK_WINDOW_TYPE_HINT_TOOLTIP:
1949 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
1951 case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
1952 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
1954 case GDK_WINDOW_TYPE_HINT_COMBO:
1955 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
1957 case GDK_WINDOW_TYPE_HINT_DND:
1958 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
1961 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
1963 case GDK_WINDOW_TYPE_HINT_NORMAL:
1964 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL");
1968 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
1969 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
1970 XA_ATOM, 32, PropModeReplace,
1971 (guchar *)&atom, 1);
1975 * gdk_window_get_type_hint:
1976 * @window: A toplevel #GdkWindow
1978 * This function returns the type hint set for a window.
1980 * Return value: The type hint set for @window
1985 gdk_window_get_type_hint (GdkWindow *window)
1987 GdkDisplay *display;
1988 GdkWindowTypeHint type;
1991 gulong nitems_return;
1992 gulong bytes_after_return;
1993 guchar *data = NULL;
1995 g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
1997 if (GDK_WINDOW_DESTROYED (window) ||
1998 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
1999 return GDK_WINDOW_TYPE_HINT_NORMAL;
2001 type = GDK_WINDOW_TYPE_HINT_NORMAL;
2003 display = gdk_drawable_get_display (window);
2005 if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2006 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
2007 0, G_MAXLONG, False, XA_ATOM, &type_return,
2008 &format_return, &nitems_return, &bytes_after_return,
2011 if ((type_return == XA_ATOM) && (format_return == 32) &&
2012 (data) && (nitems_return == 1))
2014 Atom atom = *(Atom*)data;
2016 if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG"))
2017 type = GDK_WINDOW_TYPE_HINT_DIALOG;
2018 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU"))
2019 type = GDK_WINDOW_TYPE_HINT_MENU;
2020 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR"))
2021 type = GDK_WINDOW_TYPE_HINT_TOOLBAR;
2022 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY"))
2023 type = GDK_WINDOW_TYPE_HINT_UTILITY;
2024 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH"))
2025 type = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN;
2026 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK"))
2027 type = GDK_WINDOW_TYPE_HINT_DOCK;
2028 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
2029 type = GDK_WINDOW_TYPE_HINT_DESKTOP;
2030 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
2031 type = GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
2032 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
2033 type = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
2034 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
2035 type = GDK_WINDOW_TYPE_HINT_TOOLTIP;
2036 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
2037 type = GDK_WINDOW_TYPE_HINT_NOTIFICATION;
2038 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
2039 type = GDK_WINDOW_TYPE_HINT_COMBO;
2040 else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
2041 type = GDK_WINDOW_TYPE_HINT_DND;
2044 if (type_return != None && data != NULL)
2052 gdk_wmspec_change_state (gboolean add,
2057 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
2058 XClientMessageEvent xclient;
2060 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
2061 #define _NET_WM_STATE_ADD 1 /* add/set property */
2062 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
2064 memset (&xclient, 0, sizeof (xclient));
2065 xclient.type = ClientMessage;
2066 xclient.window = GDK_WINDOW_XID (window);
2067 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
2068 xclient.format = 32;
2069 xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
2070 xclient.data.l[1] = gdk_x11_atom_to_xatom_for_display (display, state1);
2071 xclient.data.l[2] = gdk_x11_atom_to_xatom_for_display (display, state2);
2072 xclient.data.l[3] = 0;
2073 xclient.data.l[4] = 0;
2075 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
2076 SubstructureRedirectMask | SubstructureNotifyMask,
2077 (XEvent *)&xclient);
2081 * gdk_window_set_modal_hint:
2082 * @window: A toplevel #GdkWindow
2083 * @modal: %TRUE if the window is modal, %FALSE otherwise.
2085 * The application can use this hint to tell the window manager
2086 * that a certain window has modal behaviour. The window manager
2087 * can use this information to handle modal windows in a special
2090 * You should only use this on windows for which you have
2091 * previously called gdk_window_set_transient_for()
2094 gdk_window_set_modal_hint (GdkWindow *window,
2097 GdkWindowObject *private;
2099 if (GDK_WINDOW_DESTROYED (window) ||
2100 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2103 private = (GdkWindowObject*) window;
2105 private->modal_hint = modal;
2107 if (GDK_WINDOW_IS_MAPPED (window))
2108 gdk_wmspec_change_state (modal, window,
2109 gdk_atom_intern_static_string ("_NET_WM_STATE_MODAL"),
2114 * gdk_window_set_skip_taskbar_hint:
2115 * @window: a toplevel #GdkWindow
2116 * @skips_taskbar: %TRUE to skip the taskbar
2118 * Toggles whether a window should appear in a task list or window
2119 * list. If a window's semantic type as specified with
2120 * gdk_window_set_type_hint() already fully describes the window, this
2121 * function should <emphasis>not</emphasis> be called in addition,
2122 * instead you should allow the window to be treated according to
2123 * standard policy for its semantic type.
2128 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2129 gboolean skips_taskbar)
2131 GdkToplevelX11 *toplevel;
2133 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2135 if (GDK_WINDOW_DESTROYED (window) ||
2136 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2139 toplevel = _gdk_x11_window_get_toplevel (window);
2140 toplevel->skip_taskbar_hint = skips_taskbar;
2142 if (GDK_WINDOW_IS_MAPPED (window))
2143 gdk_wmspec_change_state (skips_taskbar, window,
2144 gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_TASKBAR"),
2149 * gdk_window_set_skip_pager_hint:
2150 * @window: a toplevel #GdkWindow
2151 * @skips_pager: %TRUE to skip the pager
2153 * Toggles whether a window should appear in a pager (workspace
2154 * switcher, or other desktop utility program that displays a small
2155 * thumbnail representation of the windows on the desktop). If a
2156 * window's semantic type as specified with gdk_window_set_type_hint()
2157 * already fully describes the window, this function should
2158 * <emphasis>not</emphasis> be called in addition, instead you should
2159 * allow the window to be treated according to standard policy for
2160 * its semantic type.
2165 gdk_window_set_skip_pager_hint (GdkWindow *window,
2166 gboolean skips_pager)
2168 GdkToplevelX11 *toplevel;
2170 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2172 if (GDK_WINDOW_DESTROYED (window) ||
2173 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2176 toplevel = _gdk_x11_window_get_toplevel (window);
2177 toplevel->skip_pager_hint = skips_pager;
2179 if (GDK_WINDOW_IS_MAPPED (window))
2180 gdk_wmspec_change_state (skips_pager, window,
2181 gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_PAGER"),
2186 * gdk_window_set_urgency_hint:
2187 * @window: a toplevel #GdkWindow
2188 * @urgent: %TRUE if the window is urgent
2190 * Toggles whether a window needs the user's
2196 gdk_window_set_urgency_hint (GdkWindow *window,
2199 GdkToplevelX11 *toplevel;
2201 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2203 if (GDK_WINDOW_DESTROYED (window) ||
2204 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2207 toplevel = _gdk_x11_window_get_toplevel (window);
2208 toplevel->urgency_hint = urgent;
2210 update_wm_hints (window, FALSE);
2214 * gdk_window_set_geometry_hints:
2215 * @window: a toplevel #GdkWindow
2216 * @geometry: geometry hints
2217 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
2219 * Sets the geometry hints for @window. Hints flagged in @geom_mask
2220 * are set, hints not flagged in @geom_mask are unset.
2221 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
2223 * This function provides hints to the windowing system about
2224 * acceptable sizes for a toplevel window. The purpose of
2225 * this is to constrain user resizing, but the windowing system
2226 * will typically (but is not required to) also constrain the
2227 * current size of the window to the provided values and
2228 * constrain programatic resizing via gdk_window_resize() or
2229 * gdk_window_move_resize().
2231 * Note that on X11, this effect has no effect on windows
2232 * of type %GDK_WINDOW_TEMP or windows where override redirect
2233 * has been turned on via gdk_window_set_override_redirect()
2234 * since these windows are not resizable by the user.
2236 * Since you can't count on the windowing system doing the
2237 * constraints for programmatic resizes, you should generally
2238 * call gdk_window_constrain_size() yourself to determine
2239 * appropriate sizes.
2243 gdk_window_set_geometry_hints (GdkWindow *window,
2244 const GdkGeometry *geometry,
2245 GdkWindowHints geom_mask)
2247 XSizeHints size_hints;
2249 if (GDK_WINDOW_DESTROYED (window) ||
2250 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2253 size_hints.flags = 0;
2255 if (geom_mask & GDK_HINT_POS)
2257 size_hints.flags |= PPosition;
2258 /* We need to initialize the following obsolete fields because KWM
2259 * apparently uses these fields if they are non-zero.
2266 if (geom_mask & GDK_HINT_USER_POS)
2268 size_hints.flags |= USPosition;
2271 if (geom_mask & GDK_HINT_USER_SIZE)
2273 size_hints.flags |= USSize;
2276 if (geom_mask & GDK_HINT_MIN_SIZE)
2278 size_hints.flags |= PMinSize;
2279 size_hints.min_width = geometry->min_width;
2280 size_hints.min_height = geometry->min_height;
2283 if (geom_mask & GDK_HINT_MAX_SIZE)
2285 size_hints.flags |= PMaxSize;
2286 size_hints.max_width = MAX (geometry->max_width, 1);
2287 size_hints.max_height = MAX (geometry->max_height, 1);
2290 if (geom_mask & GDK_HINT_BASE_SIZE)
2292 size_hints.flags |= PBaseSize;
2293 size_hints.base_width = geometry->base_width;
2294 size_hints.base_height = geometry->base_height;
2297 if (geom_mask & GDK_HINT_RESIZE_INC)
2299 size_hints.flags |= PResizeInc;
2300 size_hints.width_inc = geometry->width_inc;
2301 size_hints.height_inc = geometry->height_inc;
2304 if (geom_mask & GDK_HINT_ASPECT)
2306 size_hints.flags |= PAspect;
2307 if (geometry->min_aspect <= 1)
2309 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
2310 size_hints.min_aspect.y = 65536;
2314 size_hints.min_aspect.x = 65536;
2315 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
2317 if (geometry->max_aspect <= 1)
2319 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
2320 size_hints.max_aspect.y = 65536;
2324 size_hints.max_aspect.x = 65536;
2325 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
2329 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2331 size_hints.flags |= PWinGravity;
2332 size_hints.win_gravity = geometry->win_gravity;
2335 /* FIXME: Would it be better to delete this property if
2336 * geom_mask == 0? It would save space on the server
2338 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2339 GDK_WINDOW_XID (window),
2344 gdk_window_get_geometry_hints (GdkWindow *window,
2345 GdkGeometry *geometry,
2346 GdkWindowHints *geom_mask)
2348 XSizeHints *size_hints;
2349 glong junk_supplied_mask = 0;
2351 g_return_if_fail (GDK_IS_WINDOW (window));
2352 g_return_if_fail (geometry != NULL);
2353 g_return_if_fail (geom_mask != NULL);
2357 if (GDK_WINDOW_DESTROYED (window) ||
2358 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2361 size_hints = XAllocSizeHints ();
2365 if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2366 GDK_WINDOW_XID (window),
2368 &junk_supplied_mask))
2369 size_hints->flags = 0;
2371 if (size_hints->flags & PMinSize)
2373 *geom_mask |= GDK_HINT_MIN_SIZE;
2374 geometry->min_width = size_hints->min_width;
2375 geometry->min_height = size_hints->min_height;
2378 if (size_hints->flags & PMaxSize)
2380 *geom_mask |= GDK_HINT_MAX_SIZE;
2381 geometry->max_width = MAX (size_hints->max_width, 1);
2382 geometry->max_height = MAX (size_hints->max_height, 1);
2385 if (size_hints->flags & PResizeInc)
2387 *geom_mask |= GDK_HINT_RESIZE_INC;
2388 geometry->width_inc = size_hints->width_inc;
2389 geometry->height_inc = size_hints->height_inc;
2392 if (size_hints->flags & PAspect)
2394 *geom_mask |= GDK_HINT_ASPECT;
2396 geometry->min_aspect = (gdouble) size_hints->min_aspect.x / (gdouble) size_hints->min_aspect.y;
2397 geometry->max_aspect = (gdouble) size_hints->max_aspect.x / (gdouble) size_hints->max_aspect.y;
2400 if (size_hints->flags & PWinGravity)
2402 *geom_mask |= GDK_HINT_WIN_GRAVITY;
2403 geometry->win_gravity = size_hints->win_gravity;
2410 utf8_is_latin1 (const gchar *str)
2412 const char *p = str;
2416 gunichar ch = g_utf8_get_char (p);
2421 p = g_utf8_next_char (p);
2427 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
2428 * convertable to STRING, otherwise, set it as compound text
2431 set_text_property (GdkDisplay *display,
2434 const gchar *utf8_str)
2436 gchar *prop_text = NULL;
2440 gboolean is_compound_text;
2442 if (utf8_is_latin1 (utf8_str))
2444 prop_type = XA_STRING;
2445 prop_text = gdk_utf8_to_string_target (utf8_str);
2446 prop_length = prop_text ? strlen (prop_text) : 0;
2448 is_compound_text = FALSE;
2454 gdk_utf8_to_compound_text_for_display (display,
2455 utf8_str, &gdk_type, &prop_format,
2456 (guchar **)&prop_text, &prop_length);
2457 prop_type = gdk_x11_atom_to_xatom_for_display (display, gdk_type);
2458 is_compound_text = TRUE;
2463 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
2466 prop_type, prop_format,
2467 PropModeReplace, (guchar *)prop_text,
2470 if (is_compound_text)
2471 gdk_free_compound_text ((guchar *)prop_text);
2477 /* Set WM_NAME and _NET_WM_NAME
2480 set_wm_name (GdkDisplay *display,
2484 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
2485 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
2486 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2487 PropModeReplace, (guchar *)name, strlen (name));
2489 set_text_property (display, xwindow,
2490 gdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"),
2495 * gdk_window_set_title:
2496 * @window: a toplevel #GdkWindow
2497 * @title: title of @window
2499 * Sets the title of a toplevel window, to be displayed in the titlebar.
2500 * If you haven't explicitly set the icon name for the window
2501 * (using gdk_window_set_icon_name()), the icon name will be set to
2502 * @title as well. @title must be in UTF-8 encoding (as with all
2503 * user-readable strings in GDK/GTK+). @title may not be %NULL.
2506 gdk_window_set_title (GdkWindow *window,
2509 GdkDisplay *display;
2513 g_return_if_fail (title != NULL);
2515 if (GDK_WINDOW_DESTROYED (window) ||
2516 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2519 display = gdk_drawable_get_display (window);
2520 xdisplay = GDK_DISPLAY_XDISPLAY (display);
2521 xwindow = GDK_WINDOW_XID (window);
2523 set_wm_name (display, xwindow, title);
2525 if (!gdk_window_icon_name_set (window))
2527 XChangeProperty (xdisplay, xwindow,
2528 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
2529 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2530 PropModeReplace, (guchar *)title, strlen (title));
2532 set_text_property (display, xwindow,
2533 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
2539 * gdk_window_set_role:
2540 * @window: a toplevel #GdkWindow
2541 * @role: a string indicating its role
2543 * When using GTK+, typically you should use gtk_window_set_role() instead
2544 * of this low-level function.
2546 * The window manager and session manager use a window's role to
2547 * distinguish it from other kinds of window in the same application.
2548 * When an application is restarted after being saved in a previous
2549 * session, all windows with the same title and role are treated as
2550 * interchangeable. So if you have two windows with the same title
2551 * that should be distinguished for session management purposes, you
2552 * should set the role on those windows. It doesn't matter what string
2553 * you use for the role, as long as you have a different role for each
2554 * non-interchangeable kind of window.
2558 gdk_window_set_role (GdkWindow *window,
2561 GdkDisplay *display;
2563 display = gdk_drawable_get_display (window);
2565 if (GDK_WINDOW_DESTROYED (window) ||
2566 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2570 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2571 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
2572 XA_STRING, 8, PropModeReplace, (guchar *)role, strlen (role));
2574 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2575 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
2579 * gdk_window_set_startup_id:
2580 * @window: a toplevel #GdkWindow
2581 * @startup_id: a string with startup-notification identifier
2583 * When using GTK+, typically you should use gtk_window_set_startup_id()
2584 * instead of this low-level function.
2590 gdk_window_set_startup_id (GdkWindow *window,
2591 const gchar *startup_id)
2593 GdkDisplay *display;
2595 g_return_if_fail (GDK_IS_WINDOW (window));
2597 display = gdk_drawable_get_display (window);
2599 if (GDK_WINDOW_DESTROYED (window) ||
2600 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2604 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2605 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"),
2606 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2607 PropModeReplace, (unsigned char *)startup_id, strlen (startup_id));
2609 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2610 gdk_x11_get_xatom_by_name_for_display (display, "_NET_STARTUP_ID"));
2614 * gdk_window_set_transient_for:
2615 * @window: a toplevel #GdkWindow
2616 * @parent: another toplevel #GdkWindow
2618 * Indicates to the window manager that @window is a transient dialog
2619 * associated with the application window @parent. This allows the
2620 * window manager to do things like center @window on @parent and
2621 * keep @window above @parent.
2623 * See gtk_window_set_transient_for() if you're using #GtkWindow or
2627 gdk_window_set_transient_for (GdkWindow *window,
2630 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent) &&
2631 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
2632 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
2633 GDK_WINDOW_XID (window),
2634 GDK_WINDOW_XID (parent));
2638 gdk_window_x11_set_background (GdkWindow *window,
2639 const GdkColor *color)
2641 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
2642 GDK_WINDOW_XID (window), color->pixel);
2646 gdk_window_x11_set_back_pixmap (GdkWindow *window,
2651 if (pixmap == GDK_PARENT_RELATIVE_BG)
2652 xpixmap = ParentRelative;
2653 else if (pixmap == GDK_NO_BG)
2656 xpixmap = GDK_PIXMAP_XID (pixmap);
2658 if (!GDK_WINDOW_DESTROYED (window))
2659 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2660 GDK_WINDOW_XID (window), xpixmap);
2664 gdk_window_x11_set_device_cursor (GdkWindow *window,
2668 GdkWindowObject *private;
2669 GdkWindowImplX11 *impl;
2671 g_return_if_fail (GDK_IS_WINDOW (window));
2672 g_return_if_fail (GDK_IS_DEVICE (device));
2674 private = (GdkWindowObject *) window;
2675 impl = GDK_WINDOW_IMPL_X11 (private->impl);
2678 g_hash_table_remove (impl->device_cursor, device);
2681 _gdk_x11_cursor_update_theme (cursor);
2682 g_hash_table_replace (impl->device_cursor,
2683 device, gdk_cursor_ref (cursor));
2686 if (!GDK_WINDOW_DESTROYED (window))
2687 GDK_DEVICE_GET_CLASS (device)->set_window_cursor (device, window, cursor);
2691 _gdk_x11_window_get_cursor (GdkWindow *window)
2693 GdkWindowObject *private;
2694 GdkWindowImplX11 *impl;
2696 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
2698 private = (GdkWindowObject *)window;
2699 impl = GDK_WINDOW_IMPL_X11 (private->impl);
2701 return impl->cursor;
2705 gdk_window_x11_get_geometry (GdkWindow *window,
2717 guint tborder_width;
2720 if (!GDK_WINDOW_DESTROYED (window))
2722 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
2723 GDK_WINDOW_XID (window),
2724 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
2740 gdk_window_x11_get_root_coords (GdkWindow *window,
2751 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2752 GDK_WINDOW_XID (window),
2753 GDK_WINDOW_XROOTWIN (window),
2766 gdk_window_x11_get_deskrelative_origin (GdkWindow *window,
2770 gboolean return_val = FALSE;
2771 gint num_children, format_return;
2772 Window win, *child, parent, root;
2775 gulong number_return, bytes_after_return;
2776 guchar *data_return;
2778 atom = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
2779 "ENLIGHTENMENT_DESKTOP");
2780 win = GDK_WINDOW_XID (window);
2782 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
2783 &child, (unsigned int *)&num_children))
2785 if ((child) && (num_children > 0))
2797 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
2798 False, XA_CARDINAL, &type_return, &format_return,
2799 &number_return, &bytes_after_return, &data_return);
2801 if (type_return == XA_CARDINAL)
2803 XFree (data_return);
2808 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2809 GDK_WINDOW_XID (window),
2818 * gdk_window_get_root_origin:
2819 * @window: a toplevel #GdkWindow
2820 * @x: return location for X position of window frame
2821 * @y: return location for Y position of window frame
2823 * Obtains the top-left corner of the window manager frame in root
2824 * window coordinates.
2828 gdk_window_get_root_origin (GdkWindow *window,
2834 gdk_window_get_frame_extents (window, &rect);
2844 * gdk_window_get_frame_extents:
2845 * @window: a toplevel #GdkWindow
2846 * @rect: rectangle to fill with bounding box of the window frame
2848 * Obtains the bounding box of the window, including window manager
2849 * titlebar/borders if any. The frame position is given in root window
2850 * coordinates. To get the position of the window itself (rather than
2851 * the frame) in root window coordinates, use gdk_window_get_origin().
2855 gdk_window_get_frame_extents (GdkWindow *window,
2858 GdkDisplay *display;
2859 GdkWindowObject *private;
2860 GdkWindowImplX11 *impl;
2871 gulong nitems_return;
2872 gulong bytes_after_return;
2875 guint ww, wh, wb, wd;
2877 gboolean got_frame_extents = FALSE;
2879 g_return_if_fail (rect != NULL);
2881 private = (GdkWindowObject*) window;
2888 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2889 private = (GdkWindowObject*) private->parent;
2891 /* Refine our fallback answer a bit using local information */
2892 rect->x = private->x;
2893 rect->y = private->y;
2894 gdk_drawable_get_size ((GdkDrawable *)private, &rect->width, &rect->height);
2896 impl = GDK_WINDOW_IMPL_X11 (private->impl);
2897 if (GDK_WINDOW_DESTROYED (private) || impl->override_redirect)
2903 gdk_error_trap_push();
2905 display = gdk_drawable_get_display (window);
2906 xwindow = GDK_WINDOW_XID (window);
2908 /* first try: use _NET_FRAME_EXTENTS */
2909 if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
2910 gdk_x11_get_xatom_by_name_for_display (display,
2911 "_NET_FRAME_EXTENTS"),
2912 0, G_MAXLONG, False, XA_CARDINAL, &type_return,
2913 &format_return, &nitems_return, &bytes_after_return,
2917 if ((type_return == XA_CARDINAL) && (format_return == 32) &&
2918 (nitems_return == 4) && (data))
2920 gulong *ldata = (gulong *) data;
2921 got_frame_extents = TRUE;
2923 /* try to get the real client window geometry */
2924 if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow,
2925 &root, &wx, &wy, &ww, &wh, &wb, &wd) &&
2926 XTranslateCoordinates (GDK_DISPLAY_XDISPLAY (display),
2927 xwindow, root, 0, 0, &wx, &wy, &child))
2935 /* _NET_FRAME_EXTENTS format is left, right, top, bottom */
2936 rect->x -= ldata[0];
2937 rect->y -= ldata[2];
2938 rect->width += ldata[0] + ldata[1];
2939 rect->height += ldata[2] + ldata[3];
2946 if (got_frame_extents)
2949 /* no frame extents property available, which means we either have a WM that
2950 is not EWMH compliant or is broken - try fallback and walk up the window
2951 tree to get our window's parent which hopefully is the window frame */
2953 /* use NETWM_VIRTUAL_ROOTS if available */
2954 root = GDK_WINDOW_XROOTWIN (window);
2956 if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), root,
2957 gdk_x11_get_xatom_by_name_for_display (display,
2958 "_NET_VIRTUAL_ROOTS"),
2959 0, G_MAXLONG, False, XA_WINDOW, &type_return,
2960 &format_return, &nitems_return, &bytes_after_return,
2964 if ((type_return == XA_WINDOW) && (format_return == 32) && (data))
2966 nvroots = nitems_return;
2967 vroots = (Window *)data;
2971 xparent = GDK_WINDOW_XID (window);
2977 if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xwindow,
2979 &children, &nchildren))
2985 /* check virtual roots */
2986 for (i = 0; i < nvroots; i++)
2988 if (xparent == vroots[i])
2995 while (xparent != root);
2997 if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow,
2998 &root, &wx, &wy, &ww, &wh, &wb, &wd))
3010 gdk_error_trap_pop ();
3014 _gdk_windowing_get_device_state (GdkDisplay *display,
3019 GdkModifierType *mask)
3021 GdkScreen *default_screen;
3023 if (display->closed)
3026 default_screen = gdk_display_get_default_screen (display);
3029 if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
3033 GDK_DEVICE_GET_CLASS (device)->query_state (device,
3034 gdk_screen_get_root_window (default_screen),
3039 *screen = gdk_drawable_get_screen (root);
3043 XSetWindowAttributes attributes;
3045 Window xwindow, w, root, child;
3046 int rootx, rooty, winx, winy;
3049 /* FIXME: untrusted clients not multidevice-safe */
3051 xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
3052 xwindow = GDK_SCREEN_XROOTWIN (default_screen);
3054 w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
3055 CopyFromParent, InputOnly, CopyFromParent,
3057 XQueryPointer (xdisplay, w,
3058 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3059 XDestroyWindow (xdisplay, w);
3063 GdkWindow *gdk_root = gdk_window_lookup_for_display (display, root);
3064 *screen = gdk_drawable_get_screen (gdk_root);
3074 gdk_window_x11_get_device_state (GdkWindow *window,
3078 GdkModifierType *mask)
3080 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
3081 gboolean return_val;
3083 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), FALSE);
3087 if (!GDK_WINDOW_DESTROYED (window))
3089 if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
3093 GDK_DEVICE_GET_CLASS (device)->query_state (device, window,
3097 return_val = (child != NULL);
3102 int originx, originy;
3106 unsigned int xmask = 0;
3108 _gdk_windowing_get_device_state (gdk_drawable_get_display (window), device,
3109 &screen, &rootx, &rooty, &xmask);
3110 gdk_window_get_origin (window, &originx, &originy);
3111 winx = rootx - originx;
3112 winy = rooty - originy;
3124 * gdk_display_warp_pointer:
3125 * @display: a #GdkDisplay
3126 * @screen: the screen of @display to warp the pointer to
3127 * @x: the x coordinate of the destination
3128 * @y: the y coordinate of the destination
3130 * Warps the pointer of @display to the point @x,@y on
3131 * the screen @screen, unless the pointer is confined
3132 * to a window by a grab, in which case it will be moved
3133 * as far as allowed by the grab. Warping the pointer
3134 * creates events as if the user had moved the mouse
3135 * instantaneously to the destination.
3137 * Note that the pointer should normally be under the
3138 * control of the user. This function was added to cover
3139 * some rare use cases like keyboard navigation support
3140 * for the color picker in the #GtkColorSelectionDialog.
3144 * Deprecated: 3.0: Use gdk_display_warp_device() instead.
3147 gdk_display_warp_pointer (GdkDisplay *display,
3154 g_return_if_fail (GDK_IS_DISPLAY (display));
3155 g_return_if_fail (GDK_IS_SCREEN (screen));
3157 device = display->core_pointer;
3158 GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
3162 * gdk_display_warp_device:
3163 * @display: a #GdkDisplay.
3164 * @device: a #GdkDevice.
3165 * @screen: the screen of @display to warp @device to.
3166 * @x: the X coordinate of the destination.
3167 * @y: the Y coordinate of the destination.
3169 * Warps @device in @display to the point @x,@y on
3170 * the screen @screen, unless the device is confined
3171 * to a window by a grab, in which case it will be moved
3172 * as far as allowed by the grab. Warping the pointer
3173 * creates events as if the user had moved the mouse
3174 * instantaneously to the destination.
3176 * Note that the pointer should normally be under the
3177 * control of the user. This function was added to cover
3178 * some rare use cases like keyboard navigation support
3179 * for the color picker in the #GtkColorSelectionDialog.
3184 gdk_display_warp_device (GdkDisplay *display,
3190 g_return_if_fail (GDK_IS_DISPLAY (display));
3191 g_return_if_fail (GDK_IS_DEVICE (device));
3192 g_return_if_fail (GDK_IS_SCREEN (screen));
3193 g_return_if_fail (display == gdk_device_get_display (device));
3195 GDK_DEVICE_GET_CLASS (device)->warp (device, screen, x, y);
3199 _gdk_windowing_window_at_device_position (GdkDisplay *display,
3203 GdkModifierType *mask,
3204 gboolean get_toplevel)
3209 screen = gdk_display_get_default_screen (display);
3211 /* This function really only works if the mouse pointer is held still
3212 * during its operation. If it moves from one leaf window to another
3213 * than we'll end up with inaccurate values for win_x, win_y
3216 gdk_x11_display_grab (display);
3217 if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
3218 window = GDK_DEVICE_GET_CLASS (device)->window_at_position (device, win_x, win_y, mask, get_toplevel);
3221 gint i, screens, width, height;
3222 GList *toplevels, *list;
3223 Window pointer_window, root, xwindow, child;
3224 Window xwindow_last = 0;
3226 int rootx = -1, rooty = -1;
3230 /* FIXME: untrusted clients case not multidevice-safe */
3232 xwindow = GDK_SCREEN_XROOTWIN (screen);
3233 xdisplay = GDK_SCREEN_XDISPLAY (screen);
3235 pointer_window = None;
3236 screens = gdk_display_get_n_screens (display);
3237 for (i = 0; i < screens; ++i) {
3238 screen = gdk_display_get_screen (display, i);
3239 toplevels = gdk_screen_get_toplevel_windows (screen);
3240 for (list = toplevels; list != NULL; list = g_list_next (list)) {
3241 window = GDK_WINDOW (list->data);
3242 xwindow = GDK_WINDOW_XWINDOW (window);
3243 gdk_error_trap_push ();
3244 XQueryPointer (xdisplay, xwindow,
3245 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3247 if (gdk_error_trap_pop ())
3251 pointer_window = child;
3254 gdk_window_get_geometry (window, NULL, NULL, &width, &height, NULL);
3255 if (winx >= 0 && winy >= 0 && winx < width && winy < height)
3257 /* A childless toplevel, or below another window? */
3258 XSetWindowAttributes attributes;
3261 w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
3262 CopyFromParent, InputOnly, CopyFromParent,
3264 XMapWindow (xdisplay, w);
3265 XQueryPointer (xdisplay, xwindow,
3266 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3267 XDestroyWindow (xdisplay, w);
3270 pointer_window = xwindow;
3275 g_list_free (toplevels);
3276 if (pointer_window != None)
3279 xwindow = pointer_window;
3283 xwindow_last = xwindow;
3284 gdk_error_trap_push ();
3285 XQueryPointer (xdisplay, xwindow,
3286 &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
3288 if (gdk_error_trap_pop ())
3290 if (get_toplevel && xwindow_last != root &&
3291 (window = gdk_window_lookup_for_display (display, xwindow_last)) != NULL &&
3292 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
3296 window = gdk_window_lookup_for_display (display, xwindow_last);
3298 *win_x = window ? winx : -1;
3299 *win_y = window ? winy : -1;
3304 gdk_x11_display_ungrab (display);
3310 gdk_window_x11_get_events (GdkWindow *window)
3312 XWindowAttributes attrs;
3313 GdkEventMask event_mask;
3314 GdkEventMask filtered;
3316 if (GDK_WINDOW_DESTROYED (window))
3320 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3321 GDK_WINDOW_XID (window),
3323 event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
3324 /* if property change was filtered out before, keep it filtered out */
3325 filtered = GDK_STRUCTURE_MASK | GDK_PROPERTY_CHANGE_MASK;
3326 GDK_WINDOW_OBJECT (window)->event_mask = event_mask & ((GDK_WINDOW_OBJECT (window)->event_mask & filtered) | ~filtered);
3332 gdk_window_x11_set_events (GdkWindow *window,
3333 GdkEventMask event_mask)
3335 long xevent_mask = 0;
3337 if (!GDK_WINDOW_DESTROYED (window))
3339 GdkDisplayX11 *display_x11;
3341 if (GDK_WINDOW_XID (window) != GDK_WINDOW_XROOTWIN (window))
3342 xevent_mask = StructureNotifyMask | PropertyChangeMask;
3344 display_x11 = GDK_DISPLAY_X11 (gdk_drawable_get_display (window));
3345 gdk_event_source_select_events ((GdkEventSource *) display_x11->event_source,
3346 GDK_WINDOW_XWINDOW (window), event_mask,
3352 gdk_window_add_colormap_windows (GdkWindow *window)
3354 GdkWindow *toplevel;
3355 Window *old_windows;
3356 Window *new_windows;
3359 g_return_if_fail (GDK_IS_WINDOW (window));
3361 if (GDK_WINDOW_DESTROYED (window))
3364 toplevel = gdk_window_get_toplevel (window);
3367 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3368 GDK_WINDOW_XID (toplevel),
3369 &old_windows, &count))
3374 for (i = 0; i < count; i++)
3375 if (old_windows[i] == GDK_WINDOW_XID (window))
3377 XFree (old_windows);
3381 new_windows = g_new (Window, count + 1);
3383 for (i = 0; i < count; i++)
3384 new_windows[i] = old_windows[i];
3385 new_windows[count] = GDK_WINDOW_XID (window);
3387 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3388 GDK_WINDOW_XID (toplevel),
3389 new_windows, count + 1);
3391 g_free (new_windows);
3393 XFree (old_windows);
3397 do_shape_combine_region (GdkWindow *window,
3398 const cairo_region_t *shape_region,
3403 if (GDK_WINDOW_DESTROYED (window))
3406 if (shape_region == NULL)
3408 /* Use NULL mask to unset the shape */
3409 if (shape == ShapeBounding
3410 ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
3411 : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
3413 if (shape == ShapeBounding)
3415 _gdk_x11_window_tmp_unset_parent_bg (window);
3416 _gdk_x11_window_tmp_unset_bg (window, TRUE);
3418 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
3419 GDK_WINDOW_XID (window),
3424 if (shape == ShapeBounding)
3426 _gdk_x11_window_tmp_reset_parent_bg (window);
3427 _gdk_x11_window_tmp_reset_bg (window, TRUE);
3433 if (shape == ShapeBounding
3434 ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
3435 : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
3438 XRectangle *xrects = NULL;
3440 _gdk_region_get_xrectangles (shape_region,
3444 if (shape == ShapeBounding)
3446 _gdk_x11_window_tmp_unset_parent_bg (window);
3447 _gdk_x11_window_tmp_unset_bg (window, TRUE);
3449 XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
3450 GDK_WINDOW_XID (window),
3457 if (shape == ShapeBounding)
3459 _gdk_x11_window_tmp_reset_parent_bg (window);
3460 _gdk_x11_window_tmp_reset_bg (window, TRUE);
3468 gdk_window_x11_shape_combine_region (GdkWindow *window,
3469 const cairo_region_t *shape_region,
3473 do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeBounding);
3477 gdk_window_x11_input_shape_combine_region (GdkWindow *window,
3478 const cairo_region_t *shape_region,
3483 do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeInput);
3489 * gdk_window_set_override_redirect:
3490 * @window: a toplevel #GdkWindow
3491 * @override_redirect: %TRUE if window should be override redirect
3493 * An override redirect window is not under the control of the window manager.
3494 * This means it won't have a titlebar, won't be minimizable, etc. - it will
3495 * be entirely under the control of the application. The window manager
3496 * can't see the override redirect window at all.
3498 * Override redirect should only be used for short-lived temporary
3499 * windows, such as popup menus. #GtkMenu uses an override redirect
3500 * window in its implementation, for example.
3504 gdk_window_set_override_redirect (GdkWindow *window,
3505 gboolean override_redirect)
3507 XSetWindowAttributes attr;
3509 if (!GDK_WINDOW_DESTROYED (window) &&
3510 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3512 GdkWindowObject *private = (GdkWindowObject *)window;
3513 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
3515 attr.override_redirect = (override_redirect? True : False);
3516 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3517 GDK_WINDOW_XID (window),
3521 impl->override_redirect = attr.override_redirect;
3526 * gdk_window_set_accept_focus:
3527 * @window: a toplevel #GdkWindow
3528 * @accept_focus: %TRUE if the window should receive input focus
3530 * Setting @accept_focus to %FALSE hints the desktop environment that the
3531 * window doesn't want to receive input focus.
3533 * On X, it is the responsibility of the window manager to interpret this
3534 * hint. ICCCM-compliant window manager usually respect it.
3539 gdk_window_set_accept_focus (GdkWindow *window,
3540 gboolean accept_focus)
3542 GdkWindowObject *private;
3544 private = (GdkWindowObject *)window;
3546 accept_focus = accept_focus != FALSE;
3548 if (private->accept_focus != accept_focus)
3550 private->accept_focus = accept_focus;
3552 if (!GDK_WINDOW_DESTROYED (window) &&
3553 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3554 update_wm_hints (window, FALSE);
3559 * gdk_window_set_focus_on_map:
3560 * @window: a toplevel #GdkWindow
3561 * @focus_on_map: %TRUE if the window should receive input focus when mapped
3563 * Setting @focus_on_map to %FALSE hints the desktop environment that the
3564 * window doesn't want to receive input focus when it is mapped.
3565 * focus_on_map should be turned off for windows that aren't triggered
3566 * interactively (such as popups from network activity).
3568 * On X, it is the responsibility of the window manager to interpret
3569 * this hint. Window managers following the freedesktop.org window
3570 * manager extension specification should respect it.
3575 gdk_window_set_focus_on_map (GdkWindow *window,
3576 gboolean focus_on_map)
3578 GdkWindowObject *private;
3580 private = (GdkWindowObject *)window;
3582 focus_on_map = focus_on_map != FALSE;
3584 if (private->focus_on_map != focus_on_map)
3586 private->focus_on_map = focus_on_map;
3588 if ((!GDK_WINDOW_DESTROYED (window)) &&
3589 (!private->focus_on_map) &&
3590 WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3591 gdk_x11_window_set_user_time (window, 0);
3596 * gdk_x11_window_set_user_time:
3597 * @window: A toplevel #GdkWindow
3598 * @timestamp: An XServer timestamp to which the property should be set
3600 * The application can use this call to update the _NET_WM_USER_TIME
3601 * property on a toplevel window. This property stores an Xserver
3602 * time which represents the time of the last user input event
3603 * received for this window. This property may be used by the window
3604 * manager to alter the focus, stacking, and/or placement behavior of
3605 * windows when they are mapped depending on whether the new window
3606 * was created by a user action or is a "pop-up" window activated by a
3607 * timer or some other event.
3609 * Note that this property is automatically updated by GDK, so this
3610 * function should only be used by applications which handle input
3611 * events bypassing GDK.
3616 gdk_x11_window_set_user_time (GdkWindow *window,
3619 GdkDisplay *display;
3620 GdkDisplayX11 *display_x11;
3621 GdkToplevelX11 *toplevel;
3622 glong timestamp_long = (glong)timestamp;
3625 if (GDK_WINDOW_DESTROYED (window) ||
3626 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3629 display = gdk_drawable_get_display (window);
3630 display_x11 = GDK_DISPLAY_X11 (display);
3631 toplevel = _gdk_x11_window_get_toplevel (window);
3635 g_warning ("gdk_window_set_user_time called on non-toplevel\n");
3639 if (toplevel->focus_window != None &&
3640 gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
3641 gdk_atom_intern_static_string ("_NET_WM_USER_TIME_WINDOW")))
3642 xid = toplevel->focus_window;
3644 xid = GDK_WINDOW_XID (window);
3646 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xid,
3647 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
3648 XA_CARDINAL, 32, PropModeReplace,
3649 (guchar *)×tamp_long, 1);
3651 if (timestamp_long != GDK_CURRENT_TIME &&
3652 (display_x11->user_time == GDK_CURRENT_TIME ||
3653 XSERVER_TIME_IS_LATER (timestamp_long, display_x11->user_time)))
3654 display_x11->user_time = timestamp_long;
3657 toplevel->user_time = timestamp_long;
3660 #define GDK_SELECTION_MAX_SIZE(display) \
3662 XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0 \
3663 ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100 \
3664 : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
3667 * gdk_window_set_icon_list:
3668 * @window: The #GdkWindow toplevel window to set the icon of.
3669 * @pixbufs: A list of pixbufs, of different sizes.
3671 * Sets a list of icons for the window. One of these will be used
3672 * to represent the window when it has been iconified. The icon is
3673 * usually shown in an icon box or some sort of task bar. Which icon
3674 * size is shown depends on the window manager. The window manager
3675 * can scale the icon but setting several size icons can give better
3676 * image quality since the window manager may only need to scale the
3677 * icon by a small amount or not at all.
3681 gdk_window_set_icon_list (GdkWindow *window,
3690 gint width, height, stride;
3693 GdkDisplay *display;
3696 if (GDK_WINDOW_DESTROYED (window) ||
3697 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3700 display = gdk_drawable_get_display (window);
3708 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
3710 width = gdk_pixbuf_get_width (pixbuf);
3711 height = gdk_pixbuf_get_height (pixbuf);
3713 /* silently ignore overlarge icons */
3714 if (size + 2 + width * height > GDK_SELECTION_MAX_SIZE(display))
3716 g_warning ("gdk_window_set_icon_list: icons too large");
3721 size += 2 + width * height;
3723 l = g_list_next (l);
3726 data = g_malloc (size * sizeof (gulong));
3734 width = gdk_pixbuf_get_width (pixbuf);
3735 height = gdk_pixbuf_get_height (pixbuf);
3736 stride = gdk_pixbuf_get_rowstride (pixbuf);
3737 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
3742 pixels = gdk_pixbuf_get_pixels (pixbuf);
3744 for (y = 0; y < height; y++)
3746 for (x = 0; x < width; x++)
3750 r = pixels[y*stride + x*n_channels + 0];
3751 g = pixels[y*stride + x*n_channels + 1];
3752 b = pixels[y*stride + x*n_channels + 2];
3753 if (n_channels >= 4)
3754 a = pixels[y*stride + x*n_channels + 3];
3758 *p++ = a << 24 | r << 16 | g << 8 | b ;
3762 l = g_list_next (l);
3768 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3769 GDK_WINDOW_XID (window),
3770 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"),
3773 (guchar*) data, size);
3777 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3778 GDK_WINDOW_XID (window),
3779 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"));
3786 * gdk_window_set_icon:
3787 * @window: a toplevel #GdkWindow
3788 * @icon_window: a #GdkWindow to use for the icon, or %NULL to unset
3789 * @pixmap: a #GdkPixmap to use as the icon, or %NULL to unset
3790 * @mask: a 1-bit pixmap (#GdkBitmap) to use as mask for @pixmap, or %NULL to have none
3792 * Sets the icon of @window as a pixmap or window. If using GTK+, investigate
3793 * gtk_window_set_default_icon_list() first, and then gtk_window_set_icon_list()
3794 * and gtk_window_set_icon(). If those don't meet your needs, look at
3795 * gdk_window_set_icon_list(). Only if all those are too high-level do you
3796 * want to fall back to gdk_window_set_icon().
3800 gdk_window_set_icon (GdkWindow *window,
3801 GdkWindow *icon_window,
3805 GdkToplevelX11 *toplevel;
3807 if (GDK_WINDOW_DESTROYED (window) ||
3808 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3811 toplevel = _gdk_x11_window_get_toplevel (window);
3813 if (toplevel->icon_window != icon_window)
3815 if (toplevel->icon_window)
3816 g_object_unref (toplevel->icon_window);
3817 toplevel->icon_window = g_object_ref (icon_window);
3820 if (toplevel->icon_pixmap != pixmap)
3823 g_object_ref (pixmap);
3824 if (toplevel->icon_pixmap)
3825 g_object_unref (toplevel->icon_pixmap);
3826 toplevel->icon_pixmap = pixmap;
3829 if (toplevel->icon_mask != mask)
3832 g_object_ref (mask);
3833 if (toplevel->icon_mask)
3834 g_object_unref (toplevel->icon_mask);
3835 toplevel->icon_mask = mask;
3838 update_wm_hints (window, FALSE);
3842 gdk_window_icon_name_set (GdkWindow *window)
3844 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
3845 g_quark_from_static_string ("gdk-icon-name-set")));
3849 * gdk_window_set_icon_name:
3850 * @window: a toplevel #GdkWindow
3851 * @name: name of window while iconified (minimized)
3853 * Windows may have a name used while minimized, distinct from the
3854 * name they display in their titlebar. Most of the time this is a bad
3855 * idea from a user interface standpoint. But you can set such a name
3856 * with this function, if you like.
3858 * After calling this with a non-%NULL @name, calls to gdk_window_set_title()
3859 * will not update the icon title.
3861 * Using %NULL for @name unsets the icon title; further calls to
3862 * gdk_window_set_title() will again update the icon title as well.
3865 gdk_window_set_icon_name (GdkWindow *window,
3868 GdkDisplay *display;
3870 if (GDK_WINDOW_DESTROYED (window) ||
3871 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3874 display = gdk_drawable_get_display (window);
3876 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
3877 GUINT_TO_POINTER (name != NULL));
3881 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3882 GDK_WINDOW_XID (window),
3883 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
3884 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
3885 PropModeReplace, (guchar *)name, strlen (name));
3887 set_text_property (display, GDK_WINDOW_XID (window),
3888 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
3893 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3894 GDK_WINDOW_XID (window),
3895 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"));
3896 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3897 GDK_WINDOW_XID (window),
3898 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"));
3903 * gdk_window_iconify:
3904 * @window: a toplevel #GdkWindow
3906 * Asks to iconify (minimize) @window. The window manager may choose
3907 * to ignore the request, but normally will honor it. Using
3908 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
3910 * This function only makes sense when @window is a toplevel window.
3914 gdk_window_iconify (GdkWindow *window)
3916 if (GDK_WINDOW_DESTROYED (window) ||
3917 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3920 if (GDK_WINDOW_IS_MAPPED (window))
3922 XIconifyWindow (GDK_WINDOW_XDISPLAY (window),
3923 GDK_WINDOW_XWINDOW (window),
3924 gdk_screen_get_number (GDK_WINDOW_SCREEN (window)));
3928 /* Flip our client side flag, the real work happens on map. */
3929 gdk_synthesize_window_state (window,
3931 GDK_WINDOW_STATE_ICONIFIED);
3936 * gdk_window_deiconify:
3937 * @window: a toplevel #GdkWindow
3939 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
3940 * choose to ignore the request to deiconify. When using GTK+,
3941 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
3942 * you probably want to use gtk_window_present(), which raises the window, focuses it,
3943 * unminimizes it, and puts it on the current desktop.
3947 gdk_window_deiconify (GdkWindow *window)
3949 if (GDK_WINDOW_DESTROYED (window) ||
3950 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3953 if (GDK_WINDOW_IS_MAPPED (window))
3955 gdk_window_show (window);
3959 /* Flip our client side flag, the real work happens on map. */
3960 gdk_synthesize_window_state (window,
3961 GDK_WINDOW_STATE_ICONIFIED,
3968 * @window: a toplevel #GdkWindow
3970 * "Pins" a window such that it's on all workspaces and does not scroll
3971 * with viewports, for window managers that have scrollable viewports.
3972 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
3974 * On the X11 platform, this function depends on window manager
3975 * support, so may have no effect with many window managers. However,
3976 * GDK will do the best it can to convince the window manager to stick
3977 * the window. For window managers that don't support this operation,
3978 * there's nothing you can do to force it to happen.
3982 gdk_window_stick (GdkWindow *window)
3984 if (GDK_WINDOW_DESTROYED (window) ||
3985 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
3988 if (GDK_WINDOW_IS_MAPPED (window))
3990 /* "stick" means stick to all desktops _and_ do not scroll with the
3991 * viewport. i.e. glue to the monitor glass in all cases.
3994 XClientMessageEvent xclient;
3996 /* Request stick during viewport scroll */
3997 gdk_wmspec_change_state (TRUE, window,
3998 gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
4001 /* Request desktop 0xFFFFFFFF */
4002 memset (&xclient, 0, sizeof (xclient));
4003 xclient.type = ClientMessage;
4004 xclient.window = GDK_WINDOW_XWINDOW (window);
4005 xclient.display = GDK_WINDOW_XDISPLAY (window);
4006 xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
4008 xclient.format = 32;
4010 xclient.data.l[0] = 0xFFFFFFFF;
4011 xclient.data.l[1] = 0;
4012 xclient.data.l[2] = 0;
4013 xclient.data.l[3] = 0;
4014 xclient.data.l[4] = 0;
4016 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
4017 SubstructureRedirectMask | SubstructureNotifyMask,
4018 (XEvent *)&xclient);
4022 /* Flip our client side flag, the real work happens on map. */
4023 gdk_synthesize_window_state (window,
4025 GDK_WINDOW_STATE_STICKY);
4030 * gdk_window_unstick:
4031 * @window: a toplevel #GdkWindow
4033 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
4034 * and gtk_window_unstick().
4038 gdk_window_unstick (GdkWindow *window)
4040 if (GDK_WINDOW_DESTROYED (window) ||
4041 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4044 if (GDK_WINDOW_IS_MAPPED (window))
4046 /* Request unstick from viewport */
4047 gdk_wmspec_change_state (FALSE, window,
4048 gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
4051 move_to_current_desktop (window);
4055 /* Flip our client side flag, the real work happens on map. */
4056 gdk_synthesize_window_state (window,
4057 GDK_WINDOW_STATE_STICKY,
4064 * gdk_window_maximize:
4065 * @window: a toplevel #GdkWindow
4067 * Maximizes the window. If the window was already maximized, then
4068 * this function does nothing.
4070 * On X11, asks the window manager to maximize @window, if the window
4071 * manager supports this operation. Not all window managers support
4072 * this, and some deliberately ignore it or don't have a concept of
4073 * "maximized"; so you can't rely on the maximization actually
4074 * happening. But it will happen with most standard window managers,
4075 * and GDK makes a best effort to get it to happen.
4077 * On Windows, reliably maximizes the window.
4081 gdk_window_maximize (GdkWindow *window)
4083 if (GDK_WINDOW_DESTROYED (window) ||
4084 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4087 if (GDK_WINDOW_IS_MAPPED (window))
4088 gdk_wmspec_change_state (TRUE, window,
4089 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
4090 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
4092 gdk_synthesize_window_state (window,
4094 GDK_WINDOW_STATE_MAXIMIZED);
4098 * gdk_window_unmaximize:
4099 * @window: a toplevel #GdkWindow
4101 * Unmaximizes the window. If the window wasn't maximized, then this
4102 * function does nothing.
4104 * On X11, asks the window manager to unmaximize @window, if the
4105 * window manager supports this operation. Not all window managers
4106 * support this, and some deliberately ignore it or don't have a
4107 * concept of "maximized"; so you can't rely on the unmaximization
4108 * actually happening. But it will happen with most standard window
4109 * managers, and GDK makes a best effort to get it to happen.
4111 * On Windows, reliably unmaximizes the window.
4115 gdk_window_unmaximize (GdkWindow *window)
4117 if (GDK_WINDOW_DESTROYED (window) ||
4118 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4121 if (GDK_WINDOW_IS_MAPPED (window))
4122 gdk_wmspec_change_state (FALSE, window,
4123 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
4124 gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
4126 gdk_synthesize_window_state (window,
4127 GDK_WINDOW_STATE_MAXIMIZED,
4132 * gdk_window_fullscreen:
4133 * @window: a toplevel #GdkWindow
4135 * Moves the window into fullscreen mode. This means the
4136 * window covers the entire screen and is above any panels
4139 * If the window was already fullscreen, then this function does nothing.
4141 * On X11, asks the window manager to put @window in a fullscreen
4142 * state, if the window manager supports this operation. Not all
4143 * window managers support this, and some deliberately ignore it or
4144 * don't have a concept of "fullscreen"; so you can't rely on the
4145 * fullscreenification actually happening. But it will happen with
4146 * most standard window managers, and GDK makes a best effort to get
4152 gdk_window_fullscreen (GdkWindow *window)
4154 if (GDK_WINDOW_DESTROYED (window) ||
4155 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4158 if (GDK_WINDOW_IS_MAPPED (window))
4159 gdk_wmspec_change_state (TRUE, window,
4160 gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
4164 gdk_synthesize_window_state (window,
4166 GDK_WINDOW_STATE_FULLSCREEN);
4170 * gdk_window_unfullscreen:
4171 * @window: a toplevel #GdkWindow
4173 * Moves the window out of fullscreen mode. If the window was not
4174 * fullscreen, does nothing.
4176 * On X11, asks the window manager to move @window out of the fullscreen
4177 * state, if the window manager supports this operation. Not all
4178 * window managers support this, and some deliberately ignore it or
4179 * don't have a concept of "fullscreen"; so you can't rely on the
4180 * unfullscreenification actually happening. But it will happen with
4181 * most standard window managers, and GDK makes a best effort to get
4187 gdk_window_unfullscreen (GdkWindow *window)
4189 if (GDK_WINDOW_DESTROYED (window) ||
4190 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4193 if (GDK_WINDOW_IS_MAPPED (window))
4194 gdk_wmspec_change_state (FALSE, window,
4195 gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
4199 gdk_synthesize_window_state (window,
4200 GDK_WINDOW_STATE_FULLSCREEN,
4205 * gdk_window_set_keep_above:
4206 * @window: a toplevel #GdkWindow
4207 * @setting: whether to keep @window above other windows
4209 * Set if @window must be kept above other windows. If the
4210 * window was already above, then this function does nothing.
4212 * On X11, asks the window manager to keep @window above, if the window
4213 * manager supports this operation. Not all window managers support
4214 * this, and some deliberately ignore it or don't have a concept of
4215 * "keep above"; so you can't rely on the window being kept above.
4216 * But it will happen with most standard window managers,
4217 * and GDK makes a best effort to get it to happen.
4222 gdk_window_set_keep_above (GdkWindow *window,
4225 g_return_if_fail (GDK_IS_WINDOW (window));
4227 if (GDK_WINDOW_DESTROYED (window) ||
4228 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4231 if (GDK_WINDOW_IS_MAPPED (window))
4234 gdk_wmspec_change_state (FALSE, window,
4235 gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
4237 gdk_wmspec_change_state (setting, window,
4238 gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
4242 gdk_synthesize_window_state (window,
4243 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
4244 setting ? GDK_WINDOW_STATE_ABOVE : 0);
4248 * gdk_window_set_keep_below:
4249 * @window: a toplevel #GdkWindow
4250 * @setting: whether to keep @window below other windows
4252 * Set if @window must be kept below other windows. If the
4253 * window was already below, then this function does nothing.
4255 * On X11, asks the window manager to keep @window below, if the window
4256 * manager supports this operation. Not all window managers support
4257 * this, and some deliberately ignore it or don't have a concept of
4258 * "keep below"; so you can't rely on the window being kept below.
4259 * But it will happen with most standard window managers,
4260 * and GDK makes a best effort to get it to happen.
4265 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
4267 g_return_if_fail (GDK_IS_WINDOW (window));
4269 if (GDK_WINDOW_DESTROYED (window) ||
4270 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4273 if (GDK_WINDOW_IS_MAPPED (window))
4276 gdk_wmspec_change_state (FALSE, window,
4277 gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
4279 gdk_wmspec_change_state (setting, window,
4280 gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
4284 gdk_synthesize_window_state (window,
4285 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
4286 setting ? GDK_WINDOW_STATE_BELOW : 0);
4290 * gdk_window_get_group:
4291 * @window: a toplevel #GdkWindow
4293 * Returns the group leader window for @window. See gdk_window_set_group().
4295 * Return value: the group leader window for @window
4300 gdk_window_get_group (GdkWindow *window)
4302 GdkToplevelX11 *toplevel;
4304 if (GDK_WINDOW_DESTROYED (window) ||
4305 !WINDOW_IS_TOPLEVEL (window))
4308 toplevel = _gdk_x11_window_get_toplevel (window);
4310 return toplevel->group_leader;
4314 * gdk_window_set_group:
4315 * @window: a toplevel #GdkWindow
4316 * @leader: group leader window, or %NULL to restore the default group leader window
4318 * Sets the group leader window for @window. By default,
4319 * GDK sets the group leader for all toplevel windows
4320 * to a global window implicitly created by GDK. With this function
4321 * you can override this default.
4323 * The group leader window allows the window manager to distinguish
4324 * all windows that belong to a single application. It may for example
4325 * allow users to minimize/unminimize all windows belonging to an
4326 * application at once. You should only set a non-default group window
4327 * if your application pretends to be multiple applications.
4330 gdk_window_set_group (GdkWindow *window,
4333 GdkToplevelX11 *toplevel;
4335 g_return_if_fail (GDK_IS_WINDOW (window));
4336 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
4337 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
4339 if (GDK_WINDOW_DESTROYED (window) ||
4340 (leader != NULL && GDK_WINDOW_DESTROYED (leader)) ||
4341 !WINDOW_IS_TOPLEVEL (window))
4344 toplevel = _gdk_x11_window_get_toplevel (window);
4347 leader = gdk_display_get_default_group (gdk_drawable_get_display (window));
4349 if (toplevel->group_leader != leader)
4351 if (toplevel->group_leader)
4352 g_object_unref (toplevel->group_leader);
4353 toplevel->group_leader = g_object_ref (leader);
4354 (_gdk_x11_window_get_toplevel (leader))->is_leader = TRUE;
4357 update_wm_hints (window, FALSE);
4360 static MotifWmHints *
4361 gdk_window_get_mwm_hints (GdkWindow *window)
4363 GdkDisplay *display;
4364 Atom hints_atom = None;
4371 if (GDK_WINDOW_DESTROYED (window))
4374 display = gdk_drawable_get_display (window);
4376 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4378 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
4379 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4380 False, AnyPropertyType, &type, &format, &nitems,
4381 &bytes_after, &data);
4386 return (MotifWmHints *)data;
4390 gdk_window_set_mwm_hints (GdkWindow *window,
4391 MotifWmHints *new_hints)
4393 GdkDisplay *display;
4394 Atom hints_atom = None;
4396 MotifWmHints *hints;
4402 if (GDK_WINDOW_DESTROYED (window))
4405 display = gdk_drawable_get_display (window);
4407 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4409 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
4410 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4411 False, AnyPropertyType, &type, &format, &nitems,
4412 &bytes_after, &data);
4418 hints = (MotifWmHints *)data;
4420 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
4422 hints->flags |= MWM_HINTS_FUNCTIONS;
4423 hints->functions = new_hints->functions;
4425 if (new_hints->flags & MWM_HINTS_DECORATIONS)
4427 hints->flags |= MWM_HINTS_DECORATIONS;
4428 hints->decorations = new_hints->decorations;
4432 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
4433 hints_atom, hints_atom, 32, PropModeReplace,
4434 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
4436 if (hints != new_hints)
4441 * gdk_window_set_decorations:
4442 * @window: a toplevel #GdkWindow
4443 * @decorations: decoration hint mask
4445 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
4446 * This function sets the traditional Motif window manager hints that tell the
4447 * window manager which decorations you would like your window to have.
4448 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
4449 * using the GDK function directly.
4451 * The @decorations argument is the logical OR of the fields in
4452 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
4453 * mask, the other bits indicate which decorations should be turned off.
4454 * If #GDK_DECOR_ALL is not included, then the other bits indicate
4455 * which decorations should be turned on.
4457 * Most window managers honor a decorations hint of 0 to disable all decorations,
4458 * but very few honor all possible combinations of bits.
4462 gdk_window_set_decorations (GdkWindow *window,
4463 GdkWMDecoration decorations)
4467 if (GDK_WINDOW_DESTROYED (window) ||
4468 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4471 /* initialize to zero to avoid writing uninitialized data to socket */
4472 memset(&hints, 0, sizeof(hints));
4473 hints.flags = MWM_HINTS_DECORATIONS;
4474 hints.decorations = decorations;
4476 gdk_window_set_mwm_hints (window, &hints);
4480 * gdk_window_get_decorations:
4481 * @window: The toplevel #GdkWindow to get the decorations from
4482 * @decorations: The window decorations will be written here
4484 * Returns the decorations set on the GdkWindow with
4485 * gdk_window_set_decorations().
4487 * Returns: %TRUE if the window has decorations set, %FALSE otherwise.
4490 gdk_window_get_decorations(GdkWindow *window,
4491 GdkWMDecoration *decorations)
4493 MotifWmHints *hints;
4494 gboolean result = FALSE;
4496 if (GDK_WINDOW_DESTROYED (window) ||
4497 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4500 hints = gdk_window_get_mwm_hints (window);
4504 if (hints->flags & MWM_HINTS_DECORATIONS)
4507 *decorations = hints->decorations;
4518 * gdk_window_set_functions:
4519 * @window: a toplevel #GdkWindow
4520 * @functions: bitmask of operations to allow on @window
4522 * Sets hints about the window management functions to make available
4523 * via buttons on the window frame.
4525 * On the X backend, this function sets the traditional Motif window
4526 * manager hint for this purpose. However, few window managers do
4527 * anything reliable or interesting with this hint. Many ignore it
4530 * The @functions argument is the logical OR of values from the
4531 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
4532 * then the other bits indicate which functions to disable; if
4533 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
4538 gdk_window_set_functions (GdkWindow *window,
4539 GdkWMFunction functions)
4543 g_return_if_fail (GDK_IS_WINDOW (window));
4545 if (GDK_WINDOW_DESTROYED (window) ||
4546 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
4549 /* initialize to zero to avoid writing uninitialized data to socket */
4550 memset(&hints, 0, sizeof(hints));
4551 hints.flags = MWM_HINTS_FUNCTIONS;
4552 hints.functions = functions;
4554 gdk_window_set_mwm_hints (window, &hints);
4558 _xwindow_get_shape (Display *xdisplay,
4562 cairo_region_t *shape;
4570 xrl = XShapeGetRectangles (xdisplay,
4572 shape_type, &rn, &ord);
4574 if (xrl == NULL || rn == 0)
4575 return cairo_region_create (); /* Empty */
4577 if (ord != YXBanded)
4579 /* This really shouldn't happen with any xserver, as they
4580 generally convert regions to YXBanded internally */
4581 g_warning ("non YXBanded shape masks not supported");
4586 rl = g_new (GdkRectangle, rn);
4587 for (i = 0; i < rn; i++)
4591 rl[i].width = xrl[i].width;
4592 rl[i].height = xrl[i].height;
4596 shape = cairo_region_create_rectangles (rl, rn);
4604 _gdk_windowing_get_shape_for_mask (GdkBitmap *mask)
4606 GdkDisplay *display;
4608 cairo_region_t *region;
4610 display = gdk_drawable_get_display (GDK_DRAWABLE (mask));
4612 window = XCreateSimpleWindow (GDK_DISPLAY_XDISPLAY (display),
4613 GDK_SCREEN_XROOTWIN (gdk_drawable_get_screen (mask)),
4616 XShapeCombineMask (GDK_DISPLAY_XDISPLAY (display),
4620 GDK_PIXMAP_XID (mask),
4623 region = _xwindow_get_shape (GDK_DISPLAY_XDISPLAY (display),
4624 window, ShapeBounding);
4626 XDestroyWindow (GDK_DISPLAY_XDISPLAY (display), window);
4632 _gdk_windowing_window_get_shape (GdkWindow *window)
4634 if (!GDK_WINDOW_DESTROYED (window) &&
4635 gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
4636 return _xwindow_get_shape (GDK_WINDOW_XDISPLAY (window),
4637 GDK_WINDOW_XID (window), ShapeBounding);
4643 _gdk_windowing_window_get_input_shape (GdkWindow *window)
4645 #if defined(ShapeInput)
4646 if (!GDK_WINDOW_DESTROYED (window) &&
4647 gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
4648 return _xwindow_get_shape (GDK_WINDOW_XDISPLAY (window),
4649 GDK_WINDOW_XID (window),
4657 gdk_window_set_static_bit_gravity (GdkWindow *window,
4660 XSetWindowAttributes xattributes;
4661 GdkWindowObject *private;
4662 guint xattributes_mask = 0;
4664 g_return_if_fail (GDK_IS_WINDOW (window));
4666 private = GDK_WINDOW_OBJECT (window);
4667 if (private->input_only)
4670 xattributes.bit_gravity = StaticGravity;
4671 xattributes_mask |= CWBitGravity;
4672 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
4673 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
4674 GDK_WINDOW_XID (window),
4675 CWBitGravity, &xattributes);
4679 gdk_window_set_static_win_gravity (GdkWindow *window,
4682 XSetWindowAttributes xattributes;
4684 g_return_if_fail (GDK_IS_WINDOW (window));
4686 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
4688 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
4689 GDK_WINDOW_XID (window),
4690 CWWinGravity, &xattributes);
4694 gdk_window_x11_set_static_gravities (GdkWindow *window,
4695 gboolean use_static)
4697 GdkWindowObject *private = (GdkWindowObject *)window;
4700 if (!use_static == !private->guffaw_gravity)
4703 private->guffaw_gravity = use_static;
4705 if (!GDK_WINDOW_DESTROYED (window))
4707 gdk_window_set_static_bit_gravity (window, use_static);
4709 tmp_list = private->children;
4712 gdk_window_set_static_win_gravity (tmp_list->data, use_static);
4714 tmp_list = tmp_list->next;
4722 wmspec_moveresize (GdkWindow *window,
4728 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
4730 XClientMessageEvent xclient;
4732 /* Release passive grab */
4733 gdk_display_pointer_ungrab (display, timestamp);
4735 memset (&xclient, 0, sizeof (xclient));
4736 xclient.type = ClientMessage;
4737 xclient.window = GDK_WINDOW_XID (window);
4738 xclient.message_type =
4739 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
4740 xclient.format = 32;
4741 xclient.data.l[0] = root_x;
4742 xclient.data.l[1] = root_y;
4743 xclient.data.l[2] = direction;
4744 xclient.data.l[3] = 0;
4745 xclient.data.l[4] = 0;
4747 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
4748 SubstructureRedirectMask | SubstructureNotifyMask,
4749 (XEvent *)&xclient);
4752 typedef struct _MoveResizeData MoveResizeData;
4754 struct _MoveResizeData
4756 GdkDisplay *display;
4758 GdkWindow *moveresize_window;
4759 GdkWindow *moveresize_emulation_window;
4761 GdkWindowEdge resize_edge;
4762 gint moveresize_button;
4765 gint moveresize_orig_x;
4766 gint moveresize_orig_y;
4767 gint moveresize_orig_width;
4768 gint moveresize_orig_height;
4769 GdkWindowHints moveresize_geom_mask;
4770 GdkGeometry moveresize_geometry;
4771 Time moveresize_process_time;
4772 XEvent *moveresize_pending_event;
4775 /* From the WM spec */
4776 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
4777 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
4778 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
4779 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
4780 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
4781 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
4782 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
4783 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
4784 #define _NET_WM_MOVERESIZE_MOVE 8
4787 wmspec_resize_drag (GdkWindow *window,
4796 /* Let the compiler turn a switch into a table, instead
4797 * of doing the table manually, this way is easier to verify.
4801 case GDK_WINDOW_EDGE_NORTH_WEST:
4802 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
4805 case GDK_WINDOW_EDGE_NORTH:
4806 direction = _NET_WM_MOVERESIZE_SIZE_TOP;
4809 case GDK_WINDOW_EDGE_NORTH_EAST:
4810 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
4813 case GDK_WINDOW_EDGE_WEST:
4814 direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
4817 case GDK_WINDOW_EDGE_EAST:
4818 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
4821 case GDK_WINDOW_EDGE_SOUTH_WEST:
4822 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
4825 case GDK_WINDOW_EDGE_SOUTH:
4826 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
4829 case GDK_WINDOW_EDGE_SOUTH_EAST:
4830 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
4834 g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
4839 wmspec_moveresize (window, direction, root_x, root_y, timestamp);
4842 static MoveResizeData *
4843 get_move_resize_data (GdkDisplay *display,
4846 MoveResizeData *mv_resize;
4847 static GQuark move_resize_quark = 0;
4849 if (!move_resize_quark)
4850 move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize");
4852 mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark);
4854 if (!mv_resize && create)
4856 mv_resize = g_new0 (MoveResizeData, 1);
4857 mv_resize->display = display;
4859 g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize);
4866 update_pos (MoveResizeData *mv_resize,
4872 dx = new_root_x - mv_resize->moveresize_x;
4873 dy = new_root_y - mv_resize->moveresize_y;
4875 if (mv_resize->is_resize)
4879 x = mv_resize->moveresize_orig_x;
4880 y = mv_resize->moveresize_orig_y;
4882 w = mv_resize->moveresize_orig_width;
4883 h = mv_resize->moveresize_orig_height;
4885 switch (mv_resize->resize_edge)
4887 case GDK_WINDOW_EDGE_NORTH_WEST:
4893 case GDK_WINDOW_EDGE_NORTH:
4897 case GDK_WINDOW_EDGE_NORTH_EAST:
4902 case GDK_WINDOW_EDGE_SOUTH_WEST:
4907 case GDK_WINDOW_EDGE_SOUTH_EAST:
4911 case GDK_WINDOW_EDGE_SOUTH:
4914 case GDK_WINDOW_EDGE_EAST:
4917 case GDK_WINDOW_EDGE_WEST:
4928 if (mv_resize->moveresize_geom_mask)
4930 gdk_window_constrain_size (&mv_resize->moveresize_geometry,
4931 mv_resize->moveresize_geom_mask,
4935 gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
4941 x = mv_resize->moveresize_orig_x + dx;
4942 y = mv_resize->moveresize_orig_y + dy;
4944 gdk_window_move (mv_resize->moveresize_window, x, y);
4949 finish_drag (MoveResizeData *mv_resize)
4951 gdk_window_destroy (mv_resize->moveresize_emulation_window);
4952 mv_resize->moveresize_emulation_window = NULL;
4953 g_object_unref (mv_resize->moveresize_window);
4954 mv_resize->moveresize_window = NULL;
4956 if (mv_resize->moveresize_pending_event)
4958 g_free (mv_resize->moveresize_pending_event);
4959 mv_resize->moveresize_pending_event = NULL;
4964 lookahead_motion_predicate (Display *xdisplay,
4968 gboolean *seen_release = (gboolean *)arg;
4969 GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
4970 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
4975 switch (event->xany.type)
4978 *seen_release = TRUE;
4981 mv_resize->moveresize_process_time = event->xmotion.time;
4991 moveresize_lookahead (MoveResizeData *mv_resize,
4995 gboolean seen_release = FALSE;
4997 if (mv_resize->moveresize_process_time)
4999 if (event->xmotion.time == mv_resize->moveresize_process_time)
5001 mv_resize->moveresize_process_time = 0;
5008 XCheckIfEvent (event->xany.display, &tmp_event,
5009 lookahead_motion_predicate, (XPointer) & seen_release);
5011 return mv_resize->moveresize_process_time == 0;
5015 _gdk_moveresize_handle_event (XEvent *event)
5017 guint button_mask = 0;
5018 GdkWindowObject *window_private;
5019 GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
5020 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5022 if (!mv_resize || !mv_resize->moveresize_window)
5025 window_private = (GdkWindowObject *) mv_resize->moveresize_window;
5027 button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
5029 switch (event->xany.type)
5032 if (window_private->resize_count > 0)
5034 if (mv_resize->moveresize_pending_event)
5035 *mv_resize->moveresize_pending_event = *event;
5037 mv_resize->moveresize_pending_event =
5038 g_memdup (event, sizeof (XEvent));
5042 if (!moveresize_lookahead (mv_resize, event))
5045 update_pos (mv_resize,
5046 event->xmotion.x_root,
5047 event->xmotion.y_root);
5049 /* This should never be triggered in normal cases, but in the
5050 * case where the drag started without an implicit grab being
5051 * in effect, we could miss the release if it occurs before
5052 * we grab the pointer; this ensures that we will never
5053 * get a permanently stuck grab.
5055 if ((event->xmotion.state & button_mask) == 0)
5056 finish_drag (mv_resize);
5060 update_pos (mv_resize,
5061 event->xbutton.x_root,
5062 event->xbutton.y_root);
5064 if (event->xbutton.button == mv_resize->moveresize_button)
5065 finish_drag (mv_resize);
5072 _gdk_moveresize_configure_done (GdkDisplay *display,
5076 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5078 if (!mv_resize || window != mv_resize->moveresize_window)
5081 if (mv_resize->moveresize_pending_event)
5083 tmp_event = mv_resize->moveresize_pending_event;
5084 mv_resize->moveresize_pending_event = NULL;
5085 _gdk_moveresize_handle_event (tmp_event);
5093 create_moveresize_window (MoveResizeData *mv_resize,
5096 GdkWindowAttr attributes;
5097 gint attributes_mask;
5098 GdkGrabStatus status;
5100 g_assert (mv_resize->moveresize_emulation_window == NULL);
5102 attributes.x = -100;
5103 attributes.y = -100;
5104 attributes.width = 10;
5105 attributes.height = 10;
5106 attributes.window_type = GDK_WINDOW_TEMP;
5107 attributes.wclass = GDK_INPUT_ONLY;
5108 attributes.override_redirect = TRUE;
5109 attributes.event_mask = 0;
5111 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
5113 mv_resize->moveresize_emulation_window =
5114 gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)),
5118 gdk_window_show (mv_resize->moveresize_emulation_window);
5120 status = gdk_pointer_grab (mv_resize->moveresize_emulation_window,
5122 GDK_BUTTON_RELEASE_MASK |
5123 GDK_POINTER_MOTION_MASK,
5128 if (status != GDK_GRAB_SUCCESS)
5130 /* If this fails, some other client has grabbed the window
5133 finish_drag (mv_resize);
5136 mv_resize->moveresize_process_time = 0;
5140 Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
5141 so that calling XMoveWindow with these coordinates will not move the
5143 Note that this depends on the WM to implement ICCCM-compliant reference
5147 calculate_unmoving_origin (MoveResizeData *mv_resize)
5152 if (mv_resize->moveresize_geom_mask & GDK_HINT_WIN_GRAVITY &&
5153 mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC)
5155 gdk_window_get_origin (mv_resize->moveresize_window,
5156 &mv_resize->moveresize_orig_x,
5157 &mv_resize->moveresize_orig_y);
5161 gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
5162 gdk_window_get_geometry (mv_resize->moveresize_window,
5163 NULL, NULL, &width, &height, NULL);
5165 switch (mv_resize->moveresize_geometry.win_gravity)
5167 case GDK_GRAVITY_NORTH_WEST:
5168 mv_resize->moveresize_orig_x = rect.x;
5169 mv_resize->moveresize_orig_y = rect.y;
5171 case GDK_GRAVITY_NORTH:
5172 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5173 mv_resize->moveresize_orig_y = rect.y;
5175 case GDK_GRAVITY_NORTH_EAST:
5176 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5177 mv_resize->moveresize_orig_y = rect.y;
5179 case GDK_GRAVITY_WEST:
5180 mv_resize->moveresize_orig_x = rect.x;
5181 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5183 case GDK_GRAVITY_CENTER:
5184 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5185 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5187 case GDK_GRAVITY_EAST:
5188 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5189 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5191 case GDK_GRAVITY_SOUTH_WEST:
5192 mv_resize->moveresize_orig_x = rect.x;
5193 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5195 case GDK_GRAVITY_SOUTH:
5196 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5197 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5199 case GDK_GRAVITY_SOUTH_EAST:
5200 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5201 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5204 mv_resize->moveresize_orig_x = rect.x;
5205 mv_resize->moveresize_orig_y = rect.y;
5212 emulate_resize_drag (GdkWindow *window,
5219 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
5221 mv_resize->is_resize = TRUE;
5222 mv_resize->moveresize_button = button;
5223 mv_resize->resize_edge = edge;
5224 mv_resize->moveresize_x = root_x;
5225 mv_resize->moveresize_y = root_y;
5226 mv_resize->moveresize_window = g_object_ref (window);
5228 gdk_drawable_get_size (window,
5229 &mv_resize->moveresize_orig_width,
5230 &mv_resize->moveresize_orig_height);
5232 mv_resize->moveresize_geom_mask = 0;
5233 gdk_window_get_geometry_hints (window,
5234 &mv_resize->moveresize_geometry,
5235 &mv_resize->moveresize_geom_mask);
5237 calculate_unmoving_origin (mv_resize);
5239 create_moveresize_window (mv_resize, timestamp);
5243 emulate_move_drag (GdkWindow *window,
5249 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
5251 mv_resize->is_resize = FALSE;
5252 mv_resize->moveresize_button = button;
5253 mv_resize->moveresize_x = root_x;
5254 mv_resize->moveresize_y = root_y;
5256 mv_resize->moveresize_window = g_object_ref (window);
5258 calculate_unmoving_origin (mv_resize);
5260 create_moveresize_window (mv_resize, timestamp);
5264 * gdk_window_begin_resize_drag:
5265 * @window: a toplevel #GdkWindow
5266 * @edge: the edge or corner from which the drag is started
5267 * @button: the button being used to drag
5268 * @root_x: root window X coordinate of mouse click that began the drag
5269 * @root_y: root window Y coordinate of mouse click that began the drag
5270 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
5272 * Begins a window resize operation (for a toplevel window).
5273 * You might use this function to implement a "window resize grip," for
5274 * example; in fact #GtkStatusbar uses it. The function works best
5275 * with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a
5276 * fallback implementation for other window managers.
5280 gdk_window_begin_resize_drag (GdkWindow *window,
5287 if (GDK_WINDOW_DESTROYED (window) ||
5288 !WINDOW_IS_TOPLEVEL_OR_FOREIGN (window))
5291 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
5292 gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
5293 wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
5295 emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
5299 * gdk_window_begin_move_drag:
5300 * @window: a toplevel #GdkWindow
5301 * @button: the button being used to drag
5302 * @root_x: root window X coordinate of mouse click that began the drag
5303 * @root_y: root window Y coordinate of mouse click that began the drag
5304 * @timestamp: timestamp of mouse click that began the drag
5306 * Begins a window move operation (for a toplevel window). You might
5307 * use this function to implement a "window move grip," for
5308 * example. The function works best with window managers that support
5309 * the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
5310 * Window Manager Hints</ulink>, but has a fallback implementation for
5311 * other window managers.
5315 gdk_window_begin_move_drag (GdkWindow *window,
5321 if (GDK_WINDOW_DESTROYED (window) ||
5322 !WINDOW_IS_TOPLEVEL (window))
5325 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
5326 gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
5327 wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, root_x, root_y,
5330 emulate_move_drag (window, button, root_x, root_y, timestamp);
5334 * gdk_window_enable_synchronized_configure:
5335 * @window: a toplevel #GdkWindow
5337 * Indicates that the application will cooperate with the window
5338 * system in synchronizing the window repaint with the window
5339 * manager during resizing operations. After an application calls
5340 * this function, it must call gdk_window_configure_finished() every
5341 * time it has finished all processing associated with a set of
5342 * Configure events. Toplevel GTK+ windows automatically use this
5345 * On X, calling this function makes @window participate in the
5346 * _NET_WM_SYNC_REQUEST window manager protocol.
5351 gdk_window_enable_synchronized_configure (GdkWindow *window)
5353 GdkWindowObject *private = (GdkWindowObject *)window;
5354 GdkWindowImplX11 *impl;
5356 if (!GDK_IS_WINDOW_IMPL_X11 (private->impl))
5359 impl = GDK_WINDOW_IMPL_X11 (private->impl);
5361 if (!impl->use_synchronized_configure)
5363 /* This basically means you want to do fancy X specific stuff, so
5364 ensure we have a native window */
5365 gdk_window_ensure_native (window);
5367 impl->use_synchronized_configure = TRUE;
5368 ensure_sync_counter (window);
5373 * gdk_window_configure_finished:
5374 * @window: a toplevel #GdkWindow
5376 * Signal to the window system that the application has finished
5377 * handling Configure events it has received. Window Managers can
5378 * use this to better synchronize the frame repaint with the
5379 * application. GTK+ applications will automatically call this
5380 * function when appropriate.
5382 * This function can only be called if gdk_window_enable_synchronized_configure()
5383 * was called previously.
5388 gdk_window_configure_finished (GdkWindow *window)
5390 GdkWindowImplX11 *impl;
5392 if (!WINDOW_IS_TOPLEVEL (window))
5395 impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
5396 if (!impl->use_synchronized_configure)
5400 if (!GDK_WINDOW_DESTROYED (window))
5402 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
5403 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
5405 if (toplevel && toplevel->update_counter != None &&
5406 GDK_DISPLAY_X11 (display)->use_sync &&
5407 !XSyncValueIsZero (toplevel->current_counter_value))
5409 XSyncSetCounter (GDK_WINDOW_XDISPLAY (window),
5410 toplevel->update_counter,
5411 toplevel->current_counter_value);
5413 XSyncIntToValue (&toplevel->current_counter_value, 0);
5420 _gdk_windowing_window_beep (GdkWindow *window)
5422 GdkDisplay *display;
5424 g_return_if_fail (GDK_IS_WINDOW (window));
5426 display = GDK_WINDOW_DISPLAY (window);
5429 if (GDK_DISPLAY_X11 (display)->use_xkb)
5430 XkbBell (GDK_DISPLAY_XDISPLAY (display),
5431 GDK_WINDOW_XID (window),
5436 gdk_display_beep (display);
5440 * gdk_window_set_opacity:
5441 * @window: a top-level #GdkWindow
5444 * Request the windowing system to make @window partially transparent,
5445 * with opacity 0 being fully transparent and 1 fully opaque. (Values
5446 * of the opacity parameter are clamped to the [0,1] range.)
5448 * On X11, this works only on X screens with a compositing manager
5451 * For setting up per-pixel alpha, see gdk_screen_get_rgba_colormap().
5452 * For making non-toplevel windows translucent, see
5453 * gdk_window_set_composited().
5458 gdk_window_set_opacity (GdkWindow *window,
5461 GdkDisplay *display;
5464 g_return_if_fail (GDK_IS_WINDOW (window));
5466 if (GDK_WINDOW_DESTROYED (window) ||
5467 !WINDOW_IS_TOPLEVEL (window))
5470 display = gdk_drawable_get_display (window);
5474 else if (opacity > 1)
5477 cardinal = opacity * 0xffffffff;
5479 if (cardinal == 0xffffffff)
5480 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
5481 GDK_WINDOW_XID (window),
5482 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_OPACITY"));
5484 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
5485 GDK_WINDOW_XID (window),
5486 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_OPACITY"),
5489 (guchar *) &cardinal, 1);
5493 _gdk_windowing_window_set_composited (GdkWindow *window,
5494 gboolean composited)
5496 #if defined(HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES)
5497 GdkWindowObject *private = (GdkWindowObject *) window;
5498 GdkWindowImplX11 *impl;
5499 GdkDisplay *display;
5503 impl = GDK_WINDOW_IMPL_X11 (private->impl);
5505 display = gdk_screen_get_display (GDK_DRAWABLE_IMPL_X11 (impl)->screen);
5506 dpy = GDK_DISPLAY_XDISPLAY (display);
5507 xid = GDK_WINDOW_XWINDOW (private);
5511 XCompositeRedirectWindow (dpy, xid, CompositeRedirectManual);
5512 impl->damage = XDamageCreate (dpy, xid, XDamageReportBoundingBox);
5516 XCompositeUnredirectWindow (dpy, xid, CompositeRedirectManual);
5517 XDamageDestroy (dpy, impl->damage);
5518 impl->damage = None;
5524 _gdk_windowing_window_process_updates_recurse (GdkWindow *window,
5525 cairo_region_t *region)
5527 _gdk_window_process_updates_recurse (window, region);
5531 _gdk_windowing_before_process_all_updates (void)
5536 _gdk_windowing_after_process_all_updates (void)
5541 gdk_window_impl_iface_init (GdkWindowImplIface *iface)
5543 iface->show = gdk_window_x11_show;
5544 iface->hide = gdk_window_x11_hide;
5545 iface->withdraw = gdk_window_x11_withdraw;
5546 iface->set_events = gdk_window_x11_set_events;
5547 iface->get_events = gdk_window_x11_get_events;
5548 iface->raise = gdk_window_x11_raise;
5549 iface->lower = gdk_window_x11_lower;
5550 iface->restack_under = gdk_window_x11_restack_under;
5551 iface->restack_toplevel = gdk_window_x11_restack_toplevel;
5552 iface->move_resize = gdk_window_x11_move_resize;
5553 iface->set_background = gdk_window_x11_set_background;
5554 iface->set_back_pixmap = gdk_window_x11_set_back_pixmap;
5555 iface->reparent = gdk_window_x11_reparent;
5556 iface->clear_region = gdk_window_x11_clear_region;
5557 iface->set_device_cursor = gdk_window_x11_set_device_cursor;
5558 iface->get_geometry = gdk_window_x11_get_geometry;
5559 iface->get_root_coords = gdk_window_x11_get_root_coords;
5560 iface->get_device_state = gdk_window_x11_get_device_state;
5561 iface->get_deskrelative_origin = gdk_window_x11_get_deskrelative_origin;
5562 iface->shape_combine_region = gdk_window_x11_shape_combine_region;
5563 iface->input_shape_combine_region = gdk_window_x11_input_shape_combine_region;
5564 iface->set_static_gravities = gdk_window_x11_set_static_gravities;
5565 iface->queue_antiexpose = _gdk_x11_window_queue_antiexpose;
5566 iface->queue_translation = _gdk_x11_window_queue_translation;
5567 iface->destroy = _gdk_x11_window_destroy;
5568 iface->supports_native_bg = TRUE;
5572 timestamp_predicate (Display *display,
5576 Window xwindow = GPOINTER_TO_UINT (arg);
5577 GdkDisplay *gdk_display = gdk_x11_lookup_xdisplay (display);
5579 if (xevent->type == PropertyNotify &&
5580 xevent->xproperty.window == xwindow &&
5581 xevent->xproperty.atom == gdk_x11_get_xatom_by_name_for_display (gdk_display,
5582 "GDK_TIMESTAMP_PROP"))
5589 * gdk_x11_get_server_time:
5590 * @window: a #GdkWindow, used for communication with the server.
5591 * The window must have GDK_PROPERTY_CHANGE_MASK in its
5592 * events mask or a hang will result.
5594 * Routine to get the current X server time stamp.
5596 * Return value: the time stamp.
5599 gdk_x11_get_server_time (GdkWindow *window)
5605 Atom timestamp_prop_atom;
5607 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
5608 g_return_val_if_fail (!GDK_WINDOW_DESTROYED (window), 0);
5610 xdisplay = GDK_WINDOW_XDISPLAY (window);
5611 xwindow = GDK_WINDOW_XWINDOW (window);
5612 timestamp_prop_atom =
5613 gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
5614 "GDK_TIMESTAMP_PROP");
5616 XChangeProperty (xdisplay, xwindow, timestamp_prop_atom,
5617 timestamp_prop_atom,
5618 8, PropModeReplace, &c, 1);
5620 XIfEvent (xdisplay, &xevent,
5621 timestamp_predicate, GUINT_TO_POINTER(xwindow));
5623 return xevent.xproperty.time;
5626 #define __GDK_WINDOW_X11_C__
5627 #include "gdkaliasdef.c"