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/.
28 #include <X11/Xutil.h>
29 #include <X11/Xatom.h>
30 #include <netinet/in.h>
35 #include "gdkwindow.h"
36 #include "gdkinputprivate.h"
37 #include "gdkprivate-x11.h"
38 #include "gdkregion.h"
39 #include "gdkinternals.h"
41 #include "gdkwindow-x11.h"
49 #include <X11/extensions/shape.h>
52 const int _gdk_event_mask_table[21] =
56 PointerMotionHintMask,
73 SubstructureNotifyMask,
74 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
76 const int _gdk_nenvent_masks = sizeof (_gdk_event_mask_table) / sizeof (int);
78 /* Forward declarations */
79 static gboolean gdk_window_gravity_works (void);
80 static void gdk_window_set_static_win_gravity (GdkWindow *window,
82 static gboolean gdk_window_have_shape_ext (void);
83 static gboolean gdk_window_icon_name_set (GdkWindow *window);
85 static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
86 static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
88 static void gdk_window_impl_x11_get_size (GdkDrawable *drawable,
91 static GdkRegion* gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable);
92 static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
93 static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
94 static void gdk_window_impl_x11_finalize (GObject *object);
96 static gpointer parent_class = NULL;
99 gdk_window_impl_x11_get_type (void)
101 static GType object_type = 0;
105 static const GTypeInfo object_info =
107 sizeof (GdkWindowImplX11Class),
108 (GBaseInitFunc) NULL,
109 (GBaseFinalizeFunc) NULL,
110 (GClassInitFunc) gdk_window_impl_x11_class_init,
111 NULL, /* class_finalize */
112 NULL, /* class_data */
113 sizeof (GdkWindowImplX11),
115 (GInstanceInitFunc) gdk_window_impl_x11_init,
118 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
127 _gdk_window_impl_get_type (void)
129 return gdk_window_impl_x11_get_type ();
133 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
140 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
142 GObjectClass *object_class = G_OBJECT_CLASS (klass);
143 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
145 parent_class = g_type_class_peek_parent (klass);
147 object_class->finalize = gdk_window_impl_x11_finalize;
149 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
150 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
151 drawable_class->get_size = gdk_window_impl_x11_get_size;
153 /* Visible and clip regions are the same */
154 drawable_class->get_clip_region = gdk_window_impl_x11_get_visible_region;
155 drawable_class->get_visible_region = gdk_window_impl_x11_get_visible_region;
159 gdk_window_impl_x11_finalize (GObject *object)
161 GdkWindowObject *wrapper;
162 GdkDrawableImplX11 *draw_impl;
163 GdkWindowImplX11 *window_impl;
165 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
167 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
168 window_impl = GDK_WINDOW_IMPL_X11 (object);
170 wrapper = (GdkWindowObject*) draw_impl->wrapper;
172 _gdk_xgrab_check_destroy (GDK_WINDOW (wrapper));
174 if (!GDK_WINDOW_DESTROYED (wrapper))
176 gdk_xid_table_remove (draw_impl->xid);
177 if (window_impl->focus_window)
178 gdk_xid_table_remove (window_impl->focus_window);
181 G_OBJECT_CLASS (parent_class)->finalize (object);
185 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
187 GdkDrawableImplX11 *drawable_impl;
188 GdkWindowImplX11 *window_impl;
190 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
192 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
193 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
195 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
196 drawable_impl->colormap == NULL)
198 XWindowAttributes window_attributes;
200 XGetWindowAttributes (drawable_impl->xdisplay,
203 drawable_impl->colormap =
204 gdk_colormap_lookup (window_attributes.colormap);
207 return drawable_impl->colormap;
211 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
214 GdkWindowImplX11 *impl;
215 GdkDrawableImplX11 *draw_impl;
217 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
219 impl = GDK_WINDOW_IMPL_X11 (drawable);
220 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
223 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
227 XSetWindowColormap (draw_impl->xdisplay,
229 GDK_COLORMAP_XCOLORMAP (cmap));
231 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
233 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
239 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
243 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
246 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
248 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
252 gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
254 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
255 GdkRectangle result_rect;
259 result_rect.width = impl->width;
260 result_rect.height = impl->height;
262 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
264 return gdk_region_rectangle (&result_rect);
268 _gdk_windowing_window_init (void)
270 GdkWindowObject *private;
271 GdkWindowImplX11 *impl;
272 GdkDrawableImplX11 *draw_impl;
273 XWindowAttributes xattributes;
276 unsigned int border_width;
280 g_assert (_gdk_parent_root == NULL);
282 XGetGeometry (gdk_display, _gdk_root_window, &_gdk_root_window,
283 &x, &y, &width, &height, &border_width, &depth);
284 XGetWindowAttributes (gdk_display, _gdk_root_window, &xattributes);
286 _gdk_parent_root = g_object_new (GDK_TYPE_WINDOW, NULL);
287 private = (GdkWindowObject *)_gdk_parent_root;
288 impl = GDK_WINDOW_IMPL_X11 (private->impl);
289 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
291 draw_impl->xdisplay = gdk_display;
292 draw_impl->xid = _gdk_root_window;
293 draw_impl->wrapper = GDK_DRAWABLE (private);
295 private->window_type = GDK_WINDOW_ROOT;
296 private->depth = depth;
298 impl->height = height;
300 gdk_xid_table_insert (&_gdk_root_window, _gdk_parent_root);
303 static Atom wm_client_leader_atom = None;
307 * @parent: a #GdkWindow
308 * @attributes: attributes of the new window
309 * @attributes_mask: mask indicating which fields in @attributes are valid
311 * Creates a new #GdkWindow using the attributes from @attributes. See
312 * #GdkWindowAttr and #GdkWindowAttributesType for more details.
314 * Return value: the new #GdkWindow
317 gdk_window_new (GdkWindow *parent,
318 GdkWindowAttr *attributes,
319 gint attributes_mask)
322 GdkWindowObject *private;
323 GdkWindowImplX11 *impl;
324 GdkDrawableImplX11 *draw_impl;
332 XSetWindowAttributes xattributes;
333 long xattributes_mask;
334 XSizeHints size_hints;
336 XClassHint *class_hint;
344 g_return_val_if_fail (attributes != NULL, NULL);
347 parent = _gdk_parent_root;
349 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
351 if (GDK_WINDOW_DESTROYED (parent))
354 xparent = GDK_WINDOW_XID (parent);
356 window = g_object_new (GDK_TYPE_WINDOW, NULL);
357 private = (GdkWindowObject *)window;
358 impl = GDK_WINDOW_IMPL_X11 (private->impl);
359 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
360 draw_impl->wrapper = GDK_DRAWABLE (window);
362 xdisplay = draw_impl->xdisplay = GDK_WINDOW_XDISPLAY (parent);
364 /* Windows with a foreign parent are treated as if they are children
365 * of the root window, except for actual creation.
367 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
368 parent = _gdk_parent_root;
370 private->parent = (GdkWindowObject *)parent;
372 xattributes_mask = 0;
374 if (attributes_mask & GDK_WA_X)
379 if (attributes_mask & GDK_WA_Y)
386 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
387 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
389 if (attributes->wclass == GDK_INPUT_ONLY)
391 /* Backwards compatiblity - we've always ignored
392 * attributes->window_type for input-only windows
395 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
396 private->window_type = GDK_WINDOW_TEMP;
398 private->window_type = GDK_WINDOW_CHILD;
401 private->window_type = attributes->window_type;
403 _gdk_window_init_position (GDK_WINDOW (private));
404 if (impl->position_info.big)
405 private->guffaw_gravity = TRUE;
407 if (attributes_mask & GDK_WA_VISUAL)
408 visual = attributes->visual;
410 visual = gdk_visual_get_system ();
411 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
413 xattributes.event_mask = StructureNotifyMask;
414 for (i = 0; i < _gdk_nenvent_masks; i++)
416 if (attributes->event_mask & (1 << (i + 1)))
417 xattributes.event_mask |= _gdk_event_mask_table[i];
419 private->event_mask = attributes->event_mask;
421 if (xattributes.event_mask)
422 xattributes_mask |= CWEventMask;
424 if (attributes_mask & GDK_WA_NOREDIR)
426 xattributes.override_redirect =
427 (attributes->override_redirect == FALSE)?False:True;
428 xattributes_mask |= CWOverrideRedirect;
431 xattributes.override_redirect = False;
433 if (private->parent && private->parent->guffaw_gravity)
435 xattributes.win_gravity = StaticGravity;
436 xattributes_mask |= CWWinGravity;
440 switch (private->window_type)
442 case GDK_WINDOW_TOPLEVEL:
443 case GDK_WINDOW_DIALOG:
444 case GDK_WINDOW_TEMP:
445 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
447 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
448 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
449 xparent = _gdk_root_window;
451 case GDK_WINDOW_CHILD:
454 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
458 if (attributes->wclass == GDK_INPUT_OUTPUT)
461 depth = visual->depth;
463 private->input_only = FALSE;
464 private->depth = depth;
466 if (attributes_mask & GDK_WA_COLORMAP)
468 draw_impl->colormap = attributes->colormap;
469 gdk_colormap_ref (attributes->colormap);
473 if ((((GdkVisualPrivate*)gdk_visual_get_system ())->xvisual) == xvisual)
475 draw_impl->colormap =
476 gdk_colormap_get_system ();
477 gdk_colormap_ref (draw_impl->colormap);
481 draw_impl->colormap =
482 gdk_colormap_new (visual, FALSE);
486 private->bg_color.pixel = BlackPixel (gdk_display, _gdk_screen);
487 xattributes.background_pixel = private->bg_color.pixel;
489 private->bg_pixmap = NULL;
491 xattributes.border_pixel = BlackPixel (gdk_display, _gdk_screen);
492 xattributes_mask |= CWBorderPixel | CWBackPixel;
494 if (private->guffaw_gravity)
495 xattributes.bit_gravity = StaticGravity;
497 xattributes.bit_gravity = NorthWestGravity;
499 xattributes_mask |= CWBitGravity;
501 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
502 xattributes_mask |= CWColormap;
504 if (private->window_type == GDK_WINDOW_TEMP)
506 xattributes.save_under = True;
507 xattributes.override_redirect = True;
508 xattributes.cursor = None;
509 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
517 private->input_only = TRUE;
518 draw_impl->colormap = gdk_colormap_get_system ();
519 gdk_colormap_ref (draw_impl->colormap);
522 xid = draw_impl->xid = XCreateWindow (xdisplay, xparent,
523 impl->position_info.x, impl->position_info.y,
524 impl->position_info.width, impl->position_info.height,
525 0, depth, class, xvisual,
526 xattributes_mask, &xattributes);
528 gdk_drawable_ref (window);
529 gdk_xid_table_insert (&draw_impl->xid, window);
531 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
532 (attributes->cursor) :
536 private->parent->children = g_list_prepend (private->parent->children, window);
538 switch (GDK_WINDOW_TYPE (private))
540 case GDK_WINDOW_DIALOG:
541 XSetTransientForHint (xdisplay, xid, xparent);
542 case GDK_WINDOW_TOPLEVEL:
543 case GDK_WINDOW_TEMP:
544 XSetWMProtocols (xdisplay, xid,
545 _gdk_wm_window_protocols, 3);
547 case GDK_WINDOW_CHILD:
548 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
549 (draw_impl->colormap != gdk_colormap_get_system ()) &&
550 (draw_impl->colormap != gdk_window_get_colormap (gdk_window_get_toplevel (window))))
552 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
553 gdk_window_add_colormap_windows (window);
562 if (class != InputOnly)
564 /* The focus window is off the visible area, and serves to receive key
565 * press events so they don't get sent to child windows.
567 impl->focus_window = XCreateSimpleWindow (xdisplay, xid,
569 xattributes.background_pixel,
570 xattributes.background_pixel);
571 /* FIXME: probably better to actually track the requested event mask for the toplevel
573 XSelectInput (xdisplay, impl->focus_window,
574 KeyPressMask | KeyReleaseMask | FocusChangeMask);
576 XMapWindow (xdisplay, impl->focus_window);
577 gdk_xid_table_insert (&impl->focus_window, window);
580 size_hints.flags = PSize;
581 size_hints.width = impl->width;
582 size_hints.height = impl->height;
584 wm_hints.flags = StateHint | WindowGroupHint;
585 wm_hints.window_group = _gdk_leader_window;
586 wm_hints.input = True;
587 wm_hints.initial_state = NormalState;
589 /* FIXME: Is there any point in doing this? Do any WM's pay
590 * attention to PSize, and even if they do, is this the
593 XSetWMNormalHints (xdisplay, xid, &size_hints);
595 XSetWMHints (xdisplay, xid, &wm_hints);
597 if (!wm_client_leader_atom)
598 wm_client_leader_atom = gdk_x11_get_xatom_by_name ("WM_CLIENT_LEADER");
600 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
601 XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
604 XChangeProperty (xdisplay, xid,
605 gdk_x11_get_xatom_by_name ("_NET_WM_PID"),
610 XChangeProperty (xdisplay, xid,
611 wm_client_leader_atom,
612 XA_WINDOW, 32, PropModeReplace,
613 (guchar*) &_gdk_leader_window, 1);
615 if (attributes_mask & GDK_WA_TITLE)
616 title = attributes->title;
618 title = g_get_prgname ();
620 gdk_window_set_title (window, title);
622 if (attributes_mask & GDK_WA_WMCLASS)
624 class_hint = XAllocClassHint ();
625 class_hint->res_name = attributes->wmclass_name;
626 class_hint->res_class = attributes->wmclass_class;
627 XSetClassHint (xdisplay, xid, class_hint);
635 x_event_mask_to_gdk_event_mask (long mask)
637 GdkEventMask event_mask = 0;
640 for (i = 0; i < _gdk_nenvent_masks; i++)
642 if (mask & _gdk_event_mask_table[i])
643 event_mask |= 1 << (i + 1);
650 * gdk_window_foreign_new:
651 * @anid: a native window handle.
653 * Wraps a native window in a #GdkWindow.
654 * This may fail if the window has been destroyed.
656 * For example in the X backend, a native window handle is an Xlib
659 * Return value: the newly-created #GdkWindow wrapper for the
660 * native window or %NULL if the window has been destroyed.
663 gdk_window_foreign_new (GdkNativeWindow anid)
666 GdkWindowObject *private;
667 GdkWindowImplX11 *impl;
668 GdkDrawableImplX11 *draw_impl;
669 XWindowAttributes attrs;
671 Window *children = NULL;
675 gdk_error_trap_push ();
676 result = XGetWindowAttributes (gdk_display, anid, &attrs);
677 if (gdk_error_trap_pop () || !result)
680 /* FIXME: This is pretty expensive. Maybe the caller should supply
682 gdk_error_trap_push ();
683 result = XQueryTree (gdk_display, anid, &root, &parent, &children, &nchildren);
684 if (gdk_error_trap_pop () || !result)
690 window = g_object_new (GDK_TYPE_WINDOW, NULL);
691 private = (GdkWindowObject *)window;
692 impl = GDK_WINDOW_IMPL_X11 (private->impl);
693 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
694 draw_impl->wrapper = GDK_DRAWABLE (window);
696 private->parent = gdk_xid_table_lookup (parent);
697 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
698 private->parent = (GdkWindowObject *)_gdk_parent_root;
700 private->parent->children = g_list_prepend (private->parent->children, window);
702 draw_impl->xid = anid;
703 draw_impl->xdisplay = gdk_display;
705 private->x = attrs.x;
706 private->y = attrs.y;
707 impl->width = attrs.width;
708 impl->height = attrs.height;
709 private->window_type = GDK_WINDOW_FOREIGN;
710 private->destroyed = FALSE;
712 private->event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
714 if (attrs.map_state == IsUnmapped)
715 private->state = GDK_WINDOW_STATE_WITHDRAWN;
719 private->depth = attrs.depth;
721 _gdk_window_init_position (GDK_WINDOW (private));
723 gdk_drawable_ref (window);
724 gdk_xid_table_insert (&GDK_WINDOW_XID (window), window);
731 * @anid: a native window handle.
733 * Looks up the #GdkWindow that wraps the given native window handle.
735 * For example in the X backend, a native window handle is an Xlib
738 * Return value: the #GdkWindow wrapper for the native window,
739 * or %NULL if there is none.
742 gdk_window_lookup (GdkNativeWindow anid)
744 return (GdkWindow*) gdk_xid_table_lookup (anid);
748 _gdk_windowing_window_destroy (GdkWindow *window,
750 gboolean foreign_destroy)
752 GdkWindowObject *private = (GdkWindowObject *)window;
754 g_return_if_fail (GDK_IS_WINDOW (window));
756 _gdk_selection_window_destroyed (window);
758 if (private->extension_events != 0)
759 gdk_input_window_destroy (window);
763 GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
765 if (draw_impl->picture)
766 XRenderFreePicture (draw_impl->xdisplay, draw_impl->picture);
768 #endif /* HAVE_XFT */
770 if (private->window_type == GDK_WINDOW_FOREIGN)
772 if (!foreign_destroy && (private->parent != NULL))
774 /* It's somebody else's window, but in our heirarchy,
775 * so reparent it to the root window, and then send
776 * it a delete event, as if we were a WM
778 XClientMessageEvent xevent;
780 gdk_error_trap_push ();
781 gdk_window_hide (window);
782 gdk_window_reparent (window, NULL, 0, 0);
784 xevent.type = ClientMessage;
785 xevent.window = GDK_WINDOW_XID (window);
786 xevent.message_type = gdk_x11_get_xatom_by_name ("WM_PROTOCOLS");
788 xevent.data.l[0] = gdk_x11_get_xatom_by_name ("WM_DELETE_WINDOW");
789 xevent.data.l[1] = CurrentTime;
791 XSendEvent (GDK_WINDOW_XDISPLAY (window),
792 GDK_WINDOW_XID (window),
793 False, 0, (XEvent *)&xevent);
795 gdk_error_trap_pop ();
798 else if (!recursing && !foreign_destroy)
800 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
804 /* This function is called when the XWindow is really gone.
807 gdk_window_destroy_notify (GdkWindow *window)
809 GdkWindowImplX11 *window_impl;
811 g_return_if_fail (window != NULL);
813 window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
815 if (!GDK_WINDOW_DESTROYED (window))
817 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
818 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
820 _gdk_window_destroy (window, TRUE);
823 gdk_xid_table_remove (GDK_WINDOW_XID (window));
824 if (window_impl->focus_window)
825 gdk_xid_table_remove (window_impl->focus_window);
827 _gdk_xgrab_check_destroy (window);
829 gdk_drawable_unref (window);
833 set_initial_hints (GdkWindow *window)
835 GdkWindowObject *private;
839 private = (GdkWindowObject*) window;
841 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
845 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
846 GDK_WINDOW_XID (window));
848 wm_hints = XAllocWMHints ();
850 wm_hints->flags |= StateHint;
851 wm_hints->initial_state = IconicState;
853 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
854 GDK_WINDOW_XID (window), wm_hints);
858 /* We set the spec hints regardless of whether the spec is supported,
859 * since it can't hurt and it's kind of expensive to check whether
865 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
867 atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_VERT");
869 atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MAXIMIZED_HORZ");
873 if (private->state & GDK_WINDOW_STATE_STICKY)
875 atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_STICKY");
879 if (private->modal_hint)
881 atoms[i] = gdk_x11_get_xatom_by_name ("_NET_WM_STATE_MODAL");
887 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
888 GDK_WINDOW_XID (window),
889 gdk_x11_get_xatom_by_name ("_NET_WM_STATE"),
890 XA_ATOM, 32, PropModeReplace,
894 if (private->state & GDK_WINDOW_STATE_STICKY)
896 atoms[0] = 0xFFFFFFFF;
897 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
898 GDK_WINDOW_XID (window),
899 gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP"),
900 XA_CARDINAL, 32, PropModeReplace,
906 show_window_internal (GdkWindow *window,
909 GdkWindowObject *private;
911 g_return_if_fail (GDK_IS_WINDOW (window));
913 private = (GdkWindowObject*) window;
914 if (!private->destroyed)
917 XRaiseWindow (GDK_WINDOW_XDISPLAY (window),
918 GDK_WINDOW_XID (window));
920 if (!GDK_WINDOW_IS_MAPPED (window))
922 set_initial_hints (window);
924 gdk_synthesize_window_state (window,
925 GDK_WINDOW_STATE_WITHDRAWN,
929 g_assert (GDK_WINDOW_IS_MAPPED (window));
931 if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped)
932 XMapWindow (GDK_WINDOW_XDISPLAY (window),
933 GDK_WINDOW_XID (window));
938 * gdk_window_show_unraised:
939 * @window: a #GdkWindow
941 * Shows a #GdkWindow onscreen, but does not modify its stacking
942 * order. In contrast, gdk_window_show() will raise the window
943 * to the top of the window stack.
945 * On the X11 platform, in Xlib terms, this function calls
946 * XMapWindow() (it also updates some internal GDK state, which means
947 * that you can't really use XMapWindow() directly on a GDK window).
951 gdk_window_show_unraised (GdkWindow *window)
953 g_return_if_fail (GDK_IS_WINDOW (window));
955 show_window_internal (window, FALSE);
960 * @window: a #GdkWindow
962 * Like gdk_window_show_unraised(), but also raises the window to the
963 * top of the window stack (moves the window to the front of the
966 * This function maps a window so it's visible onscreen. Its opposite
967 * is gdk_window_hide().
969 * When implementing a #GtkWidget, you should call this function on the widget's
970 * #GdkWindow as part of the "map" method.
974 gdk_window_show (GdkWindow *window)
976 g_return_if_fail (GDK_IS_WINDOW (window));
978 show_window_internal (window, TRUE);
983 * @window: a #GdkWindow
985 * For toplevel windows, withdraws them, so they will no longer be
986 * known to the window manager; for all windows, unmaps them, so
987 * they won't be displayed. Normally done automatically as
988 * part of gtk_widget_hide().
992 gdk_window_hide (GdkWindow *window)
994 GdkWindowObject *private;
996 g_return_if_fail (window != NULL);
998 private = (GdkWindowObject*) window;
1000 /* We'll get the unmap notify eventually, and handle it then,
1001 * but checking here makes things more consistent if we are
1002 * just doing stuff ourself.
1004 _gdk_xgrab_check_unmap (window,
1005 NextRequest (GDK_WINDOW_XDISPLAY (window)));
1007 /* You can't simply unmap toplevel windows. */
1008 switch (private->window_type)
1010 case GDK_WINDOW_TOPLEVEL:
1011 case GDK_WINDOW_DIALOG:
1012 case GDK_WINDOW_TEMP: /* ? */
1013 gdk_window_withdraw (window);
1017 case GDK_WINDOW_FOREIGN:
1018 case GDK_WINDOW_ROOT:
1019 case GDK_WINDOW_CHILD:
1023 if (!private->destroyed)
1025 if (GDK_WINDOW_IS_MAPPED (window))
1026 gdk_synthesize_window_state (window,
1028 GDK_WINDOW_STATE_WITHDRAWN);
1030 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1032 _gdk_window_clear_update_area (window);
1034 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
1035 GDK_WINDOW_XID (window));
1040 * gdk_window_withdraw:
1041 * @window: a toplevel #GdkWindow
1043 * Withdraws a window (unmaps it and asks the window manager to forget about it).
1044 * Normally done automatically by gtk_widget_hide() called on a #GtkWindow.
1048 gdk_window_withdraw (GdkWindow *window)
1050 GdkWindowObject *private;
1052 g_return_if_fail (window != NULL);
1054 private = (GdkWindowObject*) window;
1055 if (!private->destroyed)
1057 if (GDK_WINDOW_IS_MAPPED (window))
1058 gdk_synthesize_window_state (window,
1060 GDK_WINDOW_STATE_WITHDRAWN);
1062 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1064 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
1065 GDK_WINDOW_XID (window), 0);
1071 * @window: a #GdkWindow
1072 * @x: X coordinate relative to window's parent
1073 * @y: Y coordinate relative to window's parent
1075 * Repositions a window relative to its parent window.
1076 * For toplevel windows, window managers may ignore or modify the move;
1077 * you should probably use gtk_window_move() on a #GtkWindow widget
1078 * anyway, instead of using GDK functions. For child windows,
1079 * the move will reliably succeed.
1081 * If you're also planning to resize the window, use gdk_window_move_resize()
1082 * to both move and resize simultaneously, for a nicer visual effect.
1086 gdk_window_move (GdkWindow *window,
1090 GdkWindowObject *private = (GdkWindowObject *)window;
1091 GdkWindowImplX11 *impl;
1093 g_return_if_fail (window != NULL);
1094 g_return_if_fail (GDK_IS_WINDOW (window));
1096 impl = GDK_WINDOW_IMPL_X11 (private->impl);
1098 if (!GDK_WINDOW_DESTROYED (window))
1100 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1101 _gdk_window_move_resize_child (window, x, y,
1102 impl->width, impl->height);
1105 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
1106 GDK_WINDOW_XID (window),
1113 * gdk_window_resize:
1114 * @window: a #GdkWindow
1115 * @width: new width of the window
1116 * @height: new height of the window
1118 * Resizes @window; for toplevel windows, asks the window manager to resize
1119 * the window. The window manager may not allow the resize. When using GTK+,
1120 * use gtk_window_resize() instead of this low-level GDK function.
1122 * Windows may not be resized below 1x1.
1124 * If you're also planning to move the window, use gdk_window_move_resize()
1125 * to both move and resize simultaneously, for a nicer visual effect.
1129 gdk_window_resize (GdkWindow *window,
1133 GdkWindowObject *private;
1135 g_return_if_fail (window != NULL);
1136 g_return_if_fail (GDK_IS_WINDOW (window));
1143 private = (GdkWindowObject*) window;
1145 if (!GDK_WINDOW_DESTROYED (window))
1147 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1148 _gdk_window_move_resize_child (window, private->x, private->y,
1152 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1154 if (width != impl->width || height != impl->height)
1155 private->resize_count += 1;
1157 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
1158 GDK_WINDOW_XID (window),
1165 * gdk_window_move_resize:
1166 * @window: a #GdkWindow
1167 * @x: new X position relative to window's parent
1168 * @y: new Y position relative to window's parent
1170 * @height: new height
1172 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
1173 * except that both operations are performed at once, avoiding strange
1174 * visual effects. (i.e. the user may be able to see the window first
1175 * move, then resize, if you don't use gdk_window_move_resize().)
1179 gdk_window_move_resize (GdkWindow *window,
1185 GdkWindowObject *private;
1187 g_return_if_fail (window != NULL);
1188 g_return_if_fail (GDK_IS_WINDOW (window));
1195 private = (GdkWindowObject*) window;
1197 if (!GDK_WINDOW_DESTROYED (window))
1199 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1200 _gdk_window_move_resize_child (window, x, y, width, height);
1203 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1205 if (width != impl->width || height != impl->height)
1206 private->resize_count += 1;
1208 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
1209 GDK_WINDOW_XID (window),
1210 x, y, width, height);
1216 * gdk_window_reparent:
1217 * @window: a #GdkWindow
1218 * @new_parent: new parent to move @window into
1219 * @x: X location inside the new parent
1220 * @y: Y location inside the new parent
1222 * Reparents @window into the given @new_parent. The window being
1223 * reparented will be unmapped as a side effect.
1227 gdk_window_reparent (GdkWindow *window,
1228 GdkWindow *new_parent,
1232 GdkWindowObject *window_private;
1233 GdkWindowObject *parent_private;
1234 GdkWindowObject *old_parent_private;
1236 g_return_if_fail (window != NULL);
1237 g_return_if_fail (GDK_IS_WINDOW (window));
1238 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1239 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1242 new_parent = _gdk_parent_root;
1244 window_private = (GdkWindowObject*) window;
1245 old_parent_private = (GdkWindowObject*)window_private->parent;
1246 parent_private = (GdkWindowObject*) new_parent;
1248 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (new_parent))
1249 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1250 GDK_WINDOW_XID (window),
1251 GDK_WINDOW_XID (new_parent),
1254 window_private->x = x;
1255 window_private->y = y;
1257 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1260 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1261 new_parent = _gdk_parent_root;
1263 window_private->parent = (GdkWindowObject *)new_parent;
1265 /* Switch the window type as appropriate */
1267 switch (GDK_WINDOW_TYPE (new_parent))
1269 case GDK_WINDOW_ROOT:
1270 case GDK_WINDOW_FOREIGN:
1271 /* Now a toplevel */
1272 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1274 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1275 XSetWMProtocols (GDK_WINDOW_XDISPLAY (window),
1276 GDK_WINDOW_XID (window),
1277 _gdk_wm_window_protocols, 3);
1279 case GDK_WINDOW_TOPLEVEL:
1280 case GDK_WINDOW_CHILD:
1281 case GDK_WINDOW_DIALOG:
1282 case GDK_WINDOW_TEMP:
1283 if (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD &&
1284 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
1286 /* If we were being sophisticated, we'd save the old window type
1287 * here, and restore it if we were reparented back to the
1288 * toplevel. However, the difference between different types
1289 * of toplevels only really matters on creation anyways.
1291 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1295 if (old_parent_private)
1296 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1298 if ((old_parent_private &&
1299 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1300 (!old_parent_private && parent_private->guffaw_gravity))
1301 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1303 parent_private->children = g_list_prepend (parent_private->children, window);
1304 _gdk_window_init_position (GDK_WINDOW (window_private));
1308 _gdk_windowing_window_clear_area (GdkWindow *window,
1314 g_return_if_fail (window != NULL);
1315 g_return_if_fail (GDK_IS_WINDOW (window));
1317 if (!GDK_WINDOW_DESTROYED (window))
1318 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1319 x, y, width, height, False);
1323 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1329 g_return_if_fail (window != NULL);
1330 g_return_if_fail (GDK_IS_WINDOW (window));
1332 if (!GDK_WINDOW_DESTROYED (window))
1333 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1334 x, y, width, height, True);
1340 * @window: a #GdkWindow
1342 * Raises @window to the top of the Z-order (stacking order), so that
1343 * other windows with the same parent window appear below @window.
1344 * If @window is a toplevel, the window manager may choose to deny the
1345 * request to move the window in the Z-order, gdk_window_raise() only
1346 * requests the restack, does not guarantee it.
1350 gdk_window_raise (GdkWindow *window)
1352 g_return_if_fail (window != NULL);
1353 g_return_if_fail (GDK_IS_WINDOW (window));
1355 if (!GDK_WINDOW_DESTROYED (window))
1356 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1361 * @window: a #GdkWindow
1363 * Lowers @window to the bottom of the Z-order (stacking order), so that
1364 * other windows with the same parent window appear above @window.
1365 * If @window is a toplevel, the window manager may choose to deny the
1366 * request to move the window in the Z-order, gdk_window_lower() only
1367 * requests the restack, does not guarantee it.
1369 * Note that gdk_window_show() raises the window again, so don't call this
1370 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
1374 gdk_window_lower (GdkWindow *window)
1376 g_return_if_fail (window != NULL);
1377 g_return_if_fail (GDK_IS_WINDOW (window));
1379 if (!GDK_WINDOW_DESTROYED (window))
1380 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1385 * @window: a #GdkWindow
1386 * @timestamp: timestamp of the event triggering the window focus
1388 * Sets keyboard focus to @window. If @window is not onscreen this
1389 * will not work. In most cases, gtk_window_present() should be used on
1390 * a #GtkWindow, rather than calling this function.
1394 gdk_window_focus (GdkWindow *window,
1397 g_return_if_fail (GDK_IS_WINDOW (window));
1399 if (GDK_WINDOW_DESTROYED (window))
1402 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
1406 xev.xclient.type = ClientMessage;
1407 xev.xclient.serial = 0;
1408 xev.xclient.send_event = True;
1409 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
1410 xev.xclient.display = gdk_display;
1411 xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_ACTIVE_WINDOW");
1412 xev.xclient.format = 32;
1413 xev.xclient.data.l[0] = 0;
1415 XSendEvent (gdk_display, _gdk_root_window, False,
1416 SubstructureRedirectMask | SubstructureNotifyMask,
1421 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1423 /* There is no way of knowing reliably whether we are viewable so we need
1424 * to trap errors so we don't cause a BadMatch.
1426 gdk_error_trap_push ();
1427 XSetInputFocus (GDK_WINDOW_XDISPLAY (window),
1428 GDK_WINDOW_XWINDOW (window),
1431 XSync (GDK_WINDOW_XDISPLAY (window), False);
1432 gdk_error_trap_pop ();
1437 * gdk_window_set_hints:
1438 * @window: a #GdkWindow
1439 * @x: ignored field, does not matter
1440 * @y: ignored field, does not matter
1441 * @min_width: minimum width hint
1442 * @min_height: minimum height hint
1443 * @max_width: max width hint
1444 * @max_height: max height hint
1445 * @flags: logical OR of GDK_HINT_POS, GDK_HINT_MIN_SIZE, and/or GDK_HINT_MAX_SIZE
1447 * This function is broken and useless and you should ignore it.
1448 * If using GTK+, use functions such as gtk_window_resize(), gtk_window_set_size_request(),
1449 * gtk_window_move(), gtk_window_parse_geometry(), and gtk_window_set_geometry_hints(),
1450 * depending on what you're trying to do.
1452 * If using GDK directly, use gdk_window_set_geometry_hints().
1456 gdk_window_set_hints (GdkWindow *window,
1465 XSizeHints size_hints;
1467 g_return_if_fail (window != NULL);
1468 g_return_if_fail (GDK_IS_WINDOW (window));
1470 if (GDK_WINDOW_DESTROYED (window))
1473 size_hints.flags = 0;
1475 if (flags & GDK_HINT_POS)
1477 size_hints.flags |= PPosition;
1482 if (flags & GDK_HINT_MIN_SIZE)
1484 size_hints.flags |= PMinSize;
1485 size_hints.min_width = min_width;
1486 size_hints.min_height = min_height;
1489 if (flags & GDK_HINT_MAX_SIZE)
1491 size_hints.flags |= PMaxSize;
1492 size_hints.max_width = max_width;
1493 size_hints.max_height = max_height;
1496 /* FIXME: Would it be better to delete this property if
1497 * flags == 0? It would save space on the server
1499 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1500 GDK_WINDOW_XID (window),
1505 * gdk_window_set_type_hint:
1506 * @window: A #GdkWindow
1507 * @hint: A hint of the function this window will have
1509 * The application can use this call to provide a hint to the window
1510 * manager about the functionality of a window. The window manager
1511 * can use this information when determining the decoration and behaviour
1514 * The hint must be set before the window is mapped.
1517 gdk_window_set_type_hint (GdkWindow *window,
1518 GdkWindowTypeHint hint)
1522 g_return_if_fail (window != NULL);
1523 g_return_if_fail (GDK_IS_WINDOW (window));
1525 if (GDK_WINDOW_DESTROYED (window))
1530 case GDK_WINDOW_TYPE_HINT_DIALOG:
1531 atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_DIALOG");
1533 case GDK_WINDOW_TYPE_HINT_MENU:
1534 atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_MENU");
1536 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
1537 atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_TOOLBAR");
1540 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
1542 case GDK_WINDOW_TYPE_HINT_NORMAL:
1543 atom = gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE_NORMAL");
1547 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1548 GDK_WINDOW_XID (window),
1549 gdk_x11_get_xatom_by_name ("_NET_WM_WINDOW_TYPE"),
1550 XA_ATOM, 32, PropModeReplace,
1551 (guchar *)&atom, 1);
1556 gdk_wmspec_change_state (gboolean add,
1563 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
1564 #define _NET_WM_STATE_ADD 1 /* add/set property */
1565 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
1567 xev.xclient.type = ClientMessage;
1568 xev.xclient.serial = 0;
1569 xev.xclient.send_event = True;
1570 xev.xclient.display = gdk_display;
1571 xev.xclient.window = GDK_WINDOW_XID (window);
1572 xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
1573 xev.xclient.format = 32;
1574 xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
1575 xev.xclient.data.l[1] = gdk_x11_atom_to_xatom (state1);
1576 xev.xclient.data.l[2] = gdk_x11_atom_to_xatom (state2);
1578 XSendEvent (gdk_display, _gdk_root_window, False,
1579 SubstructureRedirectMask | SubstructureNotifyMask,
1583 * gdk_window_set_modal_hint:
1584 * @window: A #GdkWindow
1585 * @modal: TRUE if the window is modal, FALSE otherwise.
1587 * The application can use this hint to tell the window manager
1588 * that a certain window has modal behaviour. The window manager
1589 * can use this information to handle modal windows in a special
1592 * You should only use this on windows for which you have
1593 * previously called #gdk_window_set_transient_for()
1596 gdk_window_set_modal_hint (GdkWindow *window,
1599 GdkWindowObject *private;
1601 g_return_if_fail (window != NULL);
1602 g_return_if_fail (GDK_IS_WINDOW (window));
1604 if (GDK_WINDOW_DESTROYED (window))
1607 private = (GdkWindowObject*) window;
1609 private->modal_hint = modal;
1611 if (GDK_WINDOW_IS_MAPPED (window))
1612 gdk_wmspec_change_state (modal, window,
1613 gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE),
1618 * gdk_window_set_geometry_hints:
1619 * @window: a #GdkWindow
1620 * @geometry: geometry hints
1621 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
1623 * Sets the geometry hints for @window. Hints flagged in @geom_mask
1624 * are set, hints not flagged in @geom_mask are unset.
1625 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
1629 gdk_window_set_geometry_hints (GdkWindow *window,
1630 GdkGeometry *geometry,
1631 GdkWindowHints geom_mask)
1633 XSizeHints size_hints;
1635 g_return_if_fail (window != NULL);
1636 g_return_if_fail (GDK_IS_WINDOW (window));
1638 if (GDK_WINDOW_DESTROYED (window))
1641 size_hints.flags = 0;
1643 if (geom_mask & GDK_HINT_POS)
1645 size_hints.flags |= PPosition;
1646 /* We need to initialize the following obsolete fields because KWM
1647 * apparently uses these fields if they are non-zero.
1654 if (geom_mask & GDK_HINT_USER_POS)
1656 size_hints.flags |= USPosition;
1659 if (geom_mask & GDK_HINT_USER_SIZE)
1661 size_hints.flags |= USSize;
1664 if (geom_mask & GDK_HINT_MIN_SIZE)
1666 size_hints.flags |= PMinSize;
1667 size_hints.min_width = geometry->min_width;
1668 size_hints.min_height = geometry->min_height;
1671 if (geom_mask & GDK_HINT_MAX_SIZE)
1673 size_hints.flags |= PMaxSize;
1674 size_hints.max_width = MAX (geometry->max_width, 1);
1675 size_hints.max_height = MAX (geometry->max_height, 1);
1678 if (geom_mask & GDK_HINT_BASE_SIZE)
1680 size_hints.flags |= PBaseSize;
1681 size_hints.base_width = geometry->base_width;
1682 size_hints.base_height = geometry->base_height;
1685 if (geom_mask & GDK_HINT_RESIZE_INC)
1687 size_hints.flags |= PResizeInc;
1688 size_hints.width_inc = geometry->width_inc;
1689 size_hints.height_inc = geometry->height_inc;
1692 if (geom_mask & GDK_HINT_ASPECT)
1694 size_hints.flags |= PAspect;
1695 if (geometry->min_aspect <= 1)
1697 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
1698 size_hints.min_aspect.y = 65536;
1702 size_hints.min_aspect.x = 65536;
1703 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
1705 if (geometry->max_aspect <= 1)
1707 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
1708 size_hints.max_aspect.y = 65536;
1712 size_hints.max_aspect.x = 65536;
1713 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
1717 if (geom_mask & GDK_HINT_WIN_GRAVITY)
1719 size_hints.flags |= PWinGravity;
1720 size_hints.win_gravity = geometry->win_gravity;
1723 /* FIXME: Would it be better to delete this property if
1724 * geom_mask == 0? It would save space on the server
1726 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1727 GDK_WINDOW_XID (window),
1732 gdk_window_get_geometry_hints (GdkWindow *window,
1733 GdkGeometry *geometry,
1734 GdkWindowHints *geom_mask)
1736 XSizeHints size_hints;
1737 glong junk_size_mask = 0;
1739 g_return_if_fail (GDK_IS_WINDOW (window));
1740 g_return_if_fail (geometry != NULL);
1741 g_return_if_fail (geom_mask != NULL);
1745 if (GDK_WINDOW_DESTROYED (window))
1748 if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
1749 GDK_WINDOW_XID (window),
1754 if (size_hints.flags & PMinSize)
1756 *geom_mask |= GDK_HINT_MIN_SIZE;
1757 geometry->min_width = size_hints.min_width;
1758 geometry->min_height = size_hints.min_height;
1761 if (size_hints.flags & PMaxSize)
1763 *geom_mask |= GDK_HINT_MAX_SIZE;
1764 geometry->max_width = MAX (size_hints.max_width, 1);
1765 geometry->max_height = MAX (size_hints.max_height, 1);
1768 if (size_hints.flags & PResizeInc)
1770 *geom_mask |= GDK_HINT_RESIZE_INC;
1771 geometry->width_inc = size_hints.width_inc;
1772 geometry->height_inc = size_hints.height_inc;
1775 if (size_hints.flags & PAspect)
1777 *geom_mask |= GDK_HINT_ASPECT;
1779 geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
1780 geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
1783 if (size_hints.flags & PWinGravity)
1785 *geom_mask |= GDK_HINT_WIN_GRAVITY;
1786 geometry->win_gravity = size_hints.win_gravity;
1791 utf8_is_latin1 (const gchar *str)
1793 const char *p = str;
1797 gunichar ch = g_utf8_get_char (p);
1802 p = g_utf8_next_char (p);
1808 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
1809 * convertable to STRING, otherwise, set it as compound text
1812 set_text_property (GdkWindow *window,
1814 const gchar *utf8_str)
1816 guchar *prop_text = NULL;
1821 if (utf8_is_latin1 (utf8_str))
1823 prop_type = XA_STRING;
1824 prop_text = gdk_utf8_to_string_target (utf8_str);
1825 prop_length = prop_text ? strlen (prop_text) : 0;
1832 gdk_utf8_to_compound_text (utf8_str, &gdk_type, &prop_format,
1833 &prop_text, &prop_length);
1834 prop_type = gdk_x11_atom_to_xatom (gdk_type);
1839 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1840 GDK_WINDOW_XID (window),
1842 prop_type, prop_format,
1843 PropModeReplace, prop_text,
1851 * gdk_window_set_title:
1852 * @window: a #GdkWindow
1853 * @title: title of @window
1855 * Sets the title of a toplevel window, to be displayed in the titlebar.
1856 * If you haven't explicitly set the icon name for the window
1857 * (using gdk_window_set_icon_name()), the icon name will be set to
1858 * @title as well. @title must be in UTF-8 encoding (as with all
1859 * user-readable strings in GDK/GTK+). @title may not be %NULL.
1863 gdk_window_set_title (GdkWindow *window,
1866 g_return_if_fail (window != NULL);
1867 g_return_if_fail (GDK_IS_WINDOW (window));
1868 g_return_if_fail (title != NULL);
1870 if (GDK_WINDOW_DESTROYED (window))
1873 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1874 GDK_WINDOW_XID (window),
1875 gdk_x11_get_xatom_by_name ("_NET_WM_NAME"),
1876 gdk_x11_get_xatom_by_name ("UTF8_STRING"), 8,
1877 PropModeReplace, title,
1880 set_text_property (window, gdk_x11_get_xatom_by_name ("WM_NAME"), title);
1881 if (!gdk_window_icon_name_set (window))
1883 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
1884 GDK_WINDOW_XID (window),
1885 gdk_x11_get_xatom_by_name ("_NET_WM_ICON_NAME"),
1886 gdk_x11_get_xatom_by_name ("UTF8_STRING"), 8,
1887 PropModeReplace, title,
1889 set_text_property (window, gdk_x11_get_xatom_by_name ("WM_ICON_NAME"), title);
1894 * gdk_window_set_role:
1895 * @window: a #GdkWindow
1896 * @role: a string indicating its role
1898 * When using GTK+, typically you should use gtk_window_set_role() instead
1899 * of this low-level function.
1901 * The window manager and session manager use a window's role to
1902 * distinguish it from other kinds of window in the same application.
1903 * When an application is restarted after being saved in a previous
1904 * session, all windows with the same title and role are treated as
1905 * interchangeable. So if you have two windows with the same title
1906 * that should be distinguished for session management purposes, you
1907 * should set the role on those windows. It doesn't matter what string
1908 * you use for the role, as long as you have a different role for each
1909 * non-interchangeable kind of window.
1913 gdk_window_set_role (GdkWindow *window,
1916 g_return_if_fail (window != NULL);
1917 g_return_if_fail (GDK_IS_WINDOW (window));
1919 if (!GDK_WINDOW_DESTROYED (window))
1922 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1923 gdk_x11_get_xatom_by_name ("WM_WINDOW_ROLE"), XA_STRING,
1924 8, PropModeReplace, role, strlen (role));
1926 XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1927 gdk_x11_get_xatom_by_name ("WM_WINDOW_ROLE"));
1932 * gdk_window_set_transient_for:
1933 * @window: a toplevel #GdkWindow
1934 * @parent: another toplevel #GdkWindow
1936 * Indicates to the window manager that @window is a transient dialog
1937 * associated with the application window @parent. This allows the
1938 * window manager to do things like center @window on @parent and
1939 * keep @window above @parent.
1941 * See gtk_window_set_transient_for() if you're using #GtkWindow or
1946 gdk_window_set_transient_for (GdkWindow *window,
1949 GdkWindowObject *private;
1950 GdkWindowObject *parent_private;
1952 g_return_if_fail (window != NULL);
1953 g_return_if_fail (GDK_IS_WINDOW (window));
1955 private = (GdkWindowObject*) window;
1956 parent_private = (GdkWindowObject*) parent;
1958 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
1959 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
1960 GDK_WINDOW_XID (window),
1961 GDK_WINDOW_XID (parent));
1965 * gdk_window_set_background:
1966 * @window: a #GdkWindow
1967 * @color: an allocated #GdkColor
1969 * Sets the background color of @window. (However, when using GTK+,
1970 * set the background of a widget with gtk_widget_modify_bg() - if
1971 * you're an application - or gtk_style_set_background() - if you're
1972 * implementing a custom widget.)
1974 * The @color must be allocated; gdk_rgb_find_color() is the best way
1975 * to allocate a color.
1977 * See also gdk_window_set_back_pixmap().
1981 gdk_window_set_background (GdkWindow *window,
1984 GdkWindowObject *private = (GdkWindowObject *)window;
1986 g_return_if_fail (window != NULL);
1987 g_return_if_fail (GDK_IS_WINDOW (window));
1989 if (!GDK_WINDOW_DESTROYED (window))
1990 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
1991 GDK_WINDOW_XID (window), color->pixel);
1993 private->bg_color = *color;
1995 if (private->bg_pixmap &&
1996 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
1997 private->bg_pixmap != GDK_NO_BG)
1998 gdk_pixmap_unref (private->bg_pixmap);
2000 private->bg_pixmap = NULL;
2004 * gdk_window_set_back_pixmap:
2005 * @window: a #GdkWindow
2006 * @pixmap: a #GdkPixmap, or %NULL
2007 * @parent_relative: whether the tiling origin is at the origin of @window's parent
2009 * Sets the background pixmap of @window. May also be used to set a background of
2010 * "None" on @window, by setting a background pixmap of %NULL.
2011 * A background pixmap will be tiled, positioning the first tile at the origin of
2012 * @window, or if @parent_relative is %TRUE, the tiling will be done based on the
2013 * origin of the parent window (useful to align tiles in a parent with tiles
2016 * A background pixmap of %NULL means that the window will have no
2017 * background. A window with no background will never have its
2018 * background filled by the windowing system, instead the window will
2019 * contain whatever pixels were already in the corresponding area of
2022 * The windowing system will normally fill a window with its background
2023 * when the window is obscured then exposed, and when you call
2024 * gdk_window_clear().
2028 gdk_window_set_back_pixmap (GdkWindow *window,
2030 gboolean parent_relative)
2032 GdkWindowObject *private = (GdkWindowObject *)window;
2035 g_return_if_fail (window != NULL);
2036 g_return_if_fail (GDK_IS_WINDOW (window));
2037 g_return_if_fail (pixmap == NULL || !parent_relative);
2039 if (private->bg_pixmap &&
2040 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2041 private->bg_pixmap != GDK_NO_BG)
2042 gdk_pixmap_unref (private->bg_pixmap);
2044 if (parent_relative)
2046 xpixmap = ParentRelative;
2047 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
2053 gdk_pixmap_ref (pixmap);
2054 private->bg_pixmap = pixmap;
2055 xpixmap = GDK_PIXMAP_XID (pixmap);
2060 private->bg_pixmap = GDK_NO_BG;
2064 if (!GDK_WINDOW_DESTROYED (window))
2065 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2066 GDK_WINDOW_XID (window), xpixmap);
2070 * gdk_window_set_cursor:
2071 * @window: a #GdkWindow
2074 * Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new() or
2075 * gdk_cursor_new_from_pixmap() to create the cursor.
2076 * To make the cursor invisible, use gdk_cursor_new_from_pixmap() to create
2077 * a cursor with no pixels in it. Passing %NULL for the @cursor argument
2078 * to gdk_window_set_cursor() means that @window will use the cursor of
2079 * its parent window. Most windows should use this default.
2083 gdk_window_set_cursor (GdkWindow *window,
2086 GdkCursorPrivate *cursor_private;
2089 g_return_if_fail (window != NULL);
2090 g_return_if_fail (GDK_IS_WINDOW (window));
2092 cursor_private = (GdkCursorPrivate*) cursor;
2097 xcursor = cursor_private->xcursor;
2099 if (!GDK_WINDOW_DESTROYED (window))
2100 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
2101 GDK_WINDOW_XID (window),
2106 * gdk_window_get_geometry:
2107 * @window: a #GdkWindow
2108 * @x: return location for X coordinate of window (relative to its parent)
2109 * @y: return location for Y coordinate of window (relative to its parent)
2110 * @width: return location for width of window
2111 * @height: return location for height of window
2112 * @depth: return location for bit depth of window
2114 * Any of the return location arguments to this function may be %NULL,
2115 * if you aren't interested in getting the value of that field.
2117 * The X and Y coordinates returned are relative to the parent window
2118 * of @window, which for toplevels usually means relative to the
2119 * window decorations (titlebar, etc.) rather than relative to the
2120 * root window (screen-size background window).
2122 * On the X11 platform, the geometry is obtained from the X server,
2123 * so reflects the latest position of @window; this may be out-of-sync
2124 * with the position of @window delivered in the most-recently-processed
2125 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
2126 * position from the most recent configure event.
2130 gdk_window_get_geometry (GdkWindow *window,
2142 guint tborder_width;
2145 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2148 window = _gdk_parent_root;
2150 if (!GDK_WINDOW_DESTROYED (window))
2152 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
2153 GDK_WINDOW_XID (window),
2154 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
2170 * gdk_window_get_origin:
2171 * @window: a #GdkWindow
2172 * @x: return location for X coordinate
2173 * @y: return location for Y coordinate
2175 * Obtains the position of a window in root window coordinates.
2176 * (Compare with gdk_window_get_position() and
2177 * gdk_window_get_geometry() which return the position of a window
2178 * relative to its parent window.)
2180 * Return value: not meaningful, ignore
2183 gdk_window_get_origin (GdkWindow *window,
2192 g_return_val_if_fail (window != NULL, 0);
2194 if (!GDK_WINDOW_DESTROYED (window))
2196 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2197 GDK_WINDOW_XID (window),
2215 * gdk_window_get_deskrelative_origin:
2216 * @window: a #GdkWindow
2217 * @x: return location for X coordinate
2218 * @y: return location for Y coordinate
2220 * This gets the origin of a #GdkWindow relative to
2221 * an Enlightenment-window-manager desktop. As long as you don't
2222 * assume that the user's desktop/workspace covers the entire
2223 * root window (i.e. you don't assume that the desktop begins
2224 * at root window coordinate 0,0) this function is not necessary.
2225 * It's deprecated for that reason.
2227 * Return value: not meaningful
2230 gdk_window_get_deskrelative_origin (GdkWindow *window,
2234 gboolean return_val = FALSE;
2235 gint num_children, format_return;
2236 Window win, *child, parent, root;
2240 static Atom atom = 0;
2241 gulong number_return, bytes_after_return;
2242 guchar *data_return;
2244 g_return_val_if_fail (window != NULL, 0);
2245 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2247 if (!GDK_WINDOW_DESTROYED (window))
2250 atom = gdk_x11_get_xatom_by_name ("ENLIGHTENMENT_DESKTOP");
2251 win = GDK_WINDOW_XID (window);
2253 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
2254 &child, (unsigned int *)&num_children))
2256 if ((child) && (num_children > 0))
2268 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
2269 False, XA_CARDINAL, &type_return, &format_return,
2270 &number_return, &bytes_after_return, &data_return);
2271 if (type_return == XA_CARDINAL)
2273 XFree (data_return);
2278 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2279 GDK_WINDOW_XID (window),
2294 * gdk_window_get_root_origin:
2295 * @window: a #GdkWindow
2296 * @x: return location for X position of window frame
2297 * @y: return location for Y position of window frame
2299 * Obtains the top-left corner of the window manager frame in root
2300 * window coordinates.
2304 gdk_window_get_root_origin (GdkWindow *window,
2310 g_return_if_fail (GDK_IS_WINDOW (window));
2312 gdk_window_get_frame_extents (window, &rect);
2322 * gdk_window_get_frame_extents:
2323 * @window: a #GdkWindow
2324 * @rect: rectangle to fill with bounding box of the window frame
2326 * Obtains the bounding box of the window, including window manager
2327 * titlebar/borders if any. The frame position is given in root window
2328 * coordinates. To get the position of the window itself (rather than
2329 * the frame) in root window coordinates, use gdk_window_get_origin().
2333 gdk_window_get_frame_extents (GdkWindow *window,
2336 GdkWindowObject *private;
2341 unsigned int nchildren;
2343 g_return_if_fail (GDK_IS_WINDOW (window));
2344 g_return_if_fail (rect != NULL);
2346 private = (GdkWindowObject*) window;
2353 if (GDK_WINDOW_DESTROYED (window))
2356 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
2357 private = (GdkWindowObject*) private->parent;
2358 if (GDK_WINDOW_DESTROYED (window))
2361 xparent = GDK_WINDOW_XID (window);
2365 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
2367 &children, &nchildren))
2373 while (xparent != root);
2375 if (xparent == root)
2377 unsigned int ww, wh, wb, wd;
2380 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
2391 _gdk_windowing_window_get_pointer (GdkWindow *window,
2394 GdkModifierType *mask)
2396 GdkWindow *return_val;
2402 unsigned int xmask = 0;
2403 gint xoffset, yoffset;
2405 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
2408 window = _gdk_parent_root;
2410 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2413 if (!GDK_WINDOW_DESTROYED (window) &&
2414 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
2415 GDK_WINDOW_XID (window),
2416 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
2419 return_val = gdk_window_lookup (child);
2423 *x = winx + xoffset;
2425 *y = winy + yoffset;
2433 _gdk_windowing_window_at_pointer (GdkScreen *screen,
2440 Window xwindow_last = 0;
2442 int rootx = -1, rooty = -1;
2446 xwindow = GDK_ROOT_WINDOW ();
2447 xdisplay = GDK_DISPLAY ();
2449 gdk_x11_grab_server ();
2452 xwindow_last = xwindow;
2453 XQueryPointer (xdisplay, xwindow,
2459 gdk_x11_ungrab_server ();
2461 window = gdk_window_lookup (xwindow_last);
2464 *win_x = window ? winx : -1;
2466 *win_y = window ? winy : -1;
2472 * gdk_window_get_events:
2473 * @window: a #GdkWindow
2475 * Gets the event mask for @window. See gdk_window_set_events().
2477 * Return value: event mask for @window
2480 gdk_window_get_events (GdkWindow *window)
2482 XWindowAttributes attrs;
2483 GdkEventMask event_mask;
2485 g_return_val_if_fail (window != NULL, 0);
2486 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
2488 if (GDK_WINDOW_DESTROYED (window))
2492 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2493 GDK_WINDOW_XID (window),
2496 event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
2497 GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
2504 * gdk_window_set_events:
2505 * @window: a #GdkWindow
2506 * @event_mask: event mask for @window
2508 * The event mask for a window determines which events will be reported
2509 * for that window. For example, an event mask including #GDK_BUTTON_PRESS_MASK
2510 * means the window should report button press events. The event mask
2511 * is the bitwise OR of values from the #GdkEventMask enumeration.
2515 gdk_window_set_events (GdkWindow *window,
2516 GdkEventMask event_mask)
2521 g_return_if_fail (window != NULL);
2522 g_return_if_fail (GDK_IS_WINDOW (window));
2524 if (!GDK_WINDOW_DESTROYED (window))
2526 GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
2527 xevent_mask = StructureNotifyMask;
2528 for (i = 0; i < _gdk_nenvent_masks; i++)
2530 if (event_mask & (1 << (i + 1)))
2531 xevent_mask |= _gdk_event_mask_table[i];
2534 XSelectInput (GDK_WINDOW_XDISPLAY (window),
2535 GDK_WINDOW_XID (window),
2541 gdk_window_add_colormap_windows (GdkWindow *window)
2543 GdkWindow *toplevel;
2544 Window *old_windows;
2545 Window *new_windows;
2548 g_return_if_fail (window != NULL);
2549 g_return_if_fail (GDK_IS_WINDOW (window));
2551 toplevel = gdk_window_get_toplevel (window);
2552 if (GDK_WINDOW_DESTROYED (toplevel))
2556 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
2557 GDK_WINDOW_XID (toplevel),
2558 &old_windows, &count))
2563 for (i = 0; i < count; i++)
2564 if (old_windows[i] == GDK_WINDOW_XID (window))
2566 XFree (old_windows);
2570 new_windows = g_new (Window, count + 1);
2572 for (i = 0; i < count; i++)
2573 new_windows[i] = old_windows[i];
2574 new_windows[count] = GDK_WINDOW_XID (window);
2576 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
2577 GDK_WINDOW_XID (toplevel),
2578 new_windows, count + 1);
2580 g_free (new_windows);
2582 XFree (old_windows);
2586 gdk_window_have_shape_ext (void)
2588 enum { UNKNOWN, NO, YES };
2589 static gint have_shape = UNKNOWN;
2591 if (have_shape == UNKNOWN)
2594 if (XQueryExtension (gdk_display, "SHAPE", &ignore, &ignore, &ignore))
2600 return (have_shape == YES);
2603 #define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
2606 * This needs the X11 shape extension.
2607 * If not available, shaped windows will look
2608 * ugly, but programs still work. Stefan Wille
2611 * gdk_window_shape_combine_mask:
2612 * @window: a #GdkWindow
2614 * @x: X position of shape mask with respect to @window
2615 * @y: Y position of shape mask with respect to @window
2617 * Applies a shape mask to @window. Pixels in @window corresponding to
2618 * set bits in the @mask will be visible; pixels in @window
2619 * corresponding to unset bits in the @mask will be transparent. This
2620 * gives a non-rectangular window.
2622 * If @mask is %NULL, the shape mask will be unset, and the @x/@y
2623 * parameters are not used.
2625 * On the X11 platform, this uses an X server extension which is
2626 * widely available on most common platforms, but not available on
2627 * very old X servers, and occasionally the implementation will be
2628 * buggy. On servers without the shape extension, this function
2633 gdk_window_shape_combine_mask (GdkWindow *window,
2638 gint xoffset, yoffset;
2640 g_return_if_fail (window != NULL);
2641 g_return_if_fail (GDK_IS_WINDOW (window));
2643 #ifdef HAVE_SHAPE_EXT
2644 if (GDK_WINDOW_DESTROYED (window))
2647 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2649 if (xoffset != 0 || yoffset != 0)
2651 WARN_SHAPE_TOO_BIG ();
2655 if (gdk_window_have_shape_ext ())
2659 pixmap = GDK_PIXMAP_XID (mask);
2668 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
2669 GDK_WINDOW_XID (window),
2675 #endif /* HAVE_SHAPE_EXT */
2679 * gdk_window_shape_combine_region:
2680 * @window: a #GdkWindow
2681 * @shape_region: region of window to be non-transparent
2682 * @offset_x: X position of @shape_region in @window coordinates
2683 * @offset_y: Y position of @shape_region in @window coordinates
2685 * Makes pixels in @window outside @shape_region be transparent,
2686 * so that the window may be nonrectangular. See also
2687 * gdk_window_shape_combine_mask() to use a bitmap as the mask.
2689 * If @shape_region is %NULL, the shape will be unset, so the whole
2690 * window will be opaque again. @offset_x and @offset_y are ignored
2691 * if @shape_region is %NULL.
2693 * On the X11 platform, this uses an X server extension which is
2694 * widely available on most common platforms, but not available on
2695 * very old X servers, and occasionally the implementation will be
2696 * buggy. On servers without the shape extension, this function
2701 gdk_window_shape_combine_region (GdkWindow *window,
2702 GdkRegion *shape_region,
2706 gint xoffset, yoffset;
2708 g_return_if_fail (GDK_IS_WINDOW (window));
2710 #ifdef HAVE_SHAPE_EXT
2711 if (GDK_WINDOW_DESTROYED (window))
2714 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
2716 if (xoffset != 0 || yoffset != 0)
2718 WARN_SHAPE_TOO_BIG ();
2722 if (shape_region == NULL)
2724 /* Use NULL mask to unset the shape */
2725 gdk_window_shape_combine_mask (window, NULL, 0, 0);
2729 if (gdk_window_have_shape_ext ())
2732 XRectangle *xrects = NULL;
2734 _gdk_region_get_xrectangles (shape_region,
2738 XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
2739 GDK_WINDOW_XID (window),
2748 #endif /* HAVE_SHAPE_EXT */
2753 * gdk_window_set_override_redirect:
2754 * @window: a #GdkWindow
2755 * @override_redirect: %TRUE if window should be override redirect
2757 * An override redirect window is not under the control of the window manager.
2758 * This means it won't have a titlebar, won't be minimizable, etc. - it will
2759 * be entirely under the control of the application. The window manager
2760 * can't see the override redirect window at all.
2762 * Override redirect should only be used for short-lived temporary
2763 * windows, such as popup menus. #GtkMenu uses an override redirect
2764 * window in its implementation, for example.
2768 gdk_window_set_override_redirect (GdkWindow *window,
2769 gboolean override_redirect)
2771 XSetWindowAttributes attr;
2773 g_return_if_fail (window != NULL);
2774 g_return_if_fail (GDK_IS_WINDOW (window));
2776 if (!GDK_WINDOW_DESTROYED (window))
2778 attr.override_redirect = (override_redirect == FALSE)?False:True;
2779 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
2780 GDK_WINDOW_XID (window),
2788 * gdk_window_set_icon_list:
2789 * @window: The #GdkWindow toplevel window to set the icon of.
2790 * @pixbufs: A list of pixbufs, of different sizes.
2792 * Sets a list of icons for the window. One of these will be used
2793 * to represent the window when it has been iconified. The icon is
2794 * usually shown in an icon box or some sort of task bar. Which icon
2795 * size is shown depends on the window manager. The window manager
2796 * can scale the icon but setting several size icons can give better
2797 * image quality since the window manager may only need to scale the
2798 * icon by a small amount or not at all.
2802 gdk_window_set_icon_list (GdkWindow *window,
2811 gint width, height, stride;
2815 g_return_if_fail (GDK_IS_WINDOW (window));
2817 if (GDK_WINDOW_DESTROYED (window))
2826 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
2828 width = gdk_pixbuf_get_width (pixbuf);
2829 height = gdk_pixbuf_get_height (pixbuf);
2831 size += 2 + width * height;
2833 l = g_list_next (l);
2836 data = g_malloc (size * sizeof (gulong));
2844 width = gdk_pixbuf_get_width (pixbuf);
2845 height = gdk_pixbuf_get_height (pixbuf);
2846 stride = gdk_pixbuf_get_rowstride (pixbuf);
2847 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
2852 pixels = gdk_pixbuf_get_pixels (pixbuf);
2854 for (y = 0; y < height; y++)
2856 for (x = 0; x < width; x++)
2860 r = pixels[y*stride + x*n_channels + 0];
2861 g = pixels[y*stride + x*n_channels + 1];
2862 b = pixels[y*stride + x*n_channels + 2];
2863 if (n_channels >= 4)
2864 a = pixels[y*stride + x*n_channels + 3];
2868 *p++ = a << 24 | r << 16 | g << 8 | b ;
2872 l = g_list_next (l);
2877 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
2878 GDK_WINDOW_XID (window),
2879 gdk_x11_get_xatom_by_name ("_NET_WM_ICON"),
2882 (guchar*) data, size);
2886 XDeleteProperty (GDK_WINDOW_XDISPLAY (window),
2887 GDK_WINDOW_XID (window),
2888 gdk_x11_get_xatom_by_name ("_NET_WM_ICON"));
2895 * gdk_window_set_icon:
2896 * @window: a #GdkWindow
2897 * @icon_window: a #GdkWindow to use for the icon, or %NULL to unset
2898 * @pixmap: a #GdkPixmap to use as the icon, or %NULL to unset
2899 * @mask: a 1-bit pixmap (#GdkBitmap) to use as mask for @pixmap, or %NULL to have none
2901 * Sets the icon of @window as a pixmap or window. If using GTK+, investigate
2902 * gtk_window_set_default_icon_list() first, and then gtk_window_set_icon_list()
2903 * and gtk_window_set_icon(). If those don't meet your needs, look at
2904 * gdk_window_set_icon_list(). Only if all those are too high-level do you
2905 * want to fall back to gdk_window_set_icon().
2909 gdk_window_set_icon (GdkWindow *window,
2910 GdkWindow *icon_window,
2916 g_return_if_fail (window != NULL);
2917 g_return_if_fail (GDK_IS_WINDOW (window));
2919 if (GDK_WINDOW_DESTROYED (window))
2922 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
2923 GDK_WINDOW_XID (window));
2925 wm_hints = XAllocWMHints ();
2927 if (icon_window != NULL)
2929 wm_hints->flags |= IconWindowHint;
2930 wm_hints->icon_window = GDK_WINDOW_XID (icon_window);
2935 wm_hints->flags |= IconPixmapHint;
2936 wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap);
2941 wm_hints->flags |= IconMaskHint;
2942 wm_hints->icon_mask = GDK_PIXMAP_XID (mask);
2945 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
2946 GDK_WINDOW_XID (window), wm_hints);
2951 gdk_window_icon_name_set (GdkWindow *window)
2953 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
2954 g_quark_from_static_string ("gdk-icon-name-set")));
2958 * gdk_window_set_icon_name:
2959 * @window: a #GdkWindow
2960 * @name: name of window while iconified (minimized)
2962 * Windows may have a name used while minimized, distinct from the
2963 * name they display in their titlebar. Most of the time this is a bad
2964 * idea from a user interface standpoint. But you can set such a name
2965 * with this function, if you like.
2969 gdk_window_set_icon_name (GdkWindow *window,
2972 g_return_if_fail (window != NULL);
2973 g_return_if_fail (GDK_IS_WINDOW (window));
2975 if (GDK_WINDOW_DESTROYED (window))
2978 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
2979 GUINT_TO_POINTER (TRUE));
2981 XChangeProperty (GDK_WINDOW_XDISPLAY (window),
2982 GDK_WINDOW_XID (window),
2983 gdk_x11_get_xatom_by_name ("_NET_WM_ICON_NAME"),
2984 gdk_x11_get_xatom_by_name ("UTF8_STRING"), 8,
2985 PropModeReplace, name,
2987 set_text_property (window, gdk_x11_get_xatom_by_name ("WM_ICON_NAME"), name);
2991 * gdk_window_iconify:
2992 * @window: a #GdkWindow
2994 * Asks to iconify (minimize) @window. The window manager may choose
2995 * to ignore the request, but normally will honor it. Using
2996 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
3000 gdk_window_iconify (GdkWindow *window)
3003 GdkWindowObject *private;
3005 g_return_if_fail (window != NULL);
3006 g_return_if_fail (GDK_IS_WINDOW (window));
3008 if (GDK_WINDOW_DESTROYED (window))
3011 display = GDK_WINDOW_XDISPLAY (window);
3013 private = (GdkWindowObject*) window;
3015 if (GDK_WINDOW_IS_MAPPED (window))
3017 XIconifyWindow (display, GDK_WINDOW_XWINDOW (window), DefaultScreen (display));
3022 /* Flip our client side flag, the real work happens on map. */
3023 gdk_synthesize_window_state (window,
3025 GDK_WINDOW_STATE_ICONIFIED);
3030 * gdk_window_deiconify:
3031 * @window: a #GdkWindow
3033 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
3034 * choose to ignore the request to deiconify. When using GTK+,
3035 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
3036 * you probably want to use gtk_window_present(), which raises the window, focuses it,
3037 * unminimizes it, and puts it on the current desktop.
3041 gdk_window_deiconify (GdkWindow *window)
3044 GdkWindowObject *private;
3046 g_return_if_fail (window != NULL);
3047 g_return_if_fail (GDK_IS_WINDOW (window));
3049 if (GDK_WINDOW_DESTROYED (window))
3052 display = GDK_WINDOW_XDISPLAY (window);
3054 private = (GdkWindowObject*) window;
3056 if (GDK_WINDOW_IS_MAPPED (window))
3058 gdk_window_show (window);
3062 /* Flip our client side flag, the real work happens on map. */
3063 gdk_synthesize_window_state (window,
3064 GDK_WINDOW_STATE_ICONIFIED,
3071 * @window: a toplevel #GdkWindow
3073 * "Pins" a window such that it's on all workspaces and does not scroll
3074 * with viewports, for window managers that have scrollable viewports.
3075 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
3077 * On the X11 platform, this function depends on window manager
3078 * support, so may have no effect with many window managers. However,
3079 * GDK will do the best it can to convince the window manager to stick
3080 * the window. For window managers that don't support this operation,
3081 * there's nothing you can do to force it to happen.
3085 gdk_window_stick (GdkWindow *window)
3087 g_return_if_fail (GDK_IS_WINDOW (window));
3089 if (GDK_WINDOW_DESTROYED (window))
3092 if (GDK_WINDOW_IS_MAPPED (window))
3094 /* "stick" means stick to all desktops _and_ do not scroll with the
3095 * viewport. i.e. glue to the monitor glass in all cases.
3100 /* Request stick during viewport scroll */
3101 gdk_wmspec_change_state (TRUE, window,
3102 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
3105 /* Request desktop 0xFFFFFFFF */
3106 xev.xclient.type = ClientMessage;
3107 xev.xclient.serial = 0;
3108 xev.xclient.send_event = True;
3109 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
3110 xev.xclient.display = gdk_display;
3111 xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP");
3112 xev.xclient.format = 32;
3114 xev.xclient.data.l[0] = 0xFFFFFFFF;
3116 XSendEvent (gdk_display, _gdk_root_window, False,
3117 SubstructureRedirectMask | SubstructureNotifyMask,
3122 /* Flip our client side flag, the real work happens on map. */
3123 gdk_synthesize_window_state (window,
3125 GDK_WINDOW_STATE_STICKY);
3130 * gdk_window_unstick:
3131 * @window: a toplevel #GdkWindow
3133 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
3134 * and gtk_window_unstick().
3138 gdk_window_unstick (GdkWindow *window)
3140 g_return_if_fail (GDK_IS_WINDOW (window));
3142 if (GDK_WINDOW_DESTROYED (window))
3145 if (GDK_WINDOW_IS_MAPPED (window))
3152 gulong *current_desktop;
3154 /* Request unstick from viewport */
3155 gdk_wmspec_change_state (FALSE, window,
3156 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
3159 /* Get current desktop, then set it; this is a race, but not
3160 * one that matters much in practice.
3162 XGetWindowProperty (gdk_display, _gdk_root_window,
3163 gdk_x11_get_xatom_by_name ("_NET_CURRENT_DESKTOP"),
3165 False, XA_CARDINAL, &type, &format, &nitems,
3166 &bytes_after, (guchar **)¤t_desktop);
3168 if (type == XA_CARDINAL)
3170 xev.xclient.type = ClientMessage;
3171 xev.xclient.serial = 0;
3172 xev.xclient.send_event = True;
3173 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
3174 xev.xclient.display = gdk_display;
3175 xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_DESKTOP");
3176 xev.xclient.format = 32;
3178 xev.xclient.data.l[0] = *current_desktop;
3180 XSendEvent (gdk_display, _gdk_root_window, False,
3181 SubstructureRedirectMask | SubstructureNotifyMask,
3184 XFree (current_desktop);
3189 /* Flip our client side flag, the real work happens on map. */
3190 gdk_synthesize_window_state (window,
3191 GDK_WINDOW_STATE_STICKY,
3198 * gdk_window_maximize:
3199 * @window: a #GdkWindow
3201 * Asks the window manager to maximize @window, if the window manager supports
3202 * this operation. Not all window managers support this, and some deliberately
3203 * ignore it or don't have a concept of "maximized"; so you can't rely on the
3204 * maximization actually happening. But it will happen with most standard
3205 * window managers, and GDK makes a best effort to get it to happen.
3207 * If the window was already maximized, then this function does nothing.
3211 gdk_window_maximize (GdkWindow *window)
3213 g_return_if_fail (GDK_IS_WINDOW (window));
3215 if (GDK_WINDOW_DESTROYED (window))
3218 if (GDK_WINDOW_IS_MAPPED (window))
3219 gdk_wmspec_change_state (TRUE, window,
3220 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
3221 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
3223 gdk_synthesize_window_state (window,
3225 GDK_WINDOW_STATE_MAXIMIZED);
3229 * gdk_window_unmaximize:
3230 * @window: a #GdkWindow
3232 * Asks the window manager to unmaximize @window, if the window manager supports
3233 * this operation. Not all window managers support this, and some deliberately
3234 * ignore it or don't have a concept of "maximized"; so you can't rely on the
3235 * unmaximization actually happening. But it will happen with most standard
3236 * window managers, and GDK makes a best effort to get it to happen.
3238 * If the window wasn't maximized, then this function does nothing.
3242 gdk_window_unmaximize (GdkWindow *window)
3244 g_return_if_fail (GDK_IS_WINDOW (window));
3246 if (GDK_WINDOW_DESTROYED (window))
3249 if (GDK_WINDOW_IS_MAPPED (window))
3250 gdk_wmspec_change_state (FALSE, window,
3251 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
3252 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
3254 gdk_synthesize_window_state (window,
3255 GDK_WINDOW_STATE_MAXIMIZED,
3260 * gdk_window_set_group:
3261 * @window: a #GdkWindow
3262 * @leader: group leader window
3264 * Sets the group leader window for @window. By default,
3265 * GDK sets the group leader for all toplevel windows
3266 * to a global window implicitly created by GDK. With this function
3267 * you can override this default.
3269 * The group leader window allows the window manager to distinguish
3270 * all windows that belong to a single application. It may for example
3271 * allow users to minimize/unminimize all windows belonging to an
3272 * application at once. You should only set a non-default group window
3273 * if your application pretends to be multiple applications.
3274 * The group leader window may not be changed after a window has been
3275 * mapped (with gdk_window_show() for example).
3279 gdk_window_set_group (GdkWindow *window,
3284 g_return_if_fail (window != NULL);
3285 g_return_if_fail (GDK_IS_WINDOW (window));
3286 g_return_if_fail (leader != NULL);
3287 g_return_if_fail (GDK_IS_WINDOW (leader));
3289 if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader))
3292 wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window),
3293 GDK_WINDOW_XID (window));
3295 wm_hints = XAllocWMHints ();
3297 wm_hints->flags |= WindowGroupHint;
3298 wm_hints->window_group = GDK_WINDOW_XID (leader);
3300 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
3301 GDK_WINDOW_XID (window), wm_hints);
3305 static MotifWmHints *
3306 gdk_window_get_mwm_hints (GdkWindow *window)
3308 static Atom hints_atom = None;
3309 MotifWmHints *hints;
3315 if (GDK_WINDOW_DESTROYED (window))
3319 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
3320 _XA_MOTIF_WM_HINTS, FALSE);
3322 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
3323 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
3324 False, AnyPropertyType, &type, &format, &nitems,
3325 &bytes_after, (guchar **)&hints);
3334 gdk_window_set_mwm_hints (GdkWindow *window,
3335 MotifWmHints *new_hints)
3337 static Atom hints_atom = None;
3338 MotifWmHints *hints;
3344 if (GDK_WINDOW_DESTROYED (window))
3348 hints_atom = XInternAtom (GDK_WINDOW_XDISPLAY (window),
3349 _XA_MOTIF_WM_HINTS, FALSE);
3351 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
3352 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
3353 False, AnyPropertyType, &type, &format, &nitems,
3354 &bytes_after, (guchar **)&hints);
3360 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
3362 hints->flags |= MWM_HINTS_FUNCTIONS;
3363 hints->functions = new_hints->functions;
3365 if (new_hints->flags & MWM_HINTS_DECORATIONS)
3367 hints->flags |= MWM_HINTS_DECORATIONS;
3368 hints->decorations = new_hints->decorations;
3372 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
3373 hints_atom, hints_atom, 32, PropModeReplace,
3374 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
3376 if (hints != new_hints)
3381 * gdk_window_set_decorations:
3382 * @window: a #GdkWindow
3383 * @decorations: decoration hint mask
3385 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
3386 * This function sets the traditional Motif window manager hints that tell the
3387 * window manager which decorations you would like your window to have.
3388 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
3389 * using the GDK function directly.
3391 * The @decorations argument is the logical OR of the fields in
3392 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
3393 * mask, the other bits indicate which decorations should be turned off.
3394 * If #GDK_DECOR_ALL is not included, then the other bits indicate
3395 * which decorations should be turned on.
3397 * Most window managers honor a decorations hint of 0 to disable all decorations,
3398 * but very few honor all possible combinations of bits.
3402 gdk_window_set_decorations (GdkWindow *window,
3403 GdkWMDecoration decorations)
3407 g_return_if_fail (window != NULL);
3408 g_return_if_fail (GDK_IS_WINDOW (window));
3410 hints.flags = MWM_HINTS_DECORATIONS;
3411 hints.decorations = decorations;
3413 gdk_window_set_mwm_hints (window, &hints);
3417 * gdk_window_get_decorations:
3418 * @window: The #GdkWindow to get the decorations from
3419 * @decorations: The window decorations will be written here
3421 * Returns the decorations set on the GdkWindow with #gdk_window_set_decorations
3422 * Returns: TRUE if the window has decorations set, FALSE otherwise.
3425 gdk_window_get_decorations(GdkWindow *window,
3426 GdkWMDecoration *decorations)
3428 MotifWmHints *hints;
3429 gboolean result = FALSE;
3431 hints = gdk_window_get_mwm_hints (window);
3435 if (hints->flags & MWM_HINTS_DECORATIONS)
3437 *decorations = hints->decorations;
3448 * gdk_window_set_functions:
3449 * @window: a #GdkWindow
3450 * @functions: bitmask of operations to allow on @window
3452 * This function isn't really good for much. It sets the traditional
3453 * Motif window manager hint for which operations the window manager
3454 * should allow on a toplevel window. However, few window managers do
3455 * anything reliable or interesting with this hint. Many ignore it
3458 * The @functions argument is the logical OR of values from the
3459 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
3460 * then the other bits indicate which functions to disable; if
3461 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
3466 gdk_window_set_functions (GdkWindow *window,
3467 GdkWMFunction functions)
3471 g_return_if_fail (window != NULL);
3472 g_return_if_fail (GDK_IS_WINDOW (window));
3474 hints.flags = MWM_HINTS_FUNCTIONS;
3475 hints.functions = functions;
3477 gdk_window_set_mwm_hints (window, &hints);
3480 #ifdef HAVE_SHAPE_EXT
3483 * propagate the shapes from all child windows of a GDK window to the parent
3484 * window. Shamelessly ripped from Enlightenment's code
3492 struct _gdk_span *next;
3496 gdk_add_to_span (struct _gdk_span **s,
3500 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
3507 /* scan the spans for this line */
3510 /* -- -> new span */
3511 /* == -> existing span */
3512 /* ## -> spans intersect */
3513 /* if we are in the middle of spanning the span into the line */
3516 /* case: ---- ==== */
3517 if (xx < ptr1->start - 1)
3519 /* ends before next span - extend to here */
3523 /* case: ----##=== */
3524 else if (xx <= ptr1->end)
3526 /* crosses into next span - delete next span and append */
3527 ss->end = ptr1->end;
3528 ss->next = ptr1->next;
3532 /* case: ---###--- */
3535 /* overlaps next span - delete and keep checking */
3536 ss->next = ptr1->next;
3541 /* otherwise havent started spanning it in yet */
3544 /* case: ---- ==== */
3545 if (xx < ptr1->start - 1)
3547 /* insert span here in list */
3548 noo = g_malloc (sizeof (struct _gdk_span));
3562 /* case: ----##=== */
3563 else if ((x < ptr1->start) && (xx <= ptr1->end))
3565 /* expand this span to the left point of the new one */
3569 /* case: ===###=== */
3570 else if ((x >= ptr1->start) && (xx <= ptr1->end))
3572 /* throw the span away */
3575 /* case: ---###--- */
3576 else if ((x < ptr1->start) && (xx > ptr1->end))
3583 /* case: ===##---- */
3584 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
3590 /* case: ==== ---- */
3591 /* case handled by next loop iteration - first case */
3596 /* it started in the middle but spans beyond your current list */
3602 /* it does not start inside a span or in the middle, so add it to the end */
3603 noo = g_malloc (sizeof (struct _gdk_span));
3611 noo->next = ptr2->next;
3624 gdk_add_rectangles (Display *disp,
3626 struct _gdk_span **spans,
3633 gint x1, y1, x2, y2;
3637 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
3640 /* go through all clip rects in this window's shape */
3641 for (k = 0; k < rn; k++)
3643 /* for each clip rect, add it to each line's spans */
3645 x2 = x + rl[k].x + (rl[k].width - 1);
3647 y2 = y + rl[k].y + (rl[k].height - 1);
3656 for (a = y1; a <= y2; a++)
3659 gdk_add_to_span (&spans[a], x1, x2);
3667 gdk_propagate_shapes (Display *disp,
3671 Window rt, par, *list = NULL;
3672 gint i, j, num = 0, num_rects = 0;
3676 XRectangle *rects = NULL;
3677 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
3678 XWindowAttributes xatt;
3680 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
3685 spans = g_malloc (sizeof (struct _gdk_span *) * h);
3687 for (i = 0; i < h; i++)
3689 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
3692 /* go through all child windows and create/insert spans */
3693 for (i = 0; i < num; i++)
3695 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
3696 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
3697 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
3700 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
3702 /* go through the spans list and build a list of rects */
3703 rects = g_malloc (sizeof (XRectangle) * 256);
3705 for (i = 0; i < baseh; i++)
3708 /* go through the line for all spans */
3711 rects[num_rects].x = ptr1->start;
3712 rects[num_rects].y = i;
3713 rects[num_rects].width = ptr1->end - ptr1->start + 1;
3714 rects[num_rects].height = 1;
3716 /* if there are more lines */
3718 /* while contigous rects (same start/end coords) exist */
3719 while ((contig) && (j < baseh))
3721 /* search next line for spans matching this one */
3727 /* if we have an exact span match set contig */
3728 if ((ptr2->start == ptr1->start) &&
3729 (ptr2->end == ptr1->end))
3732 /* remove the span - not needed */
3735 ptr3->next = ptr2->next;
3741 spans[j] = ptr2->next;
3747 /* gone past the span point no point looking */
3748 else if (ptr2->start < ptr1->start)
3756 /* if a contiguous span was found increase the rect h */
3759 rects[num_rects].height++;
3763 /* up the rect count */
3765 /* every 256 new rects increase the rect array */
3766 if ((num_rects % 256) == 0)
3767 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
3771 /* set the rects as the shape mask */
3774 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
3775 ShapeSet, YXSorted);
3780 /* free up all the spans we made */
3781 for (i = 0; i < baseh; i++)
3794 #endif /* HAVE_SHAPE_EXT */
3797 * gdk_window_set_child_shapes:
3798 * @window: a #GdkWindow
3800 * Sets the shape mask of @window to the union of shape masks
3801 * for all children of @window, ignoring the shape mask of @window
3802 * itself. Contrast with gdk_window_merge_child_shapes() which includes
3803 * the shape mask of @window in the masks to be merged.
3806 gdk_window_set_child_shapes (GdkWindow *window)
3808 g_return_if_fail (window != NULL);
3809 g_return_if_fail (GDK_IS_WINDOW (window));
3811 #ifdef HAVE_SHAPE_EXT
3812 if (!GDK_WINDOW_DESTROYED (window) &&
3813 gdk_window_have_shape_ext ())
3814 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
3815 GDK_WINDOW_XID (window), FALSE);
3820 * gdk_window_merge_child_shapes:
3821 * @window: a #GdkWindow
3823 * Merges the shape masks for any child windows into the
3824 * shape mask for @window. i.e. the union of all masks
3825 * for @window and its children will become the new mask
3826 * for @window. See gdk_window_shape_combine_mask().
3828 * This function is distinct from gdk_window_set_child_shapes()
3829 * because it includes @window's shape mask in the set of shapes to
3834 gdk_window_merge_child_shapes (GdkWindow *window)
3836 g_return_if_fail (window != NULL);
3837 g_return_if_fail (GDK_IS_WINDOW (window));
3839 #ifdef HAVE_SHAPE_EXT
3840 if (!GDK_WINDOW_DESTROYED (window) &&
3841 gdk_window_have_shape_ext ())
3842 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
3843 GDK_WINDOW_XID (window), TRUE);
3847 /* Support for windows that can be guffaw-scrolled
3848 * (See http://www.gtk.org/~otaylor/whitepapers/guffaw-scrolling.txt)
3852 gdk_window_gravity_works (void)
3854 enum { UNKNOWN, NO, YES };
3855 static gint gravity_works = UNKNOWN;
3857 if (gravity_works == UNKNOWN)
3864 /* This particular server apparently has a bug so that the test
3865 * works but the actual code crashes it
3867 if ((!strcmp (XServerVendor (gdk_display), "Sun Microsystems, Inc.")) &&
3868 (VendorRelease (gdk_display) == 3400))
3874 attr.window_type = GDK_WINDOW_TEMP;
3875 attr.wclass = GDK_INPUT_OUTPUT;
3880 attr.event_mask = 0;
3882 parent = gdk_window_new (NULL, &attr, GDK_WA_X | GDK_WA_Y);
3884 attr.window_type = GDK_WINDOW_CHILD;
3885 child = gdk_window_new (parent, &attr, GDK_WA_X | GDK_WA_Y);
3887 gdk_window_set_static_win_gravity (child, TRUE);
3889 gdk_window_resize (parent, 100, 110);
3890 gdk_window_move (parent, 0, -10);
3891 gdk_window_move_resize (parent, 0, 0, 100, 100);
3893 gdk_window_resize (parent, 100, 110);
3894 gdk_window_move (parent, 0, -10);
3895 gdk_window_move_resize (parent, 0, 0, 100, 100);
3897 gdk_window_get_geometry (child, NULL, &y, NULL, NULL, NULL);
3899 gdk_window_destroy (parent);
3900 gdk_window_destroy (child);
3902 gravity_works = ((y == -20) ? YES : NO);
3905 return (gravity_works == YES);
3909 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
3911 XSetWindowAttributes xattributes;
3912 GdkWindowObject *private;
3913 guint xattributes_mask = 0;
3915 g_return_if_fail (window != NULL);
3917 private = GDK_WINDOW_OBJECT (window);
3918 if (private->input_only)
3921 xattributes.bit_gravity = StaticGravity;
3922 xattributes_mask |= CWBitGravity;
3923 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
3924 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3925 GDK_WINDOW_XID (window),
3926 CWBitGravity, &xattributes);
3930 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
3932 XSetWindowAttributes xattributes;
3934 g_return_if_fail (window != NULL);
3936 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
3938 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3939 GDK_WINDOW_XID (window),
3940 CWWinGravity, &xattributes);
3944 * gdk_window_set_static_gravities:
3945 * @window: a #GdkWindow
3946 * @use_static: %TRUE to turn on static gravity
3948 * Set the bit gravity of the given window to static, and flag it so
3949 * all children get static subwindow gravity. This is used if you are
3950 * implementing scary features that involve deep knowledge of the
3951 * windowing system. Don't worry about it unless you have to.
3953 * Return value: %TRUE if the server supports static gravity
3956 gdk_window_set_static_gravities (GdkWindow *window,
3957 gboolean use_static)
3959 GdkWindowObject *private = (GdkWindowObject *)window;
3962 g_return_val_if_fail (window != NULL, FALSE);
3963 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
3965 if (!use_static == !private->guffaw_gravity)
3968 if (use_static && !gdk_window_gravity_works ())
3971 private->guffaw_gravity = use_static;
3973 if (!GDK_WINDOW_DESTROYED (window))
3975 gdk_window_set_static_bit_gravity (window, use_static);
3977 tmp_list = private->children;
3980 gdk_window_set_static_win_gravity (tmp_list->data, use_static);
3982 tmp_list = tmp_list->next;
3989 /* internal function created for and used by gdk_window_xid_at_coords */
3991 gdk_window_xid_at (Window base,
3997 gboolean excl_child)
4000 Window *list = NULL;
4001 Window child = 0, parent_win = 0, root_win = 0;
4003 unsigned int ww, wh, wb, wd, num;
4006 xdisplay = GDK_DISPLAY ();
4007 if (!XGetGeometry (xdisplay, base, &root_win, &wx, &wy, &ww, &wh, &wb, &wd))
4014 (x < (int) (wx + ww)) &&
4015 (y < (int) (wy + wh))))
4018 if (!XQueryTree (xdisplay, base, &root_win, &parent_win, &list, &num))
4023 for (i = num - 1; ; i--)
4025 if ((!excl_child) || (!g_list_find (excludes, (gpointer *) list[i])))
4027 if ((child = gdk_window_xid_at (list[i], wx, wy, x, y, excludes, excl_child)) != 0)
4042 * The following fucntion by The Rasterman <raster@redhat.com>
4043 * This function returns the X Window ID in which the x y location is in
4044 * (x and y being relative to the root window), excluding any windows listed
4045 * in the GList excludes (this is a list of X Window ID's - gpointer being
4048 * This is primarily designed for internal gdk use - for DND for example
4049 * when using a shaped icon window as the drag object - you exclude the
4050 * X Window ID of the "icon" (perhaps more if excludes may be needed) and
4051 * You can get back an X Window ID as to what X Window ID is infact under
4052 * those X,Y co-ordinates.
4055 gdk_window_xid_at_coords (gint x,
4058 gboolean excl_child)
4062 Window *list = NULL;
4063 Window root, child = 0, parent_win = 0, root_win = 0;
4067 window = _gdk_parent_root;
4068 xdisplay = GDK_WINDOW_XDISPLAY (window);
4069 root = GDK_WINDOW_XID (window);
4070 num = g_list_length (excludes);
4072 gdk_x11_grab_server ();
4073 if (!XQueryTree (xdisplay, root, &root_win, &parent_win, &list, &num))
4075 gdk_x11_ungrab_server ();
4083 XWindowAttributes xwa;
4085 XGetWindowAttributes (xdisplay, list [i], &xwa);
4087 if (xwa.map_state != IsViewable)
4090 if (excl_child && g_list_find (excludes, (gpointer *) list[i]))
4093 if ((child = gdk_window_xid_at (list[i], 0, 0, x, y, excludes, excl_child)) == 0)
4098 if (!g_list_find (excludes, (gpointer *) child))
4101 gdk_x11_ungrab_server ();
4108 gdk_x11_ungrab_server ();
4114 gdk_x11_ungrab_server ();
4119 wmspec_moveresize (GdkWindow *window,
4127 /* Release passive grab */
4128 gdk_pointer_ungrab (timestamp);
4130 xev.xclient.type = ClientMessage;
4131 xev.xclient.serial = 0;
4132 xev.xclient.send_event = True;
4133 xev.xclient.display = gdk_display;
4134 xev.xclient.window = GDK_WINDOW_XID (window);
4135 xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_MOVERESIZE");
4136 xev.xclient.format = 32;
4137 xev.xclient.data.l[0] = root_x;
4138 xev.xclient.data.l[1] = root_y;
4139 xev.xclient.data.l[2] = direction;
4140 xev.xclient.data.l[3] = 0;
4141 xev.xclient.data.l[4] = 0;
4143 XSendEvent (gdk_display, _gdk_root_window, False,
4144 SubstructureRedirectMask | SubstructureNotifyMask,
4148 /* From the WM spec */
4149 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
4150 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
4151 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
4152 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
4153 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
4154 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
4155 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
4156 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
4157 #define _NET_WM_MOVERESIZE_MOVE 8
4160 wmspec_resize_drag (GdkWindow *window,
4169 /* Let the compiler turn a switch into a table, instead
4170 * of doing the table manually, this way is easier to verify.
4174 case GDK_WINDOW_EDGE_NORTH_WEST:
4175 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
4178 case GDK_WINDOW_EDGE_NORTH:
4179 direction = _NET_WM_MOVERESIZE_SIZE_TOP;
4182 case GDK_WINDOW_EDGE_NORTH_EAST:
4183 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
4186 case GDK_WINDOW_EDGE_WEST:
4187 direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
4190 case GDK_WINDOW_EDGE_EAST:
4191 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
4194 case GDK_WINDOW_EDGE_SOUTH_WEST:
4195 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
4198 case GDK_WINDOW_EDGE_SOUTH:
4199 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
4202 case GDK_WINDOW_EDGE_SOUTH_EAST:
4203 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
4207 g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
4213 wmspec_moveresize (window, direction, root_x, root_y, timestamp);
4216 /* This is global for use in gdkevents-x11.c */
4217 GdkWindow *_gdk_moveresize_window;
4219 static GdkWindow *moveresize_emulation_window = NULL;
4220 static gboolean is_resize = FALSE;
4221 static GdkWindowEdge resize_edge;
4222 static gint moveresize_button;
4223 static gint moveresize_x;
4224 static gint moveresize_y;
4225 static gint moveresize_orig_x;
4226 static gint moveresize_orig_y;
4227 static gint moveresize_orig_width;
4228 static gint moveresize_orig_height;
4229 static GdkWindowHints moveresize_geom_mask = 0;
4230 static GdkGeometry moveresize_geometry;
4231 static Time moveresize_process_time;
4233 static XEvent *moveresize_pending_event;
4236 update_pos (gint new_root_x,
4241 dx = new_root_x - moveresize_x;
4242 dy = new_root_y - moveresize_y;
4248 w = moveresize_orig_width;
4249 h = moveresize_orig_height;
4251 switch (resize_edge)
4253 case GDK_WINDOW_EDGE_SOUTH_EAST:
4262 if (moveresize_geom_mask)
4264 gdk_window_constrain_size (&moveresize_geometry,
4265 moveresize_geom_mask,
4270 gdk_window_resize (_gdk_moveresize_window, w, h);
4276 x = moveresize_orig_x + dx;
4277 y = moveresize_orig_y + dy;
4279 gdk_window_move (_gdk_moveresize_window, x, y);
4286 gdk_window_destroy (moveresize_emulation_window);
4287 moveresize_emulation_window = NULL;
4288 _gdk_moveresize_window = NULL;
4290 if (moveresize_pending_event)
4292 g_free (moveresize_pending_event);
4293 moveresize_pending_event = NULL;
4298 lookahead_motion_predicate (Display *display,
4302 gboolean *seen_release = (gboolean *)arg;
4307 switch (event->xany.type)
4310 *seen_release = TRUE;
4313 moveresize_process_time = event->xmotion.time;
4323 moveresize_lookahead (XEvent *event)
4326 gboolean seen_release = FALSE;
4328 if (moveresize_process_time)
4330 if (event->xmotion.time == moveresize_process_time)
4332 moveresize_process_time = 0;
4339 XCheckIfEvent (gdk_display, &tmp_event,
4340 lookahead_motion_predicate, (XPointer)&seen_release);
4342 return moveresize_process_time == 0;
4346 _gdk_moveresize_handle_event (XEvent *event)
4348 guint button_mask = 0;
4349 GdkWindowObject *window_private = (GdkWindowObject *) _gdk_moveresize_window;
4351 button_mask = GDK_BUTTON1_MASK << (moveresize_button - 1);
4353 switch (event->xany.type)
4356 if (window_private->resize_count > 0)
4358 if (moveresize_pending_event)
4359 *moveresize_pending_event = *event;
4361 moveresize_pending_event = g_memdup (event, sizeof (XEvent));
4365 if (!moveresize_lookahead (event))
4368 update_pos (event->xmotion.x_root,
4369 event->xmotion.y_root);
4371 /* This should never be triggered in normal cases, but in the
4372 * case where the drag started without an implicit grab being
4373 * in effect, we could miss the release if it occurs before
4374 * we grab the pointer; this ensures that we will never
4375 * get a permanently stuck grab.
4377 if ((event->xmotion.state & button_mask) == 0)
4382 update_pos (event->xbutton.x_root,
4383 event->xbutton.y_root);
4385 if (event->xbutton.button == moveresize_button)
4392 _gdk_moveresize_configure_done (void)
4396 if (moveresize_pending_event)
4398 tmp_event = moveresize_pending_event;
4399 moveresize_pending_event = NULL;
4400 _gdk_moveresize_handle_event (tmp_event);
4406 create_moveresize_window (guint32 timestamp)
4408 GdkWindowAttr attributes;
4409 gint attributes_mask;
4410 GdkGrabStatus status;
4412 g_assert (moveresize_emulation_window == NULL);
4414 attributes.x = -100;
4415 attributes.y = -100;
4416 attributes.width = 10;
4417 attributes.height = 10;
4418 attributes.window_type = GDK_WINDOW_TEMP;
4419 attributes.wclass = GDK_INPUT_ONLY;
4420 attributes.override_redirect = TRUE;
4421 attributes.event_mask = 0;
4423 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
4425 moveresize_emulation_window =
4426 gdk_window_new (NULL, &attributes, attributes_mask);
4428 gdk_window_show (moveresize_emulation_window);
4430 status = gdk_pointer_grab (moveresize_emulation_window,
4432 GDK_BUTTON_RELEASE_MASK |
4433 GDK_POINTER_MOTION_MASK,
4438 if (status != GDK_GRAB_SUCCESS)
4440 /* If this fails, some other client has grabbed the window
4443 gdk_window_destroy (moveresize_emulation_window);
4444 moveresize_emulation_window = NULL;
4447 moveresize_process_time = 0;
4451 emulate_resize_drag (GdkWindow *window,
4459 moveresize_button = button;
4461 moveresize_x = root_x;
4462 moveresize_y = root_y;
4463 _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
4465 gdk_window_get_size (window, &moveresize_orig_width, &moveresize_orig_height);
4467 moveresize_geom_mask = 0;
4468 gdk_window_get_geometry_hints (window,
4469 &moveresize_geometry,
4470 &moveresize_geom_mask);
4472 create_moveresize_window (timestamp);
4476 emulate_move_drag (GdkWindow *window,
4483 moveresize_button = button;
4484 moveresize_x = root_x;
4485 moveresize_y = root_y;
4486 _gdk_moveresize_window = GDK_WINDOW (g_object_ref (G_OBJECT (window)));
4488 gdk_window_get_deskrelative_origin (_gdk_moveresize_window,
4490 &moveresize_orig_y);
4492 create_moveresize_window (timestamp);
4496 * gdk_window_begin_resize_drag:
4497 * @window: a #GdkWindow
4498 * @edge: the edge or corner from which the drag is started
4499 * @button: the button being used to drag
4500 * @root_x: root window X coordinate of mouse click that began the drag
4501 * @root_y: root window Y coordinate of mouse click that began the drag
4502 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
4504 * Begins a window resize operation (for a toplevel window).
4505 * You might use this function to implement a "window resize grip," for
4506 * example; in fact #GtkStatusbar uses it. The function works best
4507 * with window managers that support the Extended Window Manager Hints spec
4508 * (see http://www.freedesktop.org), but has a fallback implementation
4509 * for other window managers.
4513 gdk_window_begin_resize_drag (GdkWindow *window,
4520 g_return_if_fail (GDK_IS_WINDOW (window));
4521 g_return_if_fail (moveresize_emulation_window == NULL);
4523 if (GDK_WINDOW_DESTROYED (window))
4526 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
4527 wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
4529 emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
4533 * gdk_window_begin_move_drag:
4534 * @window: a #GdkWindow
4535 * @button: the button being used to drag
4536 * @root_x: root window X coordinate of mouse click that began the drag
4537 * @root_y: root window Y coordinate of mouse click that began the drag
4538 * @timestamp: timestamp of mouse click that began the drag
4540 * Begins a window move operation (for a toplevel window). You might
4541 * use this function to implement a "window move grip," for
4542 * example. The function works best with window managers that support
4543 * the Extended Window Manager Hints spec (see
4544 * http://www.freedesktop.org), but has a fallback implementation for
4545 * other window managers.
4549 gdk_window_begin_move_drag (GdkWindow *window,
4555 g_return_if_fail (GDK_IS_WINDOW (window));
4556 g_return_if_fail (moveresize_emulation_window == NULL);
4558 if (GDK_WINDOW_DESTROYED (window))
4561 if (gdk_net_wm_supports (gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
4562 wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE,
4563 root_x, root_y, timestamp);
4565 emulate_move_drag (window, button, root_x, root_y, timestamp);