1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include <X11/Xutil.h>
31 #include <X11/Xatom.h>
32 #include <netinet/in.h>
36 #include "gdkwindow.h"
38 #include "gdkinputprivate.h"
39 #include "gdkdisplay-x11.h"
40 #include "gdkprivate-x11.h"
41 #include "gdkregion.h"
42 #include "gdkinternals.h"
44 #include "gdkwindow-x11.h"
52 #include <X11/extensions/shape.h>
55 const int _gdk_event_mask_table[21] =
59 PointerMotionHintMask,
76 SubstructureNotifyMask,
77 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
79 const int _gdk_nenvent_masks = sizeof (_gdk_event_mask_table) / sizeof (int);
81 /* Forward declarations */
82 static void gdk_window_set_static_win_gravity (GdkWindow *window,
84 static gboolean gdk_window_have_shape_ext (GdkDisplay *display);
85 static gboolean gdk_window_icon_name_set (GdkWindow *window);
86 static void gdk_window_add_colormap_windows (GdkWindow *window);
87 static void set_wm_name (GdkDisplay *display,
91 static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
92 static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
94 static void gdk_window_impl_x11_get_size (GdkDrawable *drawable,
97 static GdkRegion* gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable);
98 static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
99 static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
100 static void gdk_window_impl_x11_finalize (GObject *object);
102 static gpointer parent_class = NULL;
104 #define WINDOW_IS_TOPLEVEL(window) \
105 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
106 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
109 gdk_window_impl_x11_get_type (void)
111 static GType object_type = 0;
115 static const GTypeInfo object_info =
117 sizeof (GdkWindowImplX11Class),
118 (GBaseInitFunc) NULL,
119 (GBaseFinalizeFunc) NULL,
120 (GClassInitFunc) gdk_window_impl_x11_class_init,
121 NULL, /* class_finalize */
122 NULL, /* class_data */
123 sizeof (GdkWindowImplX11),
125 (GInstanceInitFunc) gdk_window_impl_x11_init,
128 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
137 _gdk_window_impl_get_type (void)
139 return gdk_window_impl_x11_get_type ();
143 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
147 impl->toplevel_window_type = -1;
151 _gdk_x11_window_get_toplevel (GdkWindow *window)
153 GdkWindowObject *private;
154 GdkWindowImplX11 *impl;
156 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
158 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
161 private = (GdkWindowObject *)window;
162 impl = GDK_WINDOW_IMPL_X11 (private->impl);
165 impl->toplevel = g_new0 (GdkToplevelX11, 1);
167 return impl->toplevel;
171 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
173 GObjectClass *object_class = G_OBJECT_CLASS (klass);
174 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
176 parent_class = g_type_class_peek_parent (klass);
178 object_class->finalize = gdk_window_impl_x11_finalize;
180 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
181 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
182 drawable_class->get_size = gdk_window_impl_x11_get_size;
184 /* Visible and clip regions are the same */
185 drawable_class->get_clip_region = gdk_window_impl_x11_get_visible_region;
186 drawable_class->get_visible_region = gdk_window_impl_x11_get_visible_region;
190 gdk_window_impl_x11_finalize (GObject *object)
192 GdkWindowObject *wrapper;
193 GdkDrawableImplX11 *draw_impl;
194 GdkWindowImplX11 *window_impl;
196 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
198 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
199 window_impl = GDK_WINDOW_IMPL_X11 (object);
201 wrapper = (GdkWindowObject*) draw_impl->wrapper;
203 _gdk_xgrab_check_destroy (GDK_WINDOW (wrapper));
205 if (!GDK_WINDOW_DESTROYED (wrapper))
207 GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
209 _gdk_xid_table_remove (display, draw_impl->xid);
210 if (window_impl->toplevel && window_impl->toplevel->focus_window)
211 _gdk_xid_table_remove (display, window_impl->toplevel->focus_window);
214 if (window_impl->toplevel)
215 g_free (window_impl->toplevel);
217 G_OBJECT_CLASS (parent_class)->finalize (object);
221 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
223 GdkDrawableImplX11 *drawable_impl;
224 GdkWindowImplX11 *window_impl;
226 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
228 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
229 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
231 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
232 drawable_impl->colormap == NULL)
234 XWindowAttributes window_attributes;
237 XGetWindowAttributes (GDK_SCREEN_XDISPLAY (drawable_impl->screen),
241 visual = gdk_x11_screen_lookup_visual (drawable_impl->screen,
242 window_attributes.visual->visualid);
243 drawable_impl->colormap = gdk_x11_colormap_foreign_new (visual,
244 window_attributes.colormap);
247 return drawable_impl->colormap;
251 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
254 GdkWindowImplX11 *impl;
255 GdkDrawableImplX11 *draw_impl;
257 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
259 impl = GDK_WINDOW_IMPL_X11 (drawable);
260 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
262 if (cmap && GDK_WINDOW_DESTROYED (draw_impl->wrapper))
266 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
270 XSetWindowColormap (GDK_SCREEN_XDISPLAY (draw_impl->screen),
272 GDK_COLORMAP_XCOLORMAP (cmap));
274 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
276 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
282 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
286 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
289 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
291 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
295 gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
297 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
298 GdkRectangle result_rect;
302 result_rect.width = impl->width;
303 result_rect.height = impl->height;
305 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
307 return gdk_region_rectangle (&result_rect);
311 _gdk_windowing_window_init (GdkScreen * screen)
313 GdkWindowObject *private;
314 GdkWindowImplX11 *impl;
315 GdkDrawableImplX11 *draw_impl;
316 GdkScreenX11 *screen_x11;
318 screen_x11 = GDK_SCREEN_X11 (screen);
320 g_assert (screen_x11->root_window == NULL);
322 gdk_screen_set_default_colormap (screen,
323 gdk_screen_get_system_colormap (screen));
325 screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
326 private = (GdkWindowObject *)screen_x11->root_window;
327 impl = GDK_WINDOW_IMPL_X11 (private->impl);
328 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
330 draw_impl->screen = screen;
331 draw_impl->xid = screen_x11->xroot_window;
332 draw_impl->wrapper = GDK_DRAWABLE (private);
333 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
334 g_object_ref (draw_impl->colormap);
336 private->window_type = GDK_WINDOW_ROOT;
337 private->depth = DefaultDepthOfScreen (screen_x11->xscreen);
339 impl->width = WidthOfScreen (screen_x11->xscreen);
340 impl->height = HeightOfScreen (screen_x11->xscreen);
342 _gdk_window_init_position (GDK_WINDOW (private));
344 _gdk_xid_table_insert (screen_x11->display,
345 &screen_x11->xroot_window,
346 screen_x11->root_window);
350 set_wm_protocols (GdkWindow *window)
352 GdkDisplay *display = gdk_drawable_get_display (window);
355 protocols[0] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
356 protocols[1] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
357 protocols[2] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
359 XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, 3);
363 get_default_title (void)
367 title = g_get_application_name ();
369 title = g_get_prgname ();
375 check_leader_window_title (GdkDisplay *display)
377 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
379 if (display_x11->leader_window && !display_x11->leader_window_title_set)
381 set_wm_name (display,
382 display_x11->leader_window,
383 get_default_title ());
385 display_x11->leader_window_title_set = TRUE;
390 create_focus_window (Display *xdisplay,
393 Window focus_window = XCreateSimpleWindow (xdisplay, parent,
397 /* FIXME: probably better to actually track the requested event mask for the toplevel
399 XSelectInput (xdisplay, focus_window,
400 KeyPressMask | KeyReleaseMask | FocusChangeMask);
402 XMapWindow (xdisplay, focus_window);
408 setup_toplevel_window (GdkWindow *window, GdkWindow *parent)
410 GdkWindowObject *obj = (GdkWindowObject *)window;
411 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
412 GdkWindowImplX11 *impl = (GdkWindowImplX11 *)obj->impl;
413 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
414 XID xid = GDK_WINDOW_XID (window);
415 XID xparent = GDK_WINDOW_XID (parent);
416 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (parent));
417 XSizeHints size_hints;
420 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
421 XSetTransientForHint (xdisplay, xid, xparent);
423 set_wm_protocols (window);
425 if (!obj->input_only)
427 /* The focus window is off the visible area, and serves to receive key
428 * press events so they don't get sent to child windows.
430 toplevel->focus_window = create_focus_window (xdisplay, xid);
431 _gdk_xid_table_insert (screen_x11->display, &toplevel->focus_window, window);
434 check_leader_window_title (screen_x11->display);
436 /* FIXME: Is there any point in doing this? Do any WM's pay
437 * attention to PSize, and even if they do, is this the
440 size_hints.flags = PSize;
441 size_hints.width = impl->width;
442 size_hints.height = impl->height;
444 XSetWMNormalHints (xdisplay, xid, &size_hints);
446 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
447 XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
450 XChangeProperty (xdisplay, xid,
451 gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_PID"),
456 XChangeProperty (xdisplay, xid,
457 gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"),
458 XA_WINDOW, 32, PropModeReplace,
459 (guchar *) &GDK_DISPLAY_X11 (screen_x11->display)->leader_window, 1);
464 * @parent: a #GdkWindow, or %NULL to create the window as a child of
465 * the default root window for the default display.
466 * @attributes: attributes of the new window
467 * @attributes_mask: mask indicating which fields in @attributes are valid
469 * Creates a new #GdkWindow using the attributes from
470 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
471 * more details. Note: to use this on displays other than the default
472 * display, @parent must be specified.
474 * Return value: the new #GdkWindow
477 gdk_window_new (GdkWindow *parent,
478 GdkWindowAttr *attributes,
479 gint attributes_mask)
482 GdkWindowObject *private;
483 GdkWindowImplX11 *impl;
484 GdkDrawableImplX11 *draw_impl;
485 GdkScreenX11 *screen_x11;
494 XSetWindowAttributes xattributes;
495 long xattributes_mask;
496 XClassHint *class_hint;
503 g_return_val_if_fail (attributes != NULL, NULL);
508 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
510 screen = gdk_screen_get_default ();
511 parent = gdk_screen_get_root_window (screen);
514 screen = gdk_drawable_get_screen (parent);
516 screen_x11 = GDK_SCREEN_X11 (screen);
518 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
520 if (GDK_WINDOW_DESTROYED (parent))
523 xparent = GDK_WINDOW_XID (parent);
525 window = g_object_new (GDK_TYPE_WINDOW, NULL);
526 private = (GdkWindowObject *)window;
527 impl = GDK_WINDOW_IMPL_X11 (private->impl);
528 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
529 draw_impl->wrapper = GDK_DRAWABLE (window);
531 draw_impl->screen = screen;
532 xdisplay = screen_x11->xdisplay;
534 /* Windows with a foreign parent are treated as if they are children
535 * of the root window, except for actual creation.
537 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
538 parent = gdk_screen_get_root_window (screen);
540 private->parent = (GdkWindowObject *)parent;
542 private->accept_focus = TRUE;
544 xattributes_mask = 0;
546 if (attributes_mask & GDK_WA_X)
551 if (attributes_mask & GDK_WA_Y)
558 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
559 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
561 if (attributes->wclass == GDK_INPUT_ONLY)
563 /* Backwards compatiblity - we've always ignored
564 * attributes->window_type for input-only windows
567 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
568 private->window_type = GDK_WINDOW_TEMP;
570 private->window_type = GDK_WINDOW_CHILD;
573 private->window_type = attributes->window_type;
575 _gdk_window_init_position (GDK_WINDOW (private));
576 if (impl->position_info.big)
577 private->guffaw_gravity = TRUE;
579 if (attributes_mask & GDK_WA_VISUAL)
580 visual = attributes->visual;
582 visual = gdk_screen_get_system_visual (screen);
583 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
585 xattributes.event_mask = StructureNotifyMask | PropertyChangeMask;
586 for (i = 0; i < _gdk_nenvent_masks; i++)
588 if (attributes->event_mask & (1 << (i + 1)))
589 xattributes.event_mask |= _gdk_event_mask_table[i];
591 private->event_mask = attributes->event_mask;
593 if (xattributes.event_mask)
594 xattributes_mask |= CWEventMask;
596 if (attributes_mask & GDK_WA_NOREDIR)
598 xattributes.override_redirect =
599 (attributes->override_redirect == FALSE)?False:True;
600 xattributes_mask |= CWOverrideRedirect;
603 xattributes.override_redirect = False;
605 if (private->parent && private->parent->guffaw_gravity)
607 xattributes.win_gravity = StaticGravity;
608 xattributes_mask |= CWWinGravity;
612 switch (private->window_type)
614 case GDK_WINDOW_TOPLEVEL:
615 case GDK_WINDOW_DIALOG:
616 case GDK_WINDOW_TEMP:
617 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
619 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
620 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
621 xparent = GDK_SCREEN_XROOTWIN (screen);
623 case GDK_WINDOW_CHILD:
626 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
630 if (attributes->wclass == GDK_INPUT_OUTPUT)
633 depth = visual->depth;
635 private->input_only = FALSE;
636 private->depth = depth;
638 if (attributes_mask & GDK_WA_COLORMAP)
640 draw_impl->colormap = attributes->colormap;
641 g_object_ref (attributes->colormap);
645 if ((((GdkVisualPrivate *)gdk_screen_get_system_visual (screen))->xvisual) == xvisual)
647 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
648 g_object_ref (draw_impl->colormap);
652 draw_impl->colormap = gdk_colormap_new (visual, FALSE);
656 private->bg_color.pixel = BlackPixel (xdisplay, screen_x11->screen_num);
657 xattributes.background_pixel = private->bg_color.pixel;
659 private->bg_pixmap = NULL;
661 xattributes.border_pixel = BlackPixel (xdisplay, screen_x11->screen_num);
662 xattributes_mask |= CWBorderPixel | CWBackPixel;
664 if (private->guffaw_gravity)
665 xattributes.bit_gravity = StaticGravity;
667 xattributes.bit_gravity = NorthWestGravity;
669 xattributes_mask |= CWBitGravity;
671 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
672 xattributes_mask |= CWColormap;
674 if (private->window_type == GDK_WINDOW_TEMP)
676 xattributes.save_under = True;
677 xattributes.override_redirect = True;
678 xattributes.cursor = None;
679 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
687 private->input_only = TRUE;
688 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
689 g_object_ref (draw_impl->colormap);
692 xid = draw_impl->xid = XCreateWindow (xdisplay, xparent,
693 impl->position_info.x, impl->position_info.y,
694 impl->position_info.width, impl->position_info.height,
695 0, depth, class, xvisual,
696 xattributes_mask, &xattributes);
698 g_object_ref (window);
699 _gdk_xid_table_insert (screen_x11->display, &draw_impl->xid, window);
701 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
702 (attributes->cursor) :
706 private->parent->children = g_list_prepend (private->parent->children, window);
708 switch (GDK_WINDOW_TYPE (private))
710 case GDK_WINDOW_DIALOG:
711 case GDK_WINDOW_TOPLEVEL:
712 case GDK_WINDOW_TEMP:
713 if (attributes_mask & GDK_WA_TITLE)
714 title = attributes->title;
716 title = get_default_title ();
718 gdk_window_set_title (window, title);
720 if (attributes_mask & GDK_WA_WMCLASS)
722 class_hint = XAllocClassHint ();
723 class_hint->res_name = attributes->wmclass_name;
724 class_hint->res_class = attributes->wmclass_class;
725 XSetClassHint (xdisplay, xid, class_hint);
729 setup_toplevel_window (window, parent);
732 case GDK_WINDOW_CHILD:
733 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
734 (draw_impl->colormap != gdk_screen_get_system_colormap (screen)) &&
735 (draw_impl->colormap != gdk_drawable_get_colormap (gdk_window_get_toplevel (window))))
737 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
738 gdk_window_add_colormap_windows (window);
750 x_event_mask_to_gdk_event_mask (long mask)
752 GdkEventMask event_mask = 0;
755 for (i = 0; i < _gdk_nenvent_masks; i++)
757 if (mask & _gdk_event_mask_table[i])
758 event_mask |= 1 << (i + 1);
765 * gdk_window_foreign_new_for_display:
766 * @display: the #GdkDisplay where the window handle comes from.
767 * @anid: a native window handle.
769 * Wraps a native window in a #GdkWindow.
770 * This may fail if the window has been destroyed.
772 * For example in the X backend, a native window handle is an Xlib
775 * Return value: the newly-created #GdkWindow wrapper for the
776 * native window or %NULL if the window has been destroyed.
781 gdk_window_foreign_new_for_display (GdkDisplay *display,
782 GdkNativeWindow anid)
785 GdkWindowObject *private;
786 GdkWindowImplX11 *impl;
787 GdkDrawableImplX11 *draw_impl;
788 GdkDisplayX11 *display_x11;
789 XWindowAttributes attrs;
791 Window *children = NULL;
795 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
797 display_x11 = GDK_DISPLAY_X11 (display);
799 gdk_error_trap_push ();
800 result = XGetWindowAttributes (display_x11->xdisplay, anid, &attrs);
801 if (gdk_error_trap_pop () || !result)
804 /* FIXME: This is pretty expensive. Maybe the caller should supply
806 gdk_error_trap_push ();
807 result = XQueryTree (display_x11->xdisplay, anid, &root, &parent, &children, &nchildren);
808 if (gdk_error_trap_pop () || !result)
814 window = g_object_new (GDK_TYPE_WINDOW, NULL);
815 private = (GdkWindowObject *)window;
816 impl = GDK_WINDOW_IMPL_X11 (private->impl);
817 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
818 draw_impl->wrapper = GDK_DRAWABLE (window);
819 draw_impl->screen = _gdk_x11_display_screen_for_xrootwin (display, root);
821 private->parent = gdk_xid_table_lookup_for_display (display, parent);
823 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
824 private->parent = (GdkWindowObject *) gdk_screen_get_root_window (draw_impl->screen);
826 private->parent->children = g_list_prepend (private->parent->children, window);
828 draw_impl->xid = anid;
830 private->x = attrs.x;
831 private->y = attrs.y;
832 impl->width = attrs.width;
833 impl->height = attrs.height;
834 private->window_type = GDK_WINDOW_FOREIGN;
835 private->destroyed = FALSE;
837 private->event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
839 if (attrs.map_state == IsUnmapped)
840 private->state = GDK_WINDOW_STATE_WITHDRAWN;
844 private->depth = attrs.depth;
846 _gdk_window_init_position (GDK_WINDOW (private));
848 g_object_ref (window);
849 _gdk_xid_table_insert (display, &GDK_WINDOW_XID (window), window);
854 * gdk_window_lookup_for_display:
855 * @display: the #GdkDisplay corresponding to the window handle
856 * @anid: a native window handle.
858 * Looks up the #GdkWindow that wraps the given native window handle.
860 * For example in the X backend, a native window handle is an Xlib
863 * Return value: the #GdkWindow wrapper for the native window,
864 * or %NULL if there is none.
869 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
871 return (GdkWindow*) gdk_xid_table_lookup_for_display (display, anid);
876 * @anid: a native window handle.
878 * Looks up the #GdkWindow that wraps the given native window handle.
880 * For example in the X backend, a native window handle is an Xlib
883 * Return value: the #GdkWindow wrapper for the native window,
884 * or %NULL if there is none.
887 gdk_window_lookup (GdkNativeWindow anid)
889 return (GdkWindow*) gdk_xid_table_lookup (anid);
893 gdk_toplevel_x11_free_contents (GdkToplevelX11 *toplevel)
895 if (toplevel->icon_window)
897 g_object_unref (toplevel->icon_window);
898 toplevel->icon_window = NULL;
900 if (toplevel->icon_pixmap)
902 g_object_unref (toplevel->icon_pixmap);
903 toplevel->icon_pixmap = NULL;
905 if (toplevel->icon_mask)
907 g_object_unref (toplevel->icon_mask);
908 toplevel->icon_mask = NULL;
910 if (toplevel->group_leader)
912 g_object_unref (toplevel->group_leader);
913 toplevel->group_leader = NULL;
918 _gdk_windowing_window_destroy (GdkWindow *window,
920 gboolean foreign_destroy)
922 GdkWindowObject *private = (GdkWindowObject *)window;
923 GdkToplevelX11 *toplevel;
924 GdkDrawableImplX11 *draw_impl;
926 g_return_if_fail (GDK_IS_WINDOW (window));
928 _gdk_selection_window_destroyed (window);
930 if (private->extension_events != 0)
931 _gdk_input_window_destroy (window);
933 toplevel = _gdk_x11_window_get_toplevel (window);
935 gdk_toplevel_x11_free_contents (toplevel);
937 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
939 if (draw_impl->xft_draw)
940 XftDrawDestroy (draw_impl->xft_draw);
942 if (!recursing && !foreign_destroy)
944 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
949 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
951 /* It's somebody else's window, but in our heirarchy,
952 * so reparent it to the root window, and then send
953 * it a delete event, as if we were a WM
955 XClientMessageEvent xevent;
957 gdk_error_trap_push ();
958 gdk_window_hide (window);
959 gdk_window_reparent (window, NULL, 0, 0);
961 xevent.type = ClientMessage;
962 xevent.window = GDK_WINDOW_XID (window);
963 xevent.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
966 xevent.data.l[0] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
968 xevent.data.l[1] = CurrentTime;
969 xevent.data.l[2] = 0;
970 xevent.data.l[3] = 0;
971 xevent.data.l[4] = 0;
973 XSendEvent (GDK_WINDOW_XDISPLAY (window),
974 GDK_WINDOW_XID (window),
975 False, 0, (XEvent *)&xevent);
976 gdk_display_sync (GDK_WINDOW_DISPLAY (window));
977 gdk_error_trap_pop ();
980 /* This function is called when the XWindow is really gone.
983 gdk_window_destroy_notify (GdkWindow *window)
985 GdkWindowImplX11 *window_impl;
987 g_return_if_fail (window != NULL);
989 window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
991 if (!GDK_WINDOW_DESTROYED (window))
993 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
994 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
996 _gdk_window_destroy (window, TRUE);
999 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), GDK_WINDOW_XID (window));
1000 if (window_impl->toplevel && window_impl->toplevel->focus_window)
1001 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), window_impl->toplevel->focus_window);
1003 _gdk_xgrab_check_destroy (window);
1005 g_object_unref (window);
1009 update_wm_hints (GdkWindow *window,
1012 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
1013 GdkWindowObject *private = (GdkWindowObject *)window;
1014 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1018 private->state & GDK_WINDOW_STATE_WITHDRAWN)
1021 wm_hints.flags = StateHint | InputHint;
1022 wm_hints.input = private->accept_focus ? True : False;
1023 wm_hints.initial_state = NormalState;
1025 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1027 wm_hints.flags |= StateHint;
1028 wm_hints.initial_state = IconicState;
1031 if (toplevel->icon_window && !GDK_WINDOW_DESTROYED (toplevel->icon_window))
1033 wm_hints.flags |= IconWindowHint;
1034 wm_hints.icon_window = GDK_WINDOW_XID (toplevel->icon_window);
1037 if (toplevel->icon_pixmap)
1039 wm_hints.flags |= IconPixmapHint;
1040 wm_hints.icon_pixmap = GDK_PIXMAP_XID (toplevel->icon_pixmap);
1043 if (toplevel->icon_mask)
1045 wm_hints.flags |= IconMaskHint;
1046 wm_hints.icon_mask = GDK_PIXMAP_XID (toplevel->icon_mask);
1049 wm_hints.flags |= WindowGroupHint;
1050 if (toplevel->group_leader && !GDK_WINDOW_DESTROYED (toplevel->group_leader))
1052 wm_hints.flags |= WindowGroupHint;
1053 wm_hints.window_group = GDK_WINDOW_XID (toplevel->group_leader);
1056 wm_hints.window_group = GDK_DISPLAY_X11 (display)->leader_window;
1058 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1059 GDK_WINDOW_XID (window),
1064 set_initial_hints (GdkWindow *window)
1066 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1067 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1068 Window xwindow = GDK_WINDOW_XID (window);
1069 GdkWindowObject *private;
1070 GdkToplevelX11 *toplevel;
1074 private = (GdkWindowObject*) window;
1075 toplevel = _gdk_x11_window_get_toplevel (window);
1080 update_wm_hints (window, TRUE);
1082 /* We set the spec hints regardless of whether the spec is supported,
1083 * since it can't hurt and it's kind of expensive to check whether
1089 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1091 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1092 "_NET_WM_STATE_MAXIMIZED_VERT");
1094 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1095 "_NET_WM_STATE_MAXIMIZED_HORZ");
1099 if (private->state & GDK_WINDOW_STATE_STICKY)
1101 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1102 "_NET_WM_STATE_STICKY");
1106 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1108 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1109 "_NET_WM_STATE_FULLSCREEN");
1113 if (private->modal_hint)
1115 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1116 "_NET_WM_STATE_MODAL");
1120 if (toplevel->skip_taskbar_hint)
1122 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1123 "_NET_WM_STATE_SKIP_TASKBAR");
1127 if (toplevel->skip_pager_hint)
1129 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1130 "_NET_WM_STATE_SKIP_PAGER");
1136 XChangeProperty (xdisplay,
1138 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
1139 XA_ATOM, 32, PropModeReplace,
1140 (guchar*) atoms, i);
1144 XDeleteProperty (xdisplay,
1146 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"));
1149 if (private->state & GDK_WINDOW_STATE_STICKY)
1151 atoms[0] = 0xFFFFFFFF;
1152 XChangeProperty (xdisplay,
1154 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
1155 XA_CARDINAL, 32, PropModeReplace,
1156 (guchar*) atoms, 1);
1160 XDeleteProperty (xdisplay,
1162 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"));
1165 toplevel->map_serial = NextRequest (xdisplay);
1169 show_window_internal (GdkWindow *window,
1172 GdkWindowObject *private;
1174 g_return_if_fail (GDK_IS_WINDOW (window));
1176 private = (GdkWindowObject*) window;
1177 if (!private->destroyed)
1179 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1180 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
1181 Window xwindow = GDK_WINDOW_XID (window);
1184 XRaiseWindow (xdisplay, xwindow);
1186 if (!GDK_WINDOW_IS_MAPPED (window))
1188 set_initial_hints (window);
1190 gdk_synthesize_window_state (window,
1191 GDK_WINDOW_STATE_WITHDRAWN,
1195 g_assert (GDK_WINDOW_IS_MAPPED (window));
1197 if (impl->position_info.mapped)
1198 XMapWindow (xdisplay, xwindow);
1203 * gdk_window_show_unraised:
1204 * @window: a #GdkWindow
1206 * Shows a #GdkWindow onscreen, but does not modify its stacking
1207 * order. In contrast, gdk_window_show() will raise the window
1208 * to the top of the window stack.
1210 * On the X11 platform, in Xlib terms, this function calls
1211 * XMapWindow() (it also updates some internal GDK state, which means
1212 * that you can't really use XMapWindow() directly on a GDK window).
1216 gdk_window_show_unraised (GdkWindow *window)
1218 g_return_if_fail (GDK_IS_WINDOW (window));
1220 show_window_internal (window, FALSE);
1225 * @window: a #GdkWindow
1227 * Like gdk_window_show_unraised(), but also raises the window to the
1228 * top of the window stack (moves the window to the front of the
1231 * This function maps a window so it's visible onscreen. Its opposite
1232 * is gdk_window_hide().
1234 * When implementing a #GtkWidget, you should call this function on the widget's
1235 * #GdkWindow as part of the "map" method.
1239 gdk_window_show (GdkWindow *window)
1241 g_return_if_fail (GDK_IS_WINDOW (window));
1243 show_window_internal (window, TRUE);
1248 * @window: a #GdkWindow
1250 * For toplevel windows, withdraws them, so they will no longer be
1251 * known to the window manager; for all windows, unmaps them, so
1252 * they won't be displayed. Normally done automatically as
1253 * part of gtk_widget_hide().
1257 gdk_window_hide (GdkWindow *window)
1259 GdkWindowObject *private;
1261 g_return_if_fail (window != NULL);
1263 private = (GdkWindowObject*) window;
1265 /* We'll get the unmap notify eventually, and handle it then,
1266 * but checking here makes things more consistent if we are
1267 * just doing stuff ourself.
1269 _gdk_xgrab_check_unmap (window,
1270 NextRequest (GDK_WINDOW_XDISPLAY (window)));
1272 /* You can't simply unmap toplevel windows. */
1273 switch (private->window_type)
1275 case GDK_WINDOW_TOPLEVEL:
1276 case GDK_WINDOW_DIALOG:
1277 case GDK_WINDOW_TEMP: /* ? */
1278 gdk_window_withdraw (window);
1282 case GDK_WINDOW_FOREIGN:
1283 case GDK_WINDOW_ROOT:
1284 case GDK_WINDOW_CHILD:
1288 if (!private->destroyed)
1290 if (GDK_WINDOW_IS_MAPPED (window))
1291 gdk_synthesize_window_state (window,
1293 GDK_WINDOW_STATE_WITHDRAWN);
1295 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1297 _gdk_window_clear_update_area (window);
1299 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
1300 GDK_WINDOW_XID (window));
1305 * gdk_window_withdraw:
1306 * @window: a toplevel #GdkWindow
1308 * Withdraws a window (unmaps it and asks the window manager to forget about it).
1309 * This function is not really useful as gdk_window_hide() automatically
1310 * withdraws toplevel windows before hiding them.
1314 gdk_window_withdraw (GdkWindow *window)
1316 GdkWindowObject *private;
1318 g_return_if_fail (window != NULL);
1320 private = (GdkWindowObject*) window;
1321 if (!private->destroyed)
1323 if (GDK_WINDOW_IS_MAPPED (window))
1324 gdk_synthesize_window_state (window,
1326 GDK_WINDOW_STATE_WITHDRAWN);
1328 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1330 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
1331 GDK_WINDOW_XID (window), 0);
1337 * @window: a #GdkWindow
1338 * @x: X coordinate relative to window's parent
1339 * @y: Y coordinate relative to window's parent
1341 * Repositions a window relative to its parent window.
1342 * For toplevel windows, window managers may ignore or modify the move;
1343 * you should probably use gtk_window_move() on a #GtkWindow widget
1344 * anyway, instead of using GDK functions. For child windows,
1345 * the move will reliably succeed.
1347 * If you're also planning to resize the window, use gdk_window_move_resize()
1348 * to both move and resize simultaneously, for a nicer visual effect.
1351 gdk_window_move (GdkWindow *window,
1355 GdkWindowObject *private = (GdkWindowObject *)window;
1356 GdkWindowImplX11 *impl;
1358 g_return_if_fail (window != NULL);
1359 g_return_if_fail (GDK_IS_WINDOW (window));
1361 impl = GDK_WINDOW_IMPL_X11 (private->impl);
1363 if (!GDK_WINDOW_DESTROYED (window))
1365 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1366 _gdk_window_move_resize_child (window, x, y,
1367 impl->width, impl->height);
1370 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
1371 GDK_WINDOW_XID (window),
1378 * gdk_window_resize:
1379 * @window: a #GdkWindow
1380 * @width: new width of the window
1381 * @height: new height of the window
1383 * Resizes @window; for toplevel windows, asks the window manager to resize
1384 * the window. The window manager may not allow the resize. When using GTK+,
1385 * use gtk_window_resize() instead of this low-level GDK function.
1387 * Windows may not be resized below 1x1.
1389 * If you're also planning to move the window, use gdk_window_move_resize()
1390 * to both move and resize simultaneously, for a nicer visual effect.
1393 gdk_window_resize (GdkWindow *window,
1397 GdkWindowObject *private;
1399 g_return_if_fail (window != NULL);
1400 g_return_if_fail (GDK_IS_WINDOW (window));
1407 private = (GdkWindowObject*) window;
1409 if (!GDK_WINDOW_DESTROYED (window))
1411 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1412 _gdk_window_move_resize_child (window, private->x, private->y,
1416 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1418 if (width != impl->width || height != impl->height)
1419 private->resize_count += 1;
1421 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
1422 GDK_WINDOW_XID (window),
1429 * gdk_window_move_resize:
1430 * @window: a #GdkWindow
1431 * @x: new X position relative to window's parent
1432 * @y: new Y position relative to window's parent
1434 * @height: new height
1436 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
1437 * except that both operations are performed at once, avoiding strange
1438 * visual effects. (i.e. the user may be able to see the window first
1439 * move, then resize, if you don't use gdk_window_move_resize().)
1442 gdk_window_move_resize (GdkWindow *window,
1448 GdkWindowObject *private;
1450 g_return_if_fail (window != NULL);
1451 g_return_if_fail (GDK_IS_WINDOW (window));
1458 private = (GdkWindowObject*) window;
1460 if (!GDK_WINDOW_DESTROYED (window))
1462 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1463 _gdk_window_move_resize_child (window, x, y, width, height);
1466 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1468 if (width != impl->width || height != impl->height)
1469 private->resize_count += 1;
1471 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
1472 GDK_WINDOW_XID (window),
1473 x, y, width, height);
1479 * gdk_window_reparent:
1480 * @window: a #GdkWindow
1481 * @new_parent: new parent to move @window into
1482 * @x: X location inside the new parent
1483 * @y: Y location inside the new parent
1485 * Reparents @window into the given @new_parent. The window being
1486 * reparented will be unmapped as a side effect.
1490 gdk_window_reparent (GdkWindow *window,
1491 GdkWindow *new_parent,
1495 GdkDisplay *display;
1496 GdkWindowObject *window_private;
1497 GdkWindowObject *parent_private;
1498 GdkWindowObject *old_parent_private;
1499 GdkWindowImplX11 *impl;
1500 gboolean was_toplevel;
1502 g_return_if_fail (window != NULL);
1503 g_return_if_fail (GDK_IS_WINDOW (window));
1504 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1505 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1507 if (GDK_WINDOW_DESTROYED (window) ||
1508 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1514 new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1516 display = GDK_WINDOW_DISPLAY (window);
1518 window_private = (GdkWindowObject*) window;
1519 old_parent_private = (GdkWindowObject*)window_private->parent;
1520 parent_private = (GdkWindowObject*) new_parent;
1521 impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
1523 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1524 GDK_WINDOW_XID (window),
1525 GDK_WINDOW_XID (new_parent),
1528 window_private->x = x;
1529 window_private->y = y;
1531 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1534 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1535 new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1537 window_private->parent = (GdkWindowObject *)new_parent;
1539 /* Switch the window type as appropriate */
1541 switch (GDK_WINDOW_TYPE (new_parent))
1543 case GDK_WINDOW_ROOT:
1544 case GDK_WINDOW_FOREIGN:
1545 was_toplevel = WINDOW_IS_TOPLEVEL (window);
1547 if (impl->toplevel_window_type != -1)
1548 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1549 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1550 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1552 if (WINDOW_IS_TOPLEVEL (window) && !was_toplevel)
1553 setup_toplevel_window (window, new_parent);
1555 case GDK_WINDOW_TOPLEVEL:
1556 case GDK_WINDOW_CHILD:
1557 case GDK_WINDOW_DIALOG:
1558 case GDK_WINDOW_TEMP:
1559 if (WINDOW_IS_TOPLEVEL (window))
1561 /* Save the original window type so we can restore it if the
1562 * window is reparented back to be a toplevel
1564 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1565 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1568 if (impl->toplevel->focus_window)
1570 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window);
1571 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
1574 gdk_toplevel_x11_free_contents (impl->toplevel);
1575 g_free (impl->toplevel);
1576 impl->toplevel = NULL;
1581 if (old_parent_private)
1582 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1584 if ((old_parent_private &&
1585 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1586 (!old_parent_private && parent_private->guffaw_gravity))
1587 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1589 parent_private->children = g_list_prepend (parent_private->children, window);
1590 _gdk_window_init_position (GDK_WINDOW (window_private));
1594 _gdk_windowing_window_clear_area (GdkWindow *window,
1600 g_return_if_fail (window != NULL);
1601 g_return_if_fail (GDK_IS_WINDOW (window));
1603 if (!GDK_WINDOW_DESTROYED (window))
1604 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1605 x, y, width, height, False);
1609 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1615 g_return_if_fail (window != NULL);
1616 g_return_if_fail (GDK_IS_WINDOW (window));
1618 if (!GDK_WINDOW_DESTROYED (window))
1619 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1620 x, y, width, height, True);
1626 * @window: a #GdkWindow
1628 * Raises @window to the top of the Z-order (stacking order), so that
1629 * other windows with the same parent window appear below @window.
1630 * This is true whether or not the windows are visible.
1632 * If @window is a toplevel, the window manager may choose to deny the
1633 * request to move the window in the Z-order, gdk_window_raise() only
1634 * requests the restack, does not guarantee it.
1638 gdk_window_raise (GdkWindow *window)
1640 g_return_if_fail (window != NULL);
1641 g_return_if_fail (GDK_IS_WINDOW (window));
1643 if (!GDK_WINDOW_DESTROYED (window))
1644 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1649 * @window: a #GdkWindow
1651 * Lowers @window to the bottom of the Z-order (stacking order), so that
1652 * other windows with the same parent window appear above @window.
1653 * This is true whether or not the other windows are visible.
1655 * If @window is a toplevel, the window manager may choose to deny the
1656 * request to move the window in the Z-order, gdk_window_lower() only
1657 * requests the restack, does not guarantee it.
1659 * Note that gdk_window_show() raises the window again, so don't call this
1660 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
1664 gdk_window_lower (GdkWindow *window)
1666 g_return_if_fail (window != NULL);
1667 g_return_if_fail (GDK_IS_WINDOW (window));
1669 if (!GDK_WINDOW_DESTROYED (window))
1670 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1675 * @window: a #GdkWindow
1676 * @timestamp: timestamp of the event triggering the window focus
1678 * Sets keyboard focus to @window. If @window is not onscreen this
1679 * will not work. In most cases, gtk_window_present() should be used on
1680 * a #GtkWindow, rather than calling this function.
1684 gdk_window_focus (GdkWindow *window,
1687 GdkDisplay *display;
1689 g_return_if_fail (GDK_IS_WINDOW (window));
1691 if (GDK_WINDOW_DESTROYED (window))
1694 display = GDK_WINDOW_DISPLAY (window);
1696 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
1697 gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
1701 xev.xclient.type = ClientMessage;
1702 xev.xclient.serial = 0;
1703 xev.xclient.send_event = True;
1704 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
1705 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
1706 "_NET_ACTIVE_WINDOW");
1707 xev.xclient.format = 32;
1708 xev.xclient.data.l[0] = 0;
1709 xev.xclient.data.l[1] = 0;
1710 xev.xclient.data.l[2] = 0;
1711 xev.xclient.data.l[3] = 0;
1712 xev.xclient.data.l[4] = 0;
1714 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
1715 SubstructureRedirectMask | SubstructureNotifyMask,
1720 XRaiseWindow (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window));
1722 /* There is no way of knowing reliably whether we are viewable;
1723 * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
1725 _gdk_x11_set_input_focus_safe (display, GDK_WINDOW_XID (window),
1732 * gdk_window_set_hints:
1733 * @window: a #GdkWindow
1734 * @x: ignored field, does not matter
1735 * @y: ignored field, does not matter
1736 * @min_width: minimum width hint
1737 * @min_height: minimum height hint
1738 * @max_width: max width hint
1739 * @max_height: max height hint
1740 * @flags: logical OR of GDK_HINT_POS, GDK_HINT_MIN_SIZE, and/or GDK_HINT_MAX_SIZE
1742 * This function is broken and useless and you should ignore it.
1743 * If using GTK+, use functions such as gtk_window_resize(), gtk_window_set_size_request(),
1744 * gtk_window_move(), gtk_window_parse_geometry(), and gtk_window_set_geometry_hints(),
1745 * depending on what you're trying to do.
1747 * If using GDK directly, use gdk_window_set_geometry_hints().
1751 gdk_window_set_hints (GdkWindow *window,
1760 XSizeHints size_hints;
1762 g_return_if_fail (window != NULL);
1763 g_return_if_fail (GDK_IS_WINDOW (window));
1765 if (GDK_WINDOW_DESTROYED (window))
1768 size_hints.flags = 0;
1770 if (flags & GDK_HINT_POS)
1772 size_hints.flags |= PPosition;
1777 if (flags & GDK_HINT_MIN_SIZE)
1779 size_hints.flags |= PMinSize;
1780 size_hints.min_width = min_width;
1781 size_hints.min_height = min_height;
1784 if (flags & GDK_HINT_MAX_SIZE)
1786 size_hints.flags |= PMaxSize;
1787 size_hints.max_width = max_width;
1788 size_hints.max_height = max_height;
1791 /* FIXME: Would it be better to delete this property if
1792 * flags == 0? It would save space on the server
1794 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1795 GDK_WINDOW_XID (window),
1800 * gdk_window_set_type_hint:
1801 * @window: A toplevel #GdkWindow
1802 * @hint: A hint of the function this window will have
1804 * The application can use this call to provide a hint to the window
1805 * manager about the functionality of a window. The window manager
1806 * can use this information when determining the decoration and behaviour
1809 * The hint must be set before the window is mapped.
1812 gdk_window_set_type_hint (GdkWindow *window,
1813 GdkWindowTypeHint hint)
1815 GdkDisplay *display;
1818 g_return_if_fail (window != NULL);
1819 g_return_if_fail (GDK_IS_WINDOW (window));
1821 if (GDK_WINDOW_DESTROYED (window))
1824 display = gdk_drawable_get_display (window);
1828 case GDK_WINDOW_TYPE_HINT_DIALOG:
1829 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
1831 case GDK_WINDOW_TYPE_HINT_MENU:
1832 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU");
1834 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1835 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR");
1837 case GDK_WINDOW_TYPE_HINT_UTILITY:
1838 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
1840 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
1841 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
1843 case GDK_WINDOW_TYPE_HINT_DOCK:
1844 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
1846 case GDK_WINDOW_TYPE_HINT_DESKTOP:
1847 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
1850 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
1852 case GDK_WINDOW_TYPE_HINT_NORMAL:
1853 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL");
1857 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
1858 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
1859 XA_ATOM, 32, PropModeReplace,
1860 (guchar *)&atom, 1);
1865 gdk_wmspec_change_state (gboolean add,
1870 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1873 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
1874 #define _NET_WM_STATE_ADD 1 /* add/set property */
1875 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
1877 xev.xclient.type = ClientMessage;
1878 xev.xclient.serial = 0;
1879 xev.xclient.send_event = True;
1880 xev.xclient.window = GDK_WINDOW_XID (window);
1881 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
1882 xev.xclient.format = 32;
1883 xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1884 xev.xclient.data.l[1] = gdk_x11_atom_to_xatom_for_display (display, state1);
1885 xev.xclient.data.l[2] = gdk_x11_atom_to_xatom_for_display (display, state2);
1886 xev.xclient.data.l[3] = 0;
1887 xev.xclient.data.l[4] = 0;
1889 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
1890 SubstructureRedirectMask | SubstructureNotifyMask,
1895 * gdk_window_set_modal_hint:
1896 * @window: A toplevel #GdkWindow
1897 * @modal: TRUE if the window is modal, FALSE otherwise.
1899 * The application can use this hint to tell the window manager
1900 * that a certain window has modal behaviour. The window manager
1901 * can use this information to handle modal windows in a special
1904 * You should only use this on windows for which you have
1905 * previously called #gdk_window_set_transient_for()
1908 gdk_window_set_modal_hint (GdkWindow *window,
1911 GdkWindowObject *private;
1913 g_return_if_fail (window != NULL);
1914 g_return_if_fail (GDK_IS_WINDOW (window));
1916 if (GDK_WINDOW_DESTROYED (window))
1919 private = (GdkWindowObject*) window;
1921 private->modal_hint = modal;
1923 if (GDK_WINDOW_IS_MAPPED (window))
1924 gdk_wmspec_change_state (modal, window,
1925 gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE),
1930 * gdk_window_set_skip_taskbar_hint:
1931 * @window: a toplevel #GdkWindow
1932 * @skips_taskbar: %TRUE to skip the taskbar
1934 * Toggles whether a window should appear in a task list or window
1935 * list. If a window's semantic type as specified with
1936 * gdk_window_set_type_hint() already fully describes the window, this
1937 * function should NOT be called in addition, instead you should allow
1938 * the window to be treated according to standard policy for its
1944 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
1945 gboolean skips_taskbar)
1947 GdkToplevelX11 *toplevel;
1949 g_return_if_fail (window != NULL);
1950 g_return_if_fail (GDK_IS_WINDOW (window));
1951 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1953 if (GDK_WINDOW_DESTROYED (window))
1956 toplevel = _gdk_x11_window_get_toplevel (window);
1957 toplevel->skip_taskbar_hint = skips_taskbar;
1959 if (GDK_WINDOW_IS_MAPPED (window))
1960 gdk_wmspec_change_state (skips_taskbar, window,
1961 gdk_atom_intern ("_NET_WM_STATE_SKIP_TASKBAR", FALSE),
1966 * gdk_window_set_skip_pager_hint:
1967 * @window: a toplevel #GdkWindow
1968 * @skips_pager: %TRUE to skip the pager
1970 * Toggles whether a window should appear in a pager (workspace
1971 * switcher, or other desktop utility program that displays a small
1972 * thumbnail representation of the windows on the desktop). If a
1973 * window's semantic type as specified with gdk_window_set_type_hint()
1974 * already fully describes the window, this function should NOT be
1975 * called in addition, instead you should allow the window to be
1976 * treated according to standard policy for its semantic type.
1981 gdk_window_set_skip_pager_hint (GdkWindow *window,
1982 gboolean skips_pager)
1984 GdkToplevelX11 *toplevel;
1986 g_return_if_fail (window != NULL);
1987 g_return_if_fail (GDK_IS_WINDOW (window));
1988 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
1990 if (GDK_WINDOW_DESTROYED (window))
1993 toplevel = _gdk_x11_window_get_toplevel (window);
1994 toplevel->skip_pager_hint = skips_pager;
1996 if (GDK_WINDOW_IS_MAPPED (window))
1997 gdk_wmspec_change_state (skips_pager, window,
1998 gdk_atom_intern ("_NET_WM_STATE_SKIP_PAGER", FALSE),
2003 * gdk_window_set_geometry_hints:
2004 * @window: a toplevel #GdkWindow
2005 * @geometry: geometry hints
2006 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
2008 * Sets the geometry hints for @window. Hints flagged in @geom_mask
2009 * are set, hints not flagged in @geom_mask are unset.
2010 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
2012 * This function provides hints to the windowing system about
2013 * acceptable sizes for a toplevel window. The purpose of
2014 * this is to constrain user resizing, but the windowing system
2015 * will typically (but is not required to) also constrain the
2016 * current size of the window to the provided values and
2017 * constrain programatic resizing via gdk_window_resize() or
2018 * gdk_window_move_resize().
2020 * Note that on X11, this effect has no effect on windows
2021 * of type GDK_WINDOW_TEMP or windows where override_redirect
2022 * has been turned on via gdk_window_set_override_redirect()
2023 * since these windows are not resizable by the user.
2025 * Since you can't count on the windowing system doing the
2026 * constraints for programmatic resizes, you should generally
2027 * call gdk_window_constrain_size() yourself to determine
2028 * appropriate sizes.
2032 gdk_window_set_geometry_hints (GdkWindow *window,
2033 GdkGeometry *geometry,
2034 GdkWindowHints geom_mask)
2036 XSizeHints size_hints;
2038 g_return_if_fail (window != NULL);
2039 g_return_if_fail (GDK_IS_WINDOW (window));
2041 if (GDK_WINDOW_DESTROYED (window))
2044 size_hints.flags = 0;
2046 if (geom_mask & GDK_HINT_POS)
2048 size_hints.flags |= PPosition;
2049 /* We need to initialize the following obsolete fields because KWM
2050 * apparently uses these fields if they are non-zero.
2057 if (geom_mask & GDK_HINT_USER_POS)
2059 size_hints.flags |= USPosition;
2062 if (geom_mask & GDK_HINT_USER_SIZE)
2064 size_hints.flags |= USSize;
2067 if (geom_mask & GDK_HINT_MIN_SIZE)
2069 size_hints.flags |= PMinSize;
2070 size_hints.min_width = geometry->min_width;
2071 size_hints.min_height = geometry->min_height;
2074 if (geom_mask & GDK_HINT_MAX_SIZE)
2076 size_hints.flags |= PMaxSize;
2077 size_hints.max_width = MAX (geometry->max_width, 1);
2078 size_hints.max_height = MAX (geometry->max_height, 1);
2081 if (geom_mask & GDK_HINT_BASE_SIZE)
2083 size_hints.flags |= PBaseSize;
2084 size_hints.base_width = geometry->base_width;
2085 size_hints.base_height = geometry->base_height;
2088 if (geom_mask & GDK_HINT_RESIZE_INC)
2090 size_hints.flags |= PResizeInc;
2091 size_hints.width_inc = geometry->width_inc;
2092 size_hints.height_inc = geometry->height_inc;
2095 if (geom_mask & GDK_HINT_ASPECT)
2097 size_hints.flags |= PAspect;
2098 if (geometry->min_aspect <= 1)
2100 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
2101 size_hints.min_aspect.y = 65536;
2105 size_hints.min_aspect.x = 65536;
2106 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
2108 if (geometry->max_aspect <= 1)
2110 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
2111 size_hints.max_aspect.y = 65536;
2115 size_hints.max_aspect.x = 65536;
2116 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
2120 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2122 size_hints.flags |= PWinGravity;
2123 size_hints.win_gravity = geometry->win_gravity;
2126 /* FIXME: Would it be better to delete this property if
2127 * geom_mask == 0? It would save space on the server
2129 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2130 GDK_WINDOW_XID (window),
2135 gdk_window_get_geometry_hints (GdkWindow *window,
2136 GdkGeometry *geometry,
2137 GdkWindowHints *geom_mask)
2139 XSizeHints size_hints;
2140 glong junk_size_mask = 0;
2142 g_return_if_fail (GDK_IS_WINDOW (window));
2143 g_return_if_fail (geometry != NULL);
2144 g_return_if_fail (geom_mask != NULL);
2148 if (GDK_WINDOW_DESTROYED (window))
2151 if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2152 GDK_WINDOW_XID (window),
2157 if (size_hints.flags & PMinSize)
2159 *geom_mask |= GDK_HINT_MIN_SIZE;
2160 geometry->min_width = size_hints.min_width;
2161 geometry->min_height = size_hints.min_height;
2164 if (size_hints.flags & PMaxSize)
2166 *geom_mask |= GDK_HINT_MAX_SIZE;
2167 geometry->max_width = MAX (size_hints.max_width, 1);
2168 geometry->max_height = MAX (size_hints.max_height, 1);
2171 if (size_hints.flags & PResizeInc)
2173 *geom_mask |= GDK_HINT_RESIZE_INC;
2174 geometry->width_inc = size_hints.width_inc;
2175 geometry->height_inc = size_hints.height_inc;
2178 if (size_hints.flags & PAspect)
2180 *geom_mask |= GDK_HINT_ASPECT;
2182 geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
2183 geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
2186 if (size_hints.flags & PWinGravity)
2188 *geom_mask |= GDK_HINT_WIN_GRAVITY;
2189 geometry->win_gravity = size_hints.win_gravity;
2194 utf8_is_latin1 (const gchar *str)
2196 const char *p = str;
2200 gunichar ch = g_utf8_get_char (p);
2205 p = g_utf8_next_char (p);
2211 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
2212 * convertable to STRING, otherwise, set it as compound text
2215 set_text_property (GdkDisplay *display,
2218 const gchar *utf8_str)
2220 guchar *prop_text = NULL;
2224 gboolean is_compound_text;
2226 if (utf8_is_latin1 (utf8_str))
2228 prop_type = XA_STRING;
2229 prop_text = gdk_utf8_to_string_target (utf8_str);
2230 prop_length = prop_text ? strlen (prop_text) : 0;
2232 is_compound_text = FALSE;
2238 gdk_utf8_to_compound_text_for_display (display,
2239 utf8_str, &gdk_type, &prop_format,
2240 &prop_text, &prop_length);
2241 prop_type = gdk_x11_atom_to_xatom_for_display (display, gdk_type);
2242 is_compound_text = TRUE;
2247 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
2250 prop_type, prop_format,
2251 PropModeReplace, prop_text,
2254 if (is_compound_text)
2255 gdk_free_compound_text (prop_text);
2261 /* Set WM_NAME and _NET_WM_NAME
2264 set_wm_name (GdkDisplay *display,
2268 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
2269 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
2270 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2271 PropModeReplace, name, strlen (name));
2273 set_text_property (display, xwindow,
2274 gdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"),
2279 * gdk_window_set_title:
2280 * @window: a toplevel #GdkWindow
2281 * @title: title of @window
2283 * Sets the title of a toplevel window, to be displayed in the titlebar.
2284 * If you haven't explicitly set the icon name for the window
2285 * (using gdk_window_set_icon_name()), the icon name will be set to
2286 * @title as well. @title must be in UTF-8 encoding (as with all
2287 * user-readable strings in GDK/GTK+). @title may not be %NULL.
2290 gdk_window_set_title (GdkWindow *window,
2293 GdkDisplay *display;
2297 g_return_if_fail (window != NULL);
2298 g_return_if_fail (GDK_IS_WINDOW (window));
2299 g_return_if_fail (title != NULL);
2301 if (GDK_WINDOW_DESTROYED (window))
2304 display = gdk_drawable_get_display (window);
2305 xdisplay = GDK_DISPLAY_XDISPLAY (display);
2306 xwindow = GDK_WINDOW_XID (window);
2308 set_wm_name (display, xwindow, title);
2310 if (!gdk_window_icon_name_set (window))
2312 XChangeProperty (xdisplay, xwindow,
2313 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
2314 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2315 PropModeReplace, title, strlen (title));
2317 set_text_property (display, xwindow,
2318 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
2324 * gdk_window_set_role:
2325 * @window: a toplevel #GdkWindow
2326 * @role: a string indicating its role
2328 * When using GTK+, typically you should use gtk_window_set_role() instead
2329 * of this low-level function.
2331 * The window manager and session manager use a window's role to
2332 * distinguish it from other kinds of window in the same application.
2333 * When an application is restarted after being saved in a previous
2334 * session, all windows with the same title and role are treated as
2335 * interchangeable. So if you have two windows with the same title
2336 * that should be distinguished for session management purposes, you
2337 * should set the role on those windows. It doesn't matter what string
2338 * you use for the role, as long as you have a different role for each
2339 * non-interchangeable kind of window.
2343 gdk_window_set_role (GdkWindow *window,
2346 GdkDisplay *display;
2348 g_return_if_fail (window != NULL);
2349 g_return_if_fail (GDK_IS_WINDOW (window));
2351 display = gdk_drawable_get_display (window);
2353 if (!GDK_WINDOW_DESTROYED (window))
2356 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2357 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
2358 XA_STRING, 8, PropModeReplace, role, strlen (role));
2360 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2361 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
2366 * gdk_window_set_transient_for:
2367 * @window: a toplevel #GdkWindow
2368 * @parent: another toplevel #GdkWindow
2370 * Indicates to the window manager that @window is a transient dialog
2371 * associated with the application window @parent. This allows the
2372 * window manager to do things like center @window on @parent and
2373 * keep @window above @parent.
2375 * See gtk_window_set_transient_for() if you're using #GtkWindow or
2380 gdk_window_set_transient_for (GdkWindow *window,
2383 GdkWindowObject *private;
2384 GdkWindowObject *parent_private;
2386 g_return_if_fail (window != NULL);
2387 g_return_if_fail (GDK_IS_WINDOW (window));
2389 private = (GdkWindowObject*) window;
2390 parent_private = (GdkWindowObject*) parent;
2392 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
2393 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
2394 GDK_WINDOW_XID (window),
2395 GDK_WINDOW_XID (parent));
2399 * gdk_window_set_background:
2400 * @window: a #GdkWindow
2401 * @color: an allocated #GdkColor
2403 * Sets the background color of @window. (However, when using GTK+,
2404 * set the background of a widget with gtk_widget_modify_bg() - if
2405 * you're an application - or gtk_style_set_background() - if you're
2406 * implementing a custom widget.)
2408 * The @color must be allocated; gdk_rgb_find_color() is the best way
2409 * to allocate a color.
2411 * See also gdk_window_set_back_pixmap().
2415 gdk_window_set_background (GdkWindow *window,
2416 const GdkColor *color)
2418 GdkWindowObject *private = (GdkWindowObject *)window;
2420 g_return_if_fail (window != NULL);
2421 g_return_if_fail (GDK_IS_WINDOW (window));
2423 if (!GDK_WINDOW_DESTROYED (window))
2424 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
2425 GDK_WINDOW_XID (window), color->pixel);
2427 private->bg_color = *color;
2429 if (private->bg_pixmap &&
2430 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2431 private->bg_pixmap != GDK_NO_BG)
2432 g_object_unref (private->bg_pixmap);
2434 private->bg_pixmap = NULL;
2438 * gdk_window_set_back_pixmap:
2439 * @window: a #GdkWindow
2440 * @pixmap: a #GdkPixmap, or %NULL
2441 * @parent_relative: whether the tiling origin is at the origin of @window's parent
2443 * Sets the background pixmap of @window. May also be used to set a background of
2444 * "None" on @window, by setting a background pixmap of %NULL.
2445 * A background pixmap will be tiled, positioning the first tile at the origin of
2446 * @window, or if @parent_relative is %TRUE, the tiling will be done based on the
2447 * origin of the parent window (useful to align tiles in a parent with tiles
2450 * A background pixmap of %NULL means that the window will have no
2451 * background. A window with no background will never have its
2452 * background filled by the windowing system, instead the window will
2453 * contain whatever pixels were already in the corresponding area of
2456 * The windowing system will normally fill a window with its background
2457 * when the window is obscured then exposed, and when you call
2458 * gdk_window_clear().
2462 gdk_window_set_back_pixmap (GdkWindow *window,
2464 gboolean parent_relative)
2466 GdkWindowObject *private = (GdkWindowObject *)window;
2469 g_return_if_fail (window != NULL);
2470 g_return_if_fail (GDK_IS_WINDOW (window));
2471 g_return_if_fail (pixmap == NULL || !parent_relative);
2472 g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
2474 if (private->bg_pixmap &&
2475 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2476 private->bg_pixmap != GDK_NO_BG)
2477 g_object_unref (private->bg_pixmap);
2479 if (parent_relative)
2481 xpixmap = ParentRelative;
2482 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
2488 g_object_ref (pixmap);
2489 private->bg_pixmap = pixmap;
2490 xpixmap = GDK_PIXMAP_XID (pixmap);
2495 private->bg_pixmap = GDK_NO_BG;
2499 if (!GDK_WINDOW_DESTROYED (window))
2500 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2501 GDK_WINDOW_XID (window), xpixmap);
2505 * gdk_window_set_cursor:
2506 * @window: a #GdkWindow
2509 * Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new() or
2510 * gdk_cursor_new_from_pixmap() to create the cursor.
2511 * To make the cursor invisible, use gdk_cursor_new_from_pixmap() to create
2512 * a cursor with no pixels in it. Passing %NULL for the @cursor argument
2513 * to gdk_window_set_cursor() means that @window will use the cursor of
2514 * its parent window. Most windows should use this default.
2518 gdk_window_set_cursor (GdkWindow *window,
2521 GdkCursorPrivate *cursor_private;
2524 g_return_if_fail (window != NULL);
2525 g_return_if_fail (GDK_IS_WINDOW (window));
2527 cursor_private = (GdkCursorPrivate*) cursor;
2532 xcursor = cursor_private->xcursor;
2534 if (!GDK_WINDOW_DESTROYED (window))
2535 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
2536 GDK_WINDOW_XID (window),
2541 * gdk_window_get_geometry:
2542 * @window: a #GdkWindow
2543 * @x: return location for X coordinate of window (relative to its parent)
2544 * @y: return location for Y coordinate of window (relative to its parent)
2545 * @width: return location for width of window
2546 * @height: return location for height of window
2547 * @depth: return location for bit depth of window
2549 * Any of the return location arguments to this function may be %NULL,
2550 * if you aren't interested in getting the value of that field.
2552 * The X and Y coordinates returned are relative to the parent window
2553 * of @window, which for toplevels usually means relative to the
2554 * window decorations (titlebar, etc.) rather than relative to the
2555 * root window (screen-size background window).
2557 * On the X11 platform, the geometry is obtained from the X server,
2558 * so reflects the latest position of @window; this may be out-of-sync
2559 * with the position of @window delivered in the most-recently-processed
2560 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
2561 * position from the most recent configure event.
2565 gdk_window_get_geometry (GdkWindow *window,
2577 guint tborder_width;
2580 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2584 GDK_NOTE (MULTIHEAD,
2585 g_message ("gdk_window_get_geometry(): Window needs to be non-NULL to be multi head safe"));
2586 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
2589 if (!GDK_WINDOW_DESTROYED (window))
2591 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
2592 GDK_WINDOW_XID (window),
2593 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
2609 * gdk_window_get_origin:
2610 * @window: a #GdkWindow
2611 * @x: return location for X coordinate
2612 * @y: return location for Y coordinate
2614 * Obtains the position of a window in root window coordinates.
2615 * (Compare with gdk_window_get_position() and
2616 * gdk_window_get_geometry() which return the position of a window
2617 * relative to its parent window.)
2619 * Return value: not meaningful, ignore
2622 gdk_window_get_origin (GdkWindow *window,
2631 g_return_val_if_fail (window != NULL, 0);
2633 if (!GDK_WINDOW_DESTROYED (window))
2635 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2636 GDK_WINDOW_XID (window),
2637 GDK_WINDOW_XROOTWIN (window),
2653 * gdk_window_get_deskrelative_origin:
2654 * @window: a toplevel #GdkWindow
2655 * @x: return location for X coordinate
2656 * @y: return location for Y coordinate
2658 * This gets the origin of a #GdkWindow relative to
2659 * an Enlightenment-window-manager desktop. As long as you don't
2660 * assume that the user's desktop/workspace covers the entire
2661 * root window (i.e. you don't assume that the desktop begins
2662 * at root window coordinate 0,0) this function is not necessary.
2663 * It's deprecated for that reason.
2665 * Return value: not meaningful
2668 gdk_window_get_deskrelative_origin (GdkWindow *window,
2672 gboolean return_val = FALSE;
2673 gint num_children, format_return;
2674 Window win, *child, parent, root;
2679 gulong number_return, bytes_after_return;
2680 guchar *data_return;
2682 g_return_val_if_fail (window != NULL, FALSE);
2683 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
2685 if (!GDK_WINDOW_DESTROYED (window))
2687 atom = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
2688 "ENLIGHTENMENT_DESKTOP");
2689 win = GDK_WINDOW_XID (window);
2691 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
2692 &child, (unsigned int *)&num_children))
2694 if ((child) && (num_children > 0))
2706 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
2707 False, XA_CARDINAL, &type_return, &format_return,
2708 &number_return, &bytes_after_return, &data_return);
2710 if (type_return == XA_CARDINAL)
2712 XFree (data_return);
2717 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2718 GDK_WINDOW_XID (window),
2733 * gdk_window_get_root_origin:
2734 * @window: a toplevel #GdkWindow
2735 * @x: return location for X position of window frame
2736 * @y: return location for Y position of window frame
2738 * Obtains the top-left corner of the window manager frame in root
2739 * window coordinates.
2743 gdk_window_get_root_origin (GdkWindow *window,
2749 g_return_if_fail (GDK_IS_WINDOW (window));
2751 gdk_window_get_frame_extents (window, &rect);
2761 * gdk_window_get_frame_extents:
2762 * @window: a toplevel #GdkWindow
2763 * @rect: rectangle to fill with bounding box of the window frame
2765 * Obtains the bounding box of the window, including window manager
2766 * titlebar/borders if any. The frame position is given in root window
2767 * coordinates. To get the position of the window itself (rather than
2768 * the frame) in root window coordinates, use gdk_window_get_origin().
2772 gdk_window_get_frame_extents (GdkWindow *window,
2775 GdkWindowObject *private;
2780 unsigned int nchildren;
2782 g_return_if_fail (GDK_IS_WINDOW (window));
2783 g_return_if_fail (rect != NULL);
2785 private = (GdkWindowObject*) window;
2792 if (GDK_WINDOW_DESTROYED (window))
2795 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2796 private = (GdkWindowObject*) private->parent;
2798 /* Refine our fallback answer a bit using local information */
2799 rect->x = private->x;
2800 rect->y = private->y;
2801 gdk_drawable_get_size ((GdkDrawable *)private, &rect->width, &rect->height);
2803 if (GDK_WINDOW_DESTROYED (private))
2806 gdk_error_trap_push();
2808 xparent = GDK_WINDOW_XID (window);
2812 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
2814 &children, &nchildren))
2820 while (xparent != root);
2822 if (xparent == root)
2824 unsigned int ww, wh, wb, wd;
2827 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
2837 gdk_error_trap_pop ();
2841 _gdk_windowing_get_pointer (GdkDisplay *display,
2845 GdkModifierType *mask)
2847 GdkScreen *default_screen;
2855 if (display->closed)
2858 default_screen = gdk_display_get_default_screen (display);
2860 XQueryPointer (GDK_SCREEN_XDISPLAY (default_screen),
2861 GDK_SCREEN_XROOTWIN (default_screen),
2862 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
2866 GdkWindow *gdk_root = gdk_window_lookup_for_display (display, root);
2867 *screen = gdk_drawable_get_screen (gdk_root);
2876 _gdk_windowing_window_get_pointer (GdkDisplay *display,
2880 GdkModifierType *mask)
2882 GdkWindow *return_val;
2888 unsigned int xmask = 0;
2889 gint xoffset, yoffset;
2891 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2893 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2896 if (!GDK_WINDOW_DESTROYED (window) &&
2897 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
2898 GDK_WINDOW_XID (window),
2899 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
2902 return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child);
2905 *x = winx + xoffset;
2906 *y = winy + yoffset;
2913 _gdk_windowing_window_at_pointer (GdkDisplay *display,
2922 Window xwindow_last = 0;
2924 int rootx = -1, rooty = -1;
2928 screen = gdk_display_get_default_screen (display);
2930 xwindow = GDK_SCREEN_XROOTWIN (screen);
2931 xdisplay = GDK_SCREEN_XDISPLAY (screen);
2933 /* This function really only works if the mouse pointer is held still
2934 * during its operation. If it moves from one leaf window to another
2935 * than we'll end up with inaccurate values for win_x, win_y
2938 gdk_x11_display_grab (display);
2939 XQueryPointer (xdisplay, xwindow,
2940 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
2942 if (root == xwindow)
2949 xwindow_last = xwindow;
2950 XQueryPointer (xdisplay, xwindow,
2951 &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
2953 gdk_x11_display_ungrab (display);
2955 window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen),
2957 *win_x = window ? winx : -1;
2958 *win_y = window ? winy : -1;
2964 * gdk_window_get_events:
2965 * @window: a #GdkWindow
2967 * Gets the event mask for @window. See gdk_window_set_events().
2969 * Return value: event mask for @window
2972 gdk_window_get_events (GdkWindow *window)
2974 XWindowAttributes attrs;
2975 GdkEventMask event_mask;
2977 g_return_val_if_fail (window != NULL, 0);
2978 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2980 if (GDK_WINDOW_DESTROYED (window))
2984 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2985 GDK_WINDOW_XID (window),
2988 event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
2989 GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
2996 * gdk_window_set_events:
2997 * @window: a #GdkWindow
2998 * @event_mask: event mask for @window
3000 * The event mask for a window determines which events will be reported
3001 * for that window. For example, an event mask including #GDK_BUTTON_PRESS_MASK
3002 * means the window should report button press events. The event mask
3003 * is the bitwise OR of values from the #GdkEventMask enumeration.
3007 gdk_window_set_events (GdkWindow *window,
3008 GdkEventMask event_mask)
3013 g_return_if_fail (window != NULL);
3014 g_return_if_fail (GDK_IS_WINDOW (window));
3016 if (!GDK_WINDOW_DESTROYED (window))
3018 GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
3019 xevent_mask = StructureNotifyMask | PropertyChangeMask;
3020 for (i = 0; i < _gdk_nenvent_masks; i++)
3022 if (event_mask & (1 << (i + 1)))
3023 xevent_mask |= _gdk_event_mask_table[i];
3026 XSelectInput (GDK_WINDOW_XDISPLAY (window),
3027 GDK_WINDOW_XID (window),
3033 gdk_window_add_colormap_windows (GdkWindow *window)
3035 GdkWindow *toplevel;
3036 Window *old_windows;
3037 Window *new_windows;
3040 g_return_if_fail (window != NULL);
3041 g_return_if_fail (GDK_IS_WINDOW (window));
3043 if (GDK_WINDOW_DESTROYED (window))
3045 toplevel = gdk_window_get_toplevel (window);
3048 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3049 GDK_WINDOW_XID (toplevel),
3050 &old_windows, &count))
3055 for (i = 0; i < count; i++)
3056 if (old_windows[i] == GDK_WINDOW_XID (window))
3058 XFree (old_windows);
3062 new_windows = g_new (Window, count + 1);
3064 for (i = 0; i < count; i++)
3065 new_windows[i] = old_windows[i];
3066 new_windows[count] = GDK_WINDOW_XID (window);
3068 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3069 GDK_WINDOW_XID (toplevel),
3070 new_windows, count + 1);
3072 g_free (new_windows);
3074 XFree (old_windows);
3078 gdk_window_have_shape_ext (GdkDisplay *display)
3080 #ifdef HAVE_SHAPE_EXT
3083 return XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display),
3090 #define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
3093 * This needs the X11 shape extension.
3094 * If not available, shaped windows will look
3095 * ugly, but programs still work. Stefan Wille
3098 * gdk_window_shape_combine_mask:
3099 * @window: a #GdkWindow
3101 * @x: X position of shape mask with respect to @window
3102 * @y: Y position of shape mask with respect to @window
3104 * Applies a shape mask to @window. Pixels in @window corresponding to
3105 * set bits in the @mask will be visible; pixels in @window
3106 * corresponding to unset bits in the @mask will be transparent. This
3107 * gives a non-rectangular window.
3109 * If @mask is %NULL, the shape mask will be unset, and the @x/@y
3110 * parameters are not used.
3112 * On the X11 platform, this uses an X server extension which is
3113 * widely available on most common platforms, but not available on
3114 * very old X servers, and occasionally the implementation will be
3115 * buggy. On servers without the shape extension, this function
3118 * This function works on both toplevel and child windows.
3122 gdk_window_shape_combine_mask (GdkWindow *window,
3127 gint xoffset, yoffset;
3129 g_return_if_fail (window != NULL);
3130 g_return_if_fail (GDK_IS_WINDOW (window));
3132 #ifdef HAVE_SHAPE_EXT
3133 if (GDK_WINDOW_DESTROYED (window))
3136 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3138 if (xoffset != 0 || yoffset != 0)
3140 WARN_SHAPE_TOO_BIG ();
3144 if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
3148 pixmap = GDK_PIXMAP_XID (mask);
3157 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
3158 GDK_WINDOW_XID (window),
3164 #endif /* HAVE_SHAPE_EXT */
3168 * gdk_window_shape_combine_region:
3169 * @window: a #GdkWindow
3170 * @shape_region: region of window to be non-transparent
3171 * @offset_x: X position of @shape_region in @window coordinates
3172 * @offset_y: Y position of @shape_region in @window coordinates
3174 * Makes pixels in @window outside @shape_region be transparent,
3175 * so that the window may be nonrectangular. See also
3176 * gdk_window_shape_combine_mask() to use a bitmap as the mask.
3178 * If @shape_region is %NULL, the shape will be unset, so the whole
3179 * window will be opaque again. @offset_x and @offset_y are ignored
3180 * if @shape_region is %NULL.
3182 * On the X11 platform, this uses an X server extension which is
3183 * widely available on most common platforms, but not available on
3184 * very old X servers, and occasionally the implementation will be
3185 * buggy. On servers without the shape extension, this function
3188 * This function works on both toplevel and child windows.
3192 gdk_window_shape_combine_region (GdkWindow *window,
3193 GdkRegion *shape_region,
3197 gint xoffset, yoffset;
3199 g_return_if_fail (GDK_IS_WINDOW (window));
3201 #ifdef HAVE_SHAPE_EXT
3202 if (GDK_WINDOW_DESTROYED (window))
3205 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3207 if (xoffset != 0 || yoffset != 0)
3209 WARN_SHAPE_TOO_BIG ();
3213 if (shape_region == NULL)
3215 /* Use NULL mask to unset the shape */
3216 gdk_window_shape_combine_mask (window, NULL, 0, 0);
3220 if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
3223 XRectangle *xrects = NULL;
3225 _gdk_region_get_xrectangles (shape_region,
3229 XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
3230 GDK_WINDOW_XID (window),
3239 #endif /* HAVE_SHAPE_EXT */
3244 * gdk_window_set_override_redirect:
3245 * @window: a toplevel #GdkWindow
3246 * @override_redirect: %TRUE if window should be override redirect
3248 * An override redirect window is not under the control of the window manager.
3249 * This means it won't have a titlebar, won't be minimizable, etc. - it will
3250 * be entirely under the control of the application. The window manager
3251 * can't see the override redirect window at all.
3253 * Override redirect should only be used for short-lived temporary
3254 * windows, such as popup menus. #GtkMenu uses an override redirect
3255 * window in its implementation, for example.
3259 gdk_window_set_override_redirect (GdkWindow *window,
3260 gboolean override_redirect)
3262 XSetWindowAttributes attr;
3264 g_return_if_fail (window != NULL);
3265 g_return_if_fail (GDK_IS_WINDOW (window));
3267 if (!GDK_WINDOW_DESTROYED (window))
3269 attr.override_redirect = (override_redirect == FALSE)?False:True;
3270 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3271 GDK_WINDOW_XID (window),
3278 * gdk_window_set_accept_focus:
3279 * @window: a toplevel #GdkWindow
3280 * @accept_focus: %TRUE if the window should receive input focus
3282 * Setting @accept_focus to %FALSE hints the desktop environment that the
3283 * window doesn't want to receive input focus.
3285 * On X, it is the responsibility of the window manager to interpret this
3286 * hint. ICCCM-compliant window manager usually respect it.
3291 gdk_window_set_accept_focus (GdkWindow *window,
3292 gboolean accept_focus)
3294 GdkWindowObject *private;
3295 g_return_if_fail (window != NULL);
3296 g_return_if_fail (GDK_IS_WINDOW (window));
3298 private = (GdkWindowObject *)window;
3300 accept_focus = accept_focus != FALSE;
3302 if (private->accept_focus != accept_focus)
3304 private->accept_focus = accept_focus;
3306 if (!GDK_WINDOW_DESTROYED (window))
3307 update_wm_hints (window, FALSE);
3313 * gdk_window_set_icon_list:
3314 * @window: The #GdkWindow toplevel window to set the icon of.
3315 * @pixbufs: A list of pixbufs, of different sizes.
3317 * Sets a list of icons for the window. One of these will be used
3318 * to represent the window when it has been iconified. The icon is
3319 * usually shown in an icon box or some sort of task bar. Which icon
3320 * size is shown depends on the window manager. The window manager
3321 * can scale the icon but setting several size icons can give better
3322 * image quality since the window manager may only need to scale the
3323 * icon by a small amount or not at all.
3327 gdk_window_set_icon_list (GdkWindow *window,
3336 gint width, height, stride;
3339 GdkDisplay *display;
3341 g_return_if_fail (GDK_IS_WINDOW (window));
3343 if (GDK_WINDOW_DESTROYED (window))
3346 display = gdk_drawable_get_display (window);
3354 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
3356 width = gdk_pixbuf_get_width (pixbuf);
3357 height = gdk_pixbuf_get_height (pixbuf);
3359 size += 2 + width * height;
3361 l = g_list_next (l);
3364 data = g_malloc (size * sizeof (gulong));
3372 width = gdk_pixbuf_get_width (pixbuf);
3373 height = gdk_pixbuf_get_height (pixbuf);
3374 stride = gdk_pixbuf_get_rowstride (pixbuf);
3375 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
3380 pixels = gdk_pixbuf_get_pixels (pixbuf);
3382 for (y = 0; y < height; y++)
3384 for (x = 0; x < width; x++)
3388 r = pixels[y*stride + x*n_channels + 0];
3389 g = pixels[y*stride + x*n_channels + 1];
3390 b = pixels[y*stride + x*n_channels + 2];
3391 if (n_channels >= 4)
3392 a = pixels[y*stride + x*n_channels + 3];
3396 *p++ = a << 24 | r << 16 | g << 8 | b ;
3400 l = g_list_next (l);
3405 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3406 GDK_WINDOW_XID (window),
3407 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"),
3410 (guchar*) data, size);
3414 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3415 GDK_WINDOW_XID (window),
3416 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"));
3423 * gdk_window_set_icon:
3424 * @window: a toplevel #GdkWindow
3425 * @icon_window: a #GdkWindow to use for the icon, or %NULL to unset
3426 * @pixmap: a #GdkPixmap to use as the icon, or %NULL to unset
3427 * @mask: a 1-bit pixmap (#GdkBitmap) to use as mask for @pixmap, or %NULL to have none
3429 * Sets the icon of @window as a pixmap or window. If using GTK+, investigate
3430 * gtk_window_set_default_icon_list() first, and then gtk_window_set_icon_list()
3431 * and gtk_window_set_icon(). If those don't meet your needs, look at
3432 * gdk_window_set_icon_list(). Only if all those are too high-level do you
3433 * want to fall back to gdk_window_set_icon().
3437 gdk_window_set_icon (GdkWindow *window,
3438 GdkWindow *icon_window,
3442 GdkToplevelX11 *toplevel;
3444 g_return_if_fail (window != NULL);
3445 g_return_if_fail (GDK_IS_WINDOW (window));
3446 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
3448 if (GDK_WINDOW_DESTROYED (window))
3451 toplevel = _gdk_x11_window_get_toplevel (window);
3453 if (toplevel->icon_window != icon_window)
3455 if (toplevel->icon_window)
3456 g_object_unref (toplevel->icon_window);
3457 toplevel->icon_window = g_object_ref (icon_window);
3460 if (toplevel->icon_pixmap != pixmap)
3463 g_object_ref (pixmap);
3464 if (toplevel->icon_pixmap)
3465 g_object_unref (toplevel->icon_pixmap);
3466 toplevel->icon_pixmap = pixmap;
3469 if (toplevel->icon_mask != mask)
3472 g_object_ref (mask);
3473 if (toplevel->icon_mask)
3474 g_object_unref (toplevel->icon_mask);
3475 toplevel->icon_mask = mask;
3478 update_wm_hints (window, FALSE);
3482 gdk_window_icon_name_set (GdkWindow *window)
3484 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
3485 g_quark_from_static_string ("gdk-icon-name-set")));
3489 * gdk_window_set_icon_name:
3490 * @window: a toplevel #GdkWindow
3491 * @name: name of window while iconified (minimized)
3493 * Windows may have a name used while minimized, distinct from the
3494 * name they display in their titlebar. Most of the time this is a bad
3495 * idea from a user interface standpoint. But you can set such a name
3496 * with this function, if you like.
3500 gdk_window_set_icon_name (GdkWindow *window,
3503 GdkDisplay *display;
3505 g_return_if_fail (window != NULL);
3506 g_return_if_fail (GDK_IS_WINDOW (window));
3508 if (GDK_WINDOW_DESTROYED (window))
3511 display = gdk_drawable_get_display (window);
3513 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
3514 GUINT_TO_POINTER (TRUE));
3516 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3517 GDK_WINDOW_XID (window),
3518 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
3519 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
3520 PropModeReplace, name, strlen (name));
3522 set_text_property (display, GDK_WINDOW_XID (window),
3523 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
3528 * gdk_window_iconify:
3529 * @window: a toplevel #GdkWindow
3531 * Asks to iconify (minimize) @window. The window manager may choose
3532 * to ignore the request, but normally will honor it. Using
3533 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
3535 * This function only makes sense when @window is a toplevel window.
3539 gdk_window_iconify (GdkWindow *window)
3541 GdkWindowObject *private;
3543 g_return_if_fail (window != NULL);
3544 g_return_if_fail (GDK_IS_WINDOW (window));
3546 if (GDK_WINDOW_DESTROYED (window))
3549 private = (GdkWindowObject*) window;
3551 if (GDK_WINDOW_IS_MAPPED (window))
3553 XIconifyWindow (GDK_WINDOW_XDISPLAY (window),
3554 GDK_WINDOW_XWINDOW (window),
3555 gdk_screen_get_number (GDK_WINDOW_SCREEN (window)));
3559 /* Flip our client side flag, the real work happens on map. */
3560 gdk_synthesize_window_state (window,
3562 GDK_WINDOW_STATE_ICONIFIED);
3567 * gdk_window_deiconify:
3568 * @window: a toplevel #GdkWindow
3570 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
3571 * choose to ignore the request to deiconify. When using GTK+,
3572 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
3573 * you probably want to use gtk_window_present(), which raises the window, focuses it,
3574 * unminimizes it, and puts it on the current desktop.
3578 gdk_window_deiconify (GdkWindow *window)
3580 GdkWindowObject *private;
3582 g_return_if_fail (window != NULL);
3583 g_return_if_fail (GDK_IS_WINDOW (window));
3585 if (GDK_WINDOW_DESTROYED (window))
3588 private = (GdkWindowObject*) window;
3590 if (GDK_WINDOW_IS_MAPPED (window))
3592 gdk_window_show (window);
3596 /* Flip our client side flag, the real work happens on map. */
3597 gdk_synthesize_window_state (window,
3598 GDK_WINDOW_STATE_ICONIFIED,
3605 * @window: a toplevel #GdkWindow
3607 * "Pins" a window such that it's on all workspaces and does not scroll
3608 * with viewports, for window managers that have scrollable viewports.
3609 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
3611 * On the X11 platform, this function depends on window manager
3612 * support, so may have no effect with many window managers. However,
3613 * GDK will do the best it can to convince the window manager to stick
3614 * the window. For window managers that don't support this operation,
3615 * there's nothing you can do to force it to happen.
3619 gdk_window_stick (GdkWindow *window)
3621 g_return_if_fail (GDK_IS_WINDOW (window));
3623 if (GDK_WINDOW_DESTROYED (window))
3626 if (GDK_WINDOW_IS_MAPPED (window))
3628 /* "stick" means stick to all desktops _and_ do not scroll with the
3629 * viewport. i.e. glue to the monitor glass in all cases.
3634 /* Request stick during viewport scroll */
3635 gdk_wmspec_change_state (TRUE, window,
3636 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
3639 /* Request desktop 0xFFFFFFFF */
3640 xev.xclient.type = ClientMessage;
3641 xev.xclient.serial = 0;
3642 xev.xclient.send_event = True;
3643 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
3644 xev.xclient.display = GDK_WINDOW_XDISPLAY (window);
3645 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
3647 xev.xclient.format = 32;
3649 xev.xclient.data.l[0] = 0xFFFFFFFF;
3650 xev.xclient.data.l[1] = 0;
3651 xev.xclient.data.l[2] = 0;
3652 xev.xclient.data.l[3] = 0;
3653 xev.xclient.data.l[4] = 0;
3655 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
3656 SubstructureRedirectMask | SubstructureNotifyMask,
3661 /* Flip our client side flag, the real work happens on map. */
3662 gdk_synthesize_window_state (window,
3664 GDK_WINDOW_STATE_STICKY);
3669 * gdk_window_unstick:
3670 * @window: a toplevel #GdkWindow
3672 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
3673 * and gtk_window_unstick().
3677 gdk_window_unstick (GdkWindow *window)
3679 g_return_if_fail (GDK_IS_WINDOW (window));
3681 if (GDK_WINDOW_DESTROYED (window))
3684 if (GDK_WINDOW_IS_MAPPED (window))
3691 gulong *current_desktop;
3692 GdkDisplay *display = gdk_drawable_get_display (window);
3694 /* Request unstick from viewport */
3695 gdk_wmspec_change_state (FALSE, window,
3696 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
3699 /* Get current desktop, then set it; this is a race, but not
3700 * one that matters much in practice.
3702 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window),
3703 gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
3705 False, XA_CARDINAL, &type, &format, &nitems,
3706 &bytes_after, (guchar **)¤t_desktop);
3708 if (type == XA_CARDINAL)
3710 xev.xclient.type = ClientMessage;
3711 xev.xclient.serial = 0;
3712 xev.xclient.send_event = True;
3713 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
3714 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
3715 xev.xclient.format = 32;
3717 xev.xclient.data.l[0] = *current_desktop;
3718 xev.xclient.data.l[1] = 0;
3719 xev.xclient.data.l[2] = 0;
3720 xev.xclient.data.l[3] = 0;
3721 xev.xclient.data.l[4] = 0;
3723 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
3724 SubstructureRedirectMask | SubstructureNotifyMask,
3727 XFree (current_desktop);
3732 /* Flip our client side flag, the real work happens on map. */
3733 gdk_synthesize_window_state (window,
3734 GDK_WINDOW_STATE_STICKY,
3741 * gdk_window_maximize:
3742 * @window: a toplevel #GdkWindow
3744 * Maximizes the window. If the window was already maximized, then
3745 * this function does nothing.
3747 * On X11, asks the window manager to maximize @window, if the window
3748 * manager supports this operation. Not all window managers support
3749 * this, and some deliberately ignore it or don't have a concept of
3750 * "maximized"; so you can't rely on the maximization actually
3751 * happening. But it will happen with most standard window managers,
3752 * and GDK makes a best effort to get it to happen.
3754 * On Windows, reliably maximizes the window.
3758 gdk_window_maximize (GdkWindow *window)
3760 g_return_if_fail (GDK_IS_WINDOW (window));
3762 if (GDK_WINDOW_DESTROYED (window))
3765 if (GDK_WINDOW_IS_MAPPED (window))
3766 gdk_wmspec_change_state (TRUE, window,
3767 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
3768 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
3770 gdk_synthesize_window_state (window,
3772 GDK_WINDOW_STATE_MAXIMIZED);
3776 * gdk_window_unmaximize:
3777 * @window: a toplevel #GdkWindow
3779 * Unmaximizes the window. If the window wasn't maximized, then this
3780 * function does nothing.
3782 * On X11, asks the window manager to unmaximize @window, if the
3783 * window manager supports this operation. Not all window managers
3784 * support this, and some deliberately ignore it or don't have a
3785 * concept of "maximized"; so you can't rely on the unmaximization
3786 * actually happening. But it will happen with most standard window
3787 * managers, and GDK makes a best effort to get it to happen.
3789 * On Windows, reliably unmaximizes the window.
3793 gdk_window_unmaximize (GdkWindow *window)
3795 g_return_if_fail (GDK_IS_WINDOW (window));
3797 if (GDK_WINDOW_DESTROYED (window))
3800 if (GDK_WINDOW_IS_MAPPED (window))
3801 gdk_wmspec_change_state (FALSE, window,
3802 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
3803 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
3805 gdk_synthesize_window_state (window,
3806 GDK_WINDOW_STATE_MAXIMIZED,
3811 * gdk_window_fullscreen:
3812 * @window: a toplevel #GdkWindow
3814 * Moves the window into fullscreen mode. This means the
3815 * window covers the entire screen and is above any panels
3818 * If the window was already fullscreen, then this function does nothing.
3820 * On X11, asks the window manager to put @window in a fullscreen
3821 * state, if the window manager supports this operation. Not all
3822 * window managers support this, and some deliberately ignore it or
3823 * don't have a concept of "fullscreen"; so you can't rely on the
3824 * fullscreenification actually happening. But it will happen with
3825 * most standard window managers, and GDK makes a best effort to get
3831 gdk_window_fullscreen (GdkWindow *window)
3833 g_return_if_fail (GDK_IS_WINDOW (window));
3835 if (GDK_WINDOW_DESTROYED (window))
3838 if (GDK_WINDOW_IS_MAPPED (window))
3839 gdk_wmspec_change_state (TRUE, window,
3840 gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
3844 gdk_synthesize_window_state (window,
3846 GDK_WINDOW_STATE_FULLSCREEN);
3850 * gdk_window_unfullscreen:
3851 * @window: a toplevel #GdkWindow
3853 * Moves the window out of fullscreen mode. If the window was not
3854 * fullscreen, does nothing.
3856 * On X11, asks the window manager to move @window out of the fullscreen
3857 * state, if the window manager supports this operation. Not all
3858 * window managers support this, and some deliberately ignore it or
3859 * don't have a concept of "fullscreen"; so you can't rely on the
3860 * unfullscreenification actually happening. But it will happen with
3861 * most standard window managers, and GDK makes a best effort to get
3867 gdk_window_unfullscreen (GdkWindow *window)
3869 g_return_if_fail (GDK_IS_WINDOW (window));
3871 if (GDK_WINDOW_DESTROYED (window))
3874 if (GDK_WINDOW_IS_MAPPED (window))
3875 gdk_wmspec_change_state (FALSE, window,
3876 gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
3880 gdk_synthesize_window_state (window,
3881 GDK_WINDOW_STATE_FULLSCREEN,
3886 * gdk_window_set_keep_above:
3887 * @window: a toplevel #GdkWindow
3888 * @setting: whether to keep @window above other windows
3890 * Set if @window must be kept above other windows. If the
3891 * window was already above, then this function does nothing.
3893 * On X11, asks the window manager to keep @window above, if the window
3894 * manager supports this operation. Not all window managers support
3895 * this, and some deliberately ignore it or don't have a concept of
3896 * "keep above"; so you can't rely on the window being kept above.
3897 * But it will happen with most standard window managers,
3898 * and GDK makes a best effort to get it to happen.
3903 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
3905 g_return_if_fail (GDK_IS_WINDOW (window));
3907 if (GDK_WINDOW_DESTROYED (window))
3910 if (GDK_WINDOW_IS_MAPPED (window))
3911 gdk_wmspec_change_state (setting, window,
3912 gdk_atom_intern ("_NET_WM_STATE_ABOVE", setting),
3913 setting ? gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE)
3916 gdk_synthesize_window_state (window,
3917 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
3918 setting ? GDK_WINDOW_STATE_ABOVE : 0);
3922 * gdk_window_set_keep_below:
3923 * @window: a toplevel #GdkWindow
3924 * @setting: whether to keep @window below other windows
3926 * Set if @window must be kept below other windows. If the
3927 * window was already below, then this function does nothing.
3929 * On X11, asks the window manager to keep @window below, if the window
3930 * manager supports this operation. Not all window managers support
3931 * this, and some deliberately ignore it or don't have a concept of
3932 * "keep below"; so you can't rely on the window being kept below.
3933 * But it will happen with most standard window managers,
3934 * and GDK makes a best effort to get it to happen.
3939 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
3941 g_return_if_fail (GDK_IS_WINDOW (window));
3943 if (GDK_WINDOW_DESTROYED (window))
3946 if (GDK_WINDOW_IS_MAPPED (window))
3947 gdk_wmspec_change_state (setting, window,
3948 gdk_atom_intern ("_NET_WM_STATE_BELOW", setting),
3949 setting ? gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE)
3952 gdk_synthesize_window_state (window,
3953 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
3954 setting ? GDK_WINDOW_STATE_BELOW : 0);
3958 * gdk_window_get_group:
3959 * @window: a toplevel #GdkWindow
3961 * Returns the group leader window for @window. See gdk_window_set_group().
3963 * Return value: the group leader window for @window
3968 gdk_window_get_group (GdkWindow *window)
3970 GdkToplevelX11 *toplevel;
3972 g_return_val_if_fail (window != NULL, NULL);
3973 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3974 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
3976 if (GDK_WINDOW_DESTROYED (window))
3979 toplevel = _gdk_x11_window_get_toplevel (window);
3981 return toplevel->group_leader;
3985 * gdk_window_set_group:
3986 * @window: a toplevel #GdkWindow
3987 * @leader: group leader window, or %NULL to restore the default group leader window
3989 * Sets the group leader window for @window. By default,
3990 * GDK sets the group leader for all toplevel windows
3991 * to a global window implicitly created by GDK. With this function
3992 * you can override this default.
3994 * The group leader window allows the window manager to distinguish
3995 * all windows that belong to a single application. It may for example
3996 * allow users to minimize/unminimize all windows belonging to an
3997 * application at once. You should only set a non-default group window
3998 * if your application pretends to be multiple applications.
4001 gdk_window_set_group (GdkWindow *window,
4004 GdkToplevelX11 *toplevel;
4006 g_return_if_fail (window != NULL);
4007 g_return_if_fail (GDK_IS_WINDOW (window));
4008 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
4009 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
4011 if (GDK_WINDOW_DESTROYED (window) || (leader != NULL && GDK_WINDOW_DESTROYED (leader)))
4014 toplevel = _gdk_x11_window_get_toplevel (window);
4017 leader = gdk_display_get_default_group (gdk_drawable_get_display (window));
4019 if (toplevel->group_leader != leader)
4021 if (toplevel->group_leader)
4022 g_object_unref (toplevel->group_leader);
4023 toplevel->group_leader = g_object_ref (leader);
4026 update_wm_hints (window, FALSE);
4029 static MotifWmHints *
4030 gdk_window_get_mwm_hints (GdkWindow *window)
4032 GdkDisplay *display;
4033 Atom hints_atom = None;
4034 MotifWmHints *hints;
4040 if (GDK_WINDOW_DESTROYED (window))
4043 display = gdk_drawable_get_display (window);
4045 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4047 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
4048 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4049 False, AnyPropertyType, &type, &format, &nitems,
4050 &bytes_after, (guchar **)&hints);
4059 gdk_window_set_mwm_hints (GdkWindow *window,
4060 MotifWmHints *new_hints)
4062 GdkDisplay *display;
4063 Atom hints_atom = None;
4064 MotifWmHints *hints;
4070 if (GDK_WINDOW_DESTROYED (window))
4073 display = gdk_drawable_get_display (window);
4075 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4077 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
4078 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4079 False, AnyPropertyType, &type, &format, &nitems,
4080 &bytes_after, (guchar **)&hints);
4086 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
4088 hints->flags |= MWM_HINTS_FUNCTIONS;
4089 hints->functions = new_hints->functions;
4091 if (new_hints->flags & MWM_HINTS_DECORATIONS)
4093 hints->flags |= MWM_HINTS_DECORATIONS;
4094 hints->decorations = new_hints->decorations;
4098 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
4099 hints_atom, hints_atom, 32, PropModeReplace,
4100 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
4102 if (hints != new_hints)
4107 * gdk_window_set_decorations:
4108 * @window: a toplevel #GdkWindow
4109 * @decorations: decoration hint mask
4111 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
4112 * This function sets the traditional Motif window manager hints that tell the
4113 * window manager which decorations you would like your window to have.
4114 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
4115 * using the GDK function directly.
4117 * The @decorations argument is the logical OR of the fields in
4118 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
4119 * mask, the other bits indicate which decorations should be turned off.
4120 * If #GDK_DECOR_ALL is not included, then the other bits indicate
4121 * which decorations should be turned on.
4123 * Most window managers honor a decorations hint of 0 to disable all decorations,
4124 * but very few honor all possible combinations of bits.
4128 gdk_window_set_decorations (GdkWindow *window,
4129 GdkWMDecoration decorations)
4133 g_return_if_fail (window != NULL);
4134 g_return_if_fail (GDK_IS_WINDOW (window));
4136 hints.flags = MWM_HINTS_DECORATIONS;
4137 hints.decorations = decorations;
4139 gdk_window_set_mwm_hints (window, &hints);
4143 * gdk_window_get_decorations:
4144 * @window: The toplevel #GdkWindow to get the decorations from
4145 * @decorations: The window decorations will be written here
4147 * Returns the decorations set on the GdkWindow with #gdk_window_set_decorations
4148 * Returns: TRUE if the window has decorations set, FALSE otherwise.
4151 gdk_window_get_decorations(GdkWindow *window,
4152 GdkWMDecoration *decorations)
4154 MotifWmHints *hints;
4155 gboolean result = FALSE;
4157 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
4159 hints = gdk_window_get_mwm_hints (window);
4163 if (hints->flags & MWM_HINTS_DECORATIONS)
4166 *decorations = hints->decorations;
4177 * gdk_window_set_functions:
4178 * @window: a toplevel #GdkWindow
4179 * @functions: bitmask of operations to allow on @window
4181 * This function isn't really good for much. It sets the traditional
4182 * Motif window manager hint for which operations the window manager
4183 * should allow on a toplevel window. However, few window managers do
4184 * anything reliable or interesting with this hint. Many ignore it
4187 * The @functions argument is the logical OR of values from the
4188 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
4189 * then the other bits indicate which functions to disable; if
4190 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
4195 gdk_window_set_functions (GdkWindow *window,
4196 GdkWMFunction functions)
4200 g_return_if_fail (window != NULL);
4201 g_return_if_fail (GDK_IS_WINDOW (window));
4203 hints.flags = MWM_HINTS_FUNCTIONS;
4204 hints.functions = functions;
4206 gdk_window_set_mwm_hints (window, &hints);
4209 #ifdef HAVE_SHAPE_EXT
4212 * propagate the shapes from all child windows of a GDK window to the parent
4213 * window. Shamelessly ripped from Enlightenment's code
4221 struct _gdk_span *next;
4225 gdk_add_to_span (struct _gdk_span **s,
4229 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
4236 /* scan the spans for this line */
4239 /* -- -> new span */
4240 /* == -> existing span */
4241 /* ## -> spans intersect */
4242 /* if we are in the middle of spanning the span into the line */
4245 /* case: ---- ==== */
4246 if (xx < ptr1->start - 1)
4248 /* ends before next span - extend to here */
4252 /* case: ----##=== */
4253 else if (xx <= ptr1->end)
4255 /* crosses into next span - delete next span and append */
4256 ss->end = ptr1->end;
4257 ss->next = ptr1->next;
4261 /* case: ---###--- */
4264 /* overlaps next span - delete and keep checking */
4265 ss->next = ptr1->next;
4270 /* otherwise havent started spanning it in yet */
4273 /* case: ---- ==== */
4274 if (xx < ptr1->start - 1)
4276 /* insert span here in list */
4277 noo = g_malloc (sizeof (struct _gdk_span));
4291 /* case: ----##=== */
4292 else if ((x < ptr1->start) && (xx <= ptr1->end))
4294 /* expand this span to the left point of the new one */
4298 /* case: ===###=== */
4299 else if ((x >= ptr1->start) && (xx <= ptr1->end))
4301 /* throw the span away */
4304 /* case: ---###--- */
4305 else if ((x < ptr1->start) && (xx > ptr1->end))
4312 /* case: ===##---- */
4313 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
4319 /* case: ==== ---- */
4320 /* case handled by next loop iteration - first case */
4325 /* it started in the middle but spans beyond your current list */
4331 /* it does not start inside a span or in the middle, so add it to the end */
4332 noo = g_malloc (sizeof (struct _gdk_span));
4340 noo->next = ptr2->next;
4353 gdk_add_rectangles (Display *disp,
4355 struct _gdk_span **spans,
4362 gint x1, y1, x2, y2;
4366 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
4369 /* go through all clip rects in this window's shape */
4370 for (k = 0; k < rn; k++)
4372 /* for each clip rect, add it to each line's spans */
4374 x2 = x + rl[k].x + (rl[k].width - 1);
4376 y2 = y + rl[k].y + (rl[k].height - 1);
4385 for (a = y1; a <= y2; a++)
4388 gdk_add_to_span (&spans[a], x1, x2);
4396 gdk_propagate_shapes (Display *disp,
4400 Window rt, par, *list = NULL;
4401 gint i, j, num = 0, num_rects = 0;
4405 XRectangle *rects = NULL;
4406 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
4407 XWindowAttributes xatt;
4409 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
4414 spans = g_malloc (sizeof (struct _gdk_span *) * h);
4416 for (i = 0; i < h; i++)
4418 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
4421 /* go through all child windows and create/insert spans */
4422 for (i = 0; i < num; i++)
4424 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
4425 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
4426 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
4429 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
4431 /* go through the spans list and build a list of rects */
4432 rects = g_malloc (sizeof (XRectangle) * 256);
4434 for (i = 0; i < baseh; i++)
4437 /* go through the line for all spans */
4440 rects[num_rects].x = ptr1->start;
4441 rects[num_rects].y = i;
4442 rects[num_rects].width = ptr1->end - ptr1->start + 1;
4443 rects[num_rects].height = 1;
4445 /* if there are more lines */
4447 /* while contigous rects (same start/end coords) exist */
4448 while ((contig) && (j < baseh))
4450 /* search next line for spans matching this one */
4456 /* if we have an exact span match set contig */
4457 if ((ptr2->start == ptr1->start) &&
4458 (ptr2->end == ptr1->end))
4461 /* remove the span - not needed */
4464 ptr3->next = ptr2->next;
4470 spans[j] = ptr2->next;
4476 /* gone past the span point no point looking */
4477 else if (ptr2->start < ptr1->start)
4485 /* if a contiguous span was found increase the rect h */
4488 rects[num_rects].height++;
4492 /* up the rect count */
4494 /* every 256 new rects increase the rect array */
4495 if ((num_rects % 256) == 0)
4496 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
4500 /* set the rects as the shape mask */
4503 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
4504 ShapeSet, YXSorted);
4509 /* free up all the spans we made */
4510 for (i = 0; i < baseh; i++)
4523 #endif /* HAVE_SHAPE_EXT */
4526 * gdk_window_set_child_shapes:
4527 * @window: a #GdkWindow
4529 * Sets the shape mask of @window to the union of shape masks
4530 * for all children of @window, ignoring the shape mask of @window
4531 * itself. Contrast with gdk_window_merge_child_shapes() which includes
4532 * the shape mask of @window in the masks to be merged.
4535 gdk_window_set_child_shapes (GdkWindow *window)
4537 g_return_if_fail (window != NULL);
4538 g_return_if_fail (GDK_IS_WINDOW (window));
4540 #ifdef HAVE_SHAPE_EXT
4541 if (!GDK_WINDOW_DESTROYED (window) &&
4542 gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
4543 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
4544 GDK_WINDOW_XID (window), FALSE);
4549 * gdk_window_merge_child_shapes:
4550 * @window: a #GdkWindow
4552 * Merges the shape masks for any child windows into the
4553 * shape mask for @window. i.e. the union of all masks
4554 * for @window and its children will become the new mask
4555 * for @window. See gdk_window_shape_combine_mask().
4557 * This function is distinct from gdk_window_set_child_shapes()
4558 * because it includes @window's shape mask in the set of shapes to
4563 gdk_window_merge_child_shapes (GdkWindow *window)
4565 g_return_if_fail (window != NULL);
4566 g_return_if_fail (GDK_IS_WINDOW (window));
4568 #ifdef HAVE_SHAPE_EXT
4569 if (!GDK_WINDOW_DESTROYED (window) &&
4570 gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
4571 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
4572 GDK_WINDOW_XID (window), TRUE);
4577 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
4579 XSetWindowAttributes xattributes;
4580 GdkWindowObject *private;
4581 guint xattributes_mask = 0;
4583 g_return_if_fail (window != NULL);
4585 private = GDK_WINDOW_OBJECT (window);
4586 if (private->input_only)
4589 xattributes.bit_gravity = StaticGravity;
4590 xattributes_mask |= CWBitGravity;
4591 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
4592 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
4593 GDK_WINDOW_XID (window),
4594 CWBitGravity, &xattributes);
4598 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
4600 XSetWindowAttributes xattributes;
4602 g_return_if_fail (window != NULL);
4604 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
4606 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
4607 GDK_WINDOW_XID (window),
4608 CWWinGravity, &xattributes);
4612 * gdk_window_set_static_gravities:
4613 * @window: a #GdkWindow
4614 * @use_static: %TRUE to turn on static gravity
4616 * Set the bit gravity of the given window to static, and flag it so
4617 * all children get static subwindow gravity. This is used if you are
4618 * implementing scary features that involve deep knowledge of the
4619 * windowing system. Don't worry about it unless you have to.
4621 * Return value: %TRUE if the server supports static gravity
4624 gdk_window_set_static_gravities (GdkWindow *window,
4625 gboolean use_static)
4627 GdkWindowObject *private = (GdkWindowObject *)window;
4630 g_return_val_if_fail (window != NULL, FALSE);
4631 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
4633 if (!use_static == !private->guffaw_gravity)
4636 private->guffaw_gravity = use_static;
4638 if (!GDK_WINDOW_DESTROYED (window))
4640 gdk_window_set_static_bit_gravity (window, use_static);
4642 tmp_list = private->children;
4645 gdk_window_set_static_win_gravity (tmp_list->data, use_static);
4647 tmp_list = tmp_list->next;
4655 wmspec_moveresize (GdkWindow *window,
4661 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
4665 /* Release passive grab */
4666 gdk_display_pointer_ungrab (display, timestamp);
4668 xev.xclient.type = ClientMessage;
4669 xev.xclient.serial = 0;
4670 xev.xclient.send_event = True;
4671 xev.xclient.window = GDK_WINDOW_XID (window);
4672 xev.xclient.message_type =
4673 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
4674 xev.xclient.format = 32;
4675 xev.xclient.data.l[0] = root_x;
4676 xev.xclient.data.l[1] = root_y;
4677 xev.xclient.data.l[2] = direction;
4678 xev.xclient.data.l[3] = 0;
4679 xev.xclient.data.l[4] = 0;
4681 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
4682 SubstructureRedirectMask | SubstructureNotifyMask,
4686 typedef struct _MoveResizeData MoveResizeData;
4688 struct _MoveResizeData
4690 GdkDisplay *display;
4692 GdkWindow *moveresize_window;
4693 GdkWindow *moveresize_emulation_window;
4695 GdkWindowEdge resize_edge;
4696 gint moveresize_button;
4699 gint moveresize_orig_x;
4700 gint moveresize_orig_y;
4701 gint moveresize_orig_width;
4702 gint moveresize_orig_height;
4703 GdkWindowHints moveresize_geom_mask;
4704 GdkGeometry moveresize_geometry;
4705 Time moveresize_process_time;
4706 XEvent *moveresize_pending_event;
4709 /* From the WM spec */
4710 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
4711 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
4712 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
4713 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
4714 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
4715 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
4716 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
4717 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
4718 #define _NET_WM_MOVERESIZE_MOVE 8
4721 wmspec_resize_drag (GdkWindow *window,
4730 /* Let the compiler turn a switch into a table, instead
4731 * of doing the table manually, this way is easier to verify.
4735 case GDK_WINDOW_EDGE_NORTH_WEST:
4736 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
4739 case GDK_WINDOW_EDGE_NORTH:
4740 direction = _NET_WM_MOVERESIZE_SIZE_TOP;
4743 case GDK_WINDOW_EDGE_NORTH_EAST:
4744 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
4747 case GDK_WINDOW_EDGE_WEST:
4748 direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
4751 case GDK_WINDOW_EDGE_EAST:
4752 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
4755 case GDK_WINDOW_EDGE_SOUTH_WEST:
4756 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
4759 case GDK_WINDOW_EDGE_SOUTH:
4760 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
4763 case GDK_WINDOW_EDGE_SOUTH_EAST:
4764 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
4768 g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
4774 wmspec_moveresize (window, direction, root_x, root_y, timestamp);
4777 static MoveResizeData *
4778 get_move_resize_data (GdkDisplay *display,
4781 MoveResizeData *mv_resize;
4782 static GQuark move_resize_quark = 0;
4784 if (!move_resize_quark)
4785 move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize");
4787 mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark);
4789 if (!mv_resize && create)
4791 mv_resize = g_new0 (MoveResizeData, 1);
4792 mv_resize->display = display;
4794 g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize);
4801 update_pos (MoveResizeData *mv_resize,
4807 dx = new_root_x - mv_resize->moveresize_x;
4808 dy = new_root_y - mv_resize->moveresize_y;
4810 if (mv_resize->is_resize)
4814 x = mv_resize->moveresize_orig_x;
4815 y = mv_resize->moveresize_orig_y;
4817 w = mv_resize->moveresize_orig_width;
4818 h = mv_resize->moveresize_orig_height;
4820 switch (mv_resize->resize_edge)
4822 case GDK_WINDOW_EDGE_NORTH_WEST:
4828 case GDK_WINDOW_EDGE_NORTH:
4832 case GDK_WINDOW_EDGE_NORTH_EAST:
4837 case GDK_WINDOW_EDGE_SOUTH_WEST:
4842 case GDK_WINDOW_EDGE_SOUTH_EAST:
4846 case GDK_WINDOW_EDGE_SOUTH:
4849 case GDK_WINDOW_EDGE_EAST:
4852 case GDK_WINDOW_EDGE_WEST:
4863 if (mv_resize->moveresize_geom_mask)
4865 gdk_window_constrain_size (&mv_resize->moveresize_geometry,
4866 mv_resize->moveresize_geom_mask,
4870 gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
4876 x = mv_resize->moveresize_orig_x + dx;
4877 y = mv_resize->moveresize_orig_y + dy;
4879 gdk_window_move (mv_resize->moveresize_window, x, y);
4884 finish_drag (MoveResizeData *mv_resize)
4886 gdk_window_destroy (mv_resize->moveresize_emulation_window);
4887 mv_resize->moveresize_emulation_window = NULL;
4888 mv_resize->moveresize_window = NULL;
4890 if (mv_resize->moveresize_pending_event)
4892 g_free (mv_resize->moveresize_pending_event);
4893 mv_resize->moveresize_pending_event = NULL;
4898 lookahead_motion_predicate (Display *xdisplay,
4902 gboolean *seen_release = (gboolean *)arg;
4903 GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
4904 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
4909 switch (event->xany.type)
4912 *seen_release = TRUE;
4915 mv_resize->moveresize_process_time = event->xmotion.time;
4925 moveresize_lookahead (MoveResizeData *mv_resize,
4929 gboolean seen_release = FALSE;
4931 if (mv_resize->moveresize_process_time)
4933 if (event->xmotion.time == mv_resize->moveresize_process_time)
4935 mv_resize->moveresize_process_time = 0;
4942 XCheckIfEvent (event->xany.display, &tmp_event,
4943 lookahead_motion_predicate, (XPointer) & seen_release);
4945 return mv_resize->moveresize_process_time == 0;
4949 _gdk_moveresize_handle_event (XEvent *event)
4951 guint button_mask = 0;
4952 GdkWindowObject *window_private;
4953 GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
4954 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
4956 if (!mv_resize || !mv_resize->moveresize_window)
4959 window_private = (GdkWindowObject *) mv_resize->moveresize_window;
4961 button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
4963 switch (event->xany.type)
4966 if (window_private->resize_count > 0)
4968 if (mv_resize->moveresize_pending_event)
4969 *mv_resize->moveresize_pending_event = *event;
4971 mv_resize->moveresize_pending_event =
4972 g_memdup (event, sizeof (XEvent));
4976 if (!moveresize_lookahead (mv_resize, event))
4979 update_pos (mv_resize,
4980 event->xmotion.x_root,
4981 event->xmotion.y_root);
4983 /* This should never be triggered in normal cases, but in the
4984 * case where the drag started without an implicit grab being
4985 * in effect, we could miss the release if it occurs before
4986 * we grab the pointer; this ensures that we will never
4987 * get a permanently stuck grab.
4989 if ((event->xmotion.state & button_mask) == 0)
4990 finish_drag (mv_resize);
4994 update_pos (mv_resize,
4995 event->xbutton.x_root,
4996 event->xbutton.y_root);
4998 if (event->xbutton.button == mv_resize->moveresize_button)
4999 finish_drag (mv_resize);
5006 _gdk_moveresize_configure_done (GdkDisplay *display,
5010 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5012 if (!mv_resize || window != mv_resize->moveresize_window)
5015 if (mv_resize->moveresize_pending_event)
5017 tmp_event = mv_resize->moveresize_pending_event;
5018 mv_resize->moveresize_pending_event = NULL;
5019 _gdk_moveresize_handle_event (tmp_event);
5027 create_moveresize_window (MoveResizeData *mv_resize,
5030 GdkWindowAttr attributes;
5031 gint attributes_mask;
5032 GdkGrabStatus status;
5034 g_assert (mv_resize->moveresize_emulation_window == NULL);
5036 attributes.x = -100;
5037 attributes.y = -100;
5038 attributes.width = 10;
5039 attributes.height = 10;
5040 attributes.window_type = GDK_WINDOW_TEMP;
5041 attributes.wclass = GDK_INPUT_ONLY;
5042 attributes.override_redirect = TRUE;
5043 attributes.event_mask = 0;
5045 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
5047 mv_resize->moveresize_emulation_window =
5048 gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)),
5052 gdk_window_show (mv_resize->moveresize_emulation_window);
5054 status = gdk_pointer_grab (mv_resize->moveresize_emulation_window,
5056 GDK_BUTTON_RELEASE_MASK |
5057 GDK_POINTER_MOTION_MASK,
5062 if (status != GDK_GRAB_SUCCESS)
5064 /* If this fails, some other client has grabbed the window
5067 gdk_window_destroy (mv_resize->moveresize_emulation_window);
5068 mv_resize->moveresize_emulation_window = NULL;
5071 mv_resize->moveresize_process_time = 0;
5075 Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
5076 so that calling XMoveWindow with these coordinates will not move the
5078 Note that this depends on the WM to implement ICCCM-compliant reference
5082 calculate_unmoving_origin (MoveResizeData *mv_resize)
5087 if (mv_resize->moveresize_geom_mask & GDK_HINT_WIN_GRAVITY &&
5088 mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC)
5090 gdk_window_get_origin (mv_resize->moveresize_window,
5091 &mv_resize->moveresize_orig_x,
5092 &mv_resize->moveresize_orig_y);
5096 gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
5097 gdk_window_get_geometry (mv_resize->moveresize_window,
5098 NULL, NULL, &width, &height, NULL);
5100 switch (mv_resize->moveresize_geometry.win_gravity)
5102 case GDK_GRAVITY_NORTH_WEST:
5103 mv_resize->moveresize_orig_x = rect.x;
5104 mv_resize->moveresize_orig_y = rect.y;
5106 case GDK_GRAVITY_NORTH:
5107 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5108 mv_resize->moveresize_orig_y = rect.y;
5110 case GDK_GRAVITY_NORTH_EAST:
5111 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5112 mv_resize->moveresize_orig_y = rect.y;
5114 case GDK_GRAVITY_WEST:
5115 mv_resize->moveresize_orig_x = rect.x;
5116 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5118 case GDK_GRAVITY_CENTER:
5119 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5120 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5122 case GDK_GRAVITY_EAST:
5123 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5124 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5126 case GDK_GRAVITY_SOUTH_WEST:
5127 mv_resize->moveresize_orig_x = rect.x;
5128 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5130 case GDK_GRAVITY_SOUTH:
5131 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5132 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5134 case GDK_GRAVITY_SOUTH_EAST:
5135 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5136 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5139 mv_resize->moveresize_orig_x = rect.x;
5140 mv_resize->moveresize_orig_y = rect.y;
5147 emulate_resize_drag (GdkWindow *window,
5154 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
5156 mv_resize->is_resize = TRUE;
5157 mv_resize->moveresize_button = button;
5158 mv_resize->resize_edge = edge;
5159 mv_resize->moveresize_x = root_x;
5160 mv_resize->moveresize_y = root_y;
5161 mv_resize->moveresize_window = g_object_ref (window);
5163 gdk_drawable_get_size (window,
5164 &mv_resize->moveresize_orig_width,
5165 &mv_resize->moveresize_orig_height);
5167 mv_resize->moveresize_geom_mask = 0;
5168 gdk_window_get_geometry_hints (window,
5169 &mv_resize->moveresize_geometry,
5170 &mv_resize->moveresize_geom_mask);
5172 calculate_unmoving_origin (mv_resize);
5174 create_moveresize_window (mv_resize, timestamp);
5178 emulate_move_drag (GdkWindow *window,
5184 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
5186 mv_resize->is_resize = FALSE;
5187 mv_resize->moveresize_button = button;
5188 mv_resize->moveresize_x = root_x;
5189 mv_resize->moveresize_y = root_y;
5191 mv_resize->moveresize_window = g_object_ref (window);
5193 calculate_unmoving_origin (mv_resize);
5195 create_moveresize_window (mv_resize, timestamp);
5199 * gdk_window_begin_resize_drag:
5200 * @window: a toplevel #GdkWindow
5201 * @edge: the edge or corner from which the drag is started
5202 * @button: the button being used to drag
5203 * @root_x: root window X coordinate of mouse click that began the drag
5204 * @root_y: root window Y coordinate of mouse click that began the drag
5205 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
5207 * Begins a window resize operation (for a toplevel window).
5208 * You might use this function to implement a "window resize grip," for
5209 * example; in fact #GtkStatusbar uses it. The function works best
5210 * with window managers that support the Extended Window Manager Hints spec
5211 * (see http://www.freedesktop.org), but has a fallback implementation
5212 * for other window managers.
5216 gdk_window_begin_resize_drag (GdkWindow *window,
5223 g_return_if_fail (GDK_IS_WINDOW (window));
5225 if (GDK_WINDOW_DESTROYED (window))
5228 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
5229 gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
5230 wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
5232 emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
5236 * gdk_window_begin_move_drag:
5237 * @window: a toplevel #GdkWindow
5238 * @button: the button being used to drag
5239 * @root_x: root window X coordinate of mouse click that began the drag
5240 * @root_y: root window Y coordinate of mouse click that began the drag
5241 * @timestamp: timestamp of mouse click that began the drag
5243 * Begins a window move operation (for a toplevel window). You might
5244 * use this function to implement a "window move grip," for
5245 * example. The function works best with window managers that support
5246 * the Extended Window Manager Hints spec (see
5247 * http://www.freedesktop.org), but has a fallback implementation for
5248 * other window managers.
5252 gdk_window_begin_move_drag (GdkWindow *window,
5258 g_return_if_fail (GDK_IS_WINDOW (window));
5260 if (GDK_WINDOW_DESTROYED (window))
5263 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
5264 gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
5265 wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, root_x, root_y,
5268 emulate_move_drag (window, button, root_x, root_y, timestamp);