1 /* GDK - The GIMP Drawing Kit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include <X11/Xutil.h>
31 #include <X11/Xatom.h>
32 #include <netinet/in.h>
38 #include "gdkwindow.h"
40 #include "gdkinputprivate.h"
41 #include "gdkdisplay-x11.h"
42 #include "gdkprivate-x11.h"
43 #include "gdkregion.h"
44 #include "gdkinternals.h"
46 #include "gdkwindow-x11.h"
54 #include <X11/extensions/shape.h>
57 const int _gdk_event_mask_table[21] =
61 PointerMotionHintMask,
78 SubstructureNotifyMask,
79 ButtonPressMask /* SCROLL; on X mouse wheel events is treated as mouse button 4/5 */
81 const int _gdk_nenvent_masks = sizeof (_gdk_event_mask_table) / sizeof (int);
83 /* Forward declarations */
84 static void gdk_window_set_static_win_gravity (GdkWindow *window,
86 static gboolean gdk_window_have_shape_ext (GdkDisplay *display);
87 static gboolean gdk_window_icon_name_set (GdkWindow *window);
88 static void gdk_window_add_colormap_windows (GdkWindow *window);
89 static void set_wm_name (GdkDisplay *display,
93 static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
94 static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
96 static void gdk_window_impl_x11_get_size (GdkDrawable *drawable,
99 static GdkRegion* gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable);
100 static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
101 static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
102 static void gdk_window_impl_x11_finalize (GObject *object);
104 static gpointer parent_class = NULL;
106 #define WINDOW_IS_TOPLEVEL(window) \
107 (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
108 GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
110 /* Return whether time1 is considered later than time2 as far as xserver
111 * time is concerned. Accounts for wraparound.
113 #define XSERVER_TIME_IS_LATER(time1, time2) \
114 ( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
115 (( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
119 gdk_window_impl_x11_get_type (void)
121 static GType object_type = 0;
125 static const GTypeInfo object_info =
127 sizeof (GdkWindowImplX11Class),
128 (GBaseInitFunc) NULL,
129 (GBaseFinalizeFunc) NULL,
130 (GClassInitFunc) gdk_window_impl_x11_class_init,
131 NULL, /* class_finalize */
132 NULL, /* class_data */
133 sizeof (GdkWindowImplX11),
135 (GInstanceInitFunc) gdk_window_impl_x11_init,
138 object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
147 _gdk_window_impl_get_type (void)
149 return gdk_window_impl_x11_get_type ();
153 gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
157 impl->toplevel_window_type = -1;
161 _gdk_x11_window_get_toplevel (GdkWindow *window)
163 GdkWindowObject *private;
164 GdkWindowImplX11 *impl;
166 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
168 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
171 private = (GdkWindowObject *)window;
172 impl = GDK_WINDOW_IMPL_X11 (private->impl);
175 impl->toplevel = g_new0 (GdkToplevelX11, 1);
177 return impl->toplevel;
181 gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
183 GObjectClass *object_class = G_OBJECT_CLASS (klass);
184 GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
186 parent_class = g_type_class_peek_parent (klass);
188 object_class->finalize = gdk_window_impl_x11_finalize;
190 drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
191 drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
192 drawable_class->get_size = gdk_window_impl_x11_get_size;
194 /* Visible and clip regions are the same */
195 drawable_class->get_clip_region = gdk_window_impl_x11_get_visible_region;
196 drawable_class->get_visible_region = gdk_window_impl_x11_get_visible_region;
200 gdk_window_impl_x11_finalize (GObject *object)
202 GdkWindowObject *wrapper;
203 GdkDrawableImplX11 *draw_impl;
204 GdkWindowImplX11 *window_impl;
206 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
208 draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
209 window_impl = GDK_WINDOW_IMPL_X11 (object);
211 wrapper = (GdkWindowObject*) draw_impl->wrapper;
213 _gdk_xgrab_check_destroy (GDK_WINDOW (wrapper));
215 if (!GDK_WINDOW_DESTROYED (wrapper))
217 GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
219 _gdk_xid_table_remove (display, draw_impl->xid);
220 if (window_impl->toplevel && window_impl->toplevel->focus_window)
221 _gdk_xid_table_remove (display, window_impl->toplevel->focus_window);
224 if (window_impl->toplevel)
225 g_free (window_impl->toplevel);
227 G_OBJECT_CLASS (parent_class)->finalize (object);
231 tmp_unset_bg (GdkWindow *window)
233 GdkWindowImplX11 *impl;
234 GdkWindowObject *obj;
236 obj = (GdkWindowObject *) window;
237 impl = GDK_WINDOW_IMPL_X11 (obj->impl);
239 impl->position_info.no_bg = TRUE;
241 if (obj->bg_pixmap != GDK_NO_BG)
242 XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
243 GDK_DRAWABLE_XID (window), None);
247 tmp_reset_bg (GdkWindow *window)
249 GdkWindowImplX11 *impl;
250 GdkWindowObject *obj;
252 obj = (GdkWindowObject *) window;
253 impl = GDK_WINDOW_IMPL_X11 (obj->impl);
255 impl->position_info.no_bg = FALSE;
257 if (obj->bg_pixmap == GDK_NO_BG)
264 if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
265 xpixmap = ParentRelative;
267 xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
269 XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
270 GDK_DRAWABLE_XID (window), xpixmap);
274 XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
275 GDK_DRAWABLE_XID (window),
276 obj->bg_color.pixel);
281 _gdk_x11_window_tmp_unset_bg (GdkWindow *window,
284 GdkWindowObject *private;
286 g_return_if_fail (GDK_IS_WINDOW (window));
288 private = (GdkWindowObject *)window;
290 if (private->input_only || private->destroyed ||
291 (private->window_type != GDK_WINDOW_ROOT &&
292 !GDK_WINDOW_IS_MAPPED (window)))
297 if (private->window_type != GDK_WINDOW_ROOT &&
298 private->window_type != GDK_WINDOW_FOREIGN)
300 tmp_unset_bg (window);
307 for (l = private->children; l != NULL; l = l->next)
308 _gdk_x11_window_tmp_unset_bg (l->data, TRUE);
313 _gdk_x11_window_tmp_reset_bg (GdkWindow *window,
316 GdkWindowObject *private;
318 g_return_if_fail (GDK_IS_WINDOW (window));
320 private = (GdkWindowObject *)window;
322 if (private->input_only || private->destroyed ||
323 (private->window_type != GDK_WINDOW_ROOT &&
324 !GDK_WINDOW_IS_MAPPED (window)))
329 if (private->window_type != GDK_WINDOW_ROOT &&
330 private->window_type != GDK_WINDOW_FOREIGN)
332 tmp_reset_bg (window);
339 for (l = private->children; l != NULL; l = l->next)
340 _gdk_x11_window_tmp_reset_bg (l->data, TRUE);
345 gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
347 GdkDrawableImplX11 *drawable_impl;
348 GdkWindowImplX11 *window_impl;
350 g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
352 drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
353 window_impl = GDK_WINDOW_IMPL_X11 (drawable);
355 if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
356 drawable_impl->colormap == NULL)
358 XWindowAttributes window_attributes;
361 XGetWindowAttributes (GDK_SCREEN_XDISPLAY (drawable_impl->screen),
365 visual = gdk_x11_screen_lookup_visual (drawable_impl->screen,
366 window_attributes.visual->visualid);
367 drawable_impl->colormap = gdk_x11_colormap_foreign_new (visual,
368 window_attributes.colormap);
371 return drawable_impl->colormap;
375 gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
378 GdkWindowImplX11 *impl;
379 GdkDrawableImplX11 *draw_impl;
381 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
383 impl = GDK_WINDOW_IMPL_X11 (drawable);
384 draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
386 if (cmap && GDK_WINDOW_DESTROYED (draw_impl->wrapper))
390 GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
394 XSetWindowColormap (GDK_SCREEN_XDISPLAY (draw_impl->screen),
396 GDK_COLORMAP_XCOLORMAP (cmap));
398 if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
400 gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
406 gdk_window_impl_x11_get_size (GdkDrawable *drawable,
410 g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
413 *width = GDK_WINDOW_IMPL_X11 (drawable)->width;
415 *height = GDK_WINDOW_IMPL_X11 (drawable)->height;
419 gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
421 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
422 GdkRectangle result_rect;
426 result_rect.width = impl->width;
427 result_rect.height = impl->height;
429 gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
431 return gdk_region_rectangle (&result_rect);
435 _gdk_windowing_window_init (GdkScreen * screen)
437 GdkWindowObject *private;
438 GdkWindowImplX11 *impl;
439 GdkDrawableImplX11 *draw_impl;
440 GdkScreenX11 *screen_x11;
442 screen_x11 = GDK_SCREEN_X11 (screen);
444 g_assert (screen_x11->root_window == NULL);
446 gdk_screen_set_default_colormap (screen,
447 gdk_screen_get_system_colormap (screen));
449 screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
450 private = (GdkWindowObject *)screen_x11->root_window;
451 impl = GDK_WINDOW_IMPL_X11 (private->impl);
452 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
454 draw_impl->screen = screen;
455 draw_impl->xid = screen_x11->xroot_window;
456 draw_impl->wrapper = GDK_DRAWABLE (private);
457 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
458 g_object_ref (draw_impl->colormap);
460 private->window_type = GDK_WINDOW_ROOT;
461 private->depth = DefaultDepthOfScreen (screen_x11->xscreen);
463 impl->width = WidthOfScreen (screen_x11->xscreen);
464 impl->height = HeightOfScreen (screen_x11->xscreen);
466 _gdk_window_init_position (GDK_WINDOW (private));
468 _gdk_xid_table_insert (screen_x11->display,
469 &screen_x11->xroot_window,
470 screen_x11->root_window);
474 set_wm_protocols (GdkWindow *window)
476 GdkDisplay *display = gdk_drawable_get_display (window);
480 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
481 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
482 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
485 if (GDK_DISPLAY_X11 (display)->use_sync)
486 protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
489 XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
493 get_default_title (void)
497 title = g_get_application_name ();
499 title = g_get_prgname ();
505 check_leader_window_title (GdkDisplay *display)
507 GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
509 if (display_x11->leader_window && !display_x11->leader_window_title_set)
511 set_wm_name (display,
512 display_x11->leader_window,
513 get_default_title ());
515 display_x11->leader_window_title_set = TRUE;
520 create_focus_window (Display *xdisplay,
523 Window focus_window = XCreateSimpleWindow (xdisplay, parent,
527 /* FIXME: probably better to actually track the requested event mask for the toplevel
529 XSelectInput (xdisplay, focus_window,
530 KeyPressMask | KeyReleaseMask | FocusChangeMask);
532 XMapWindow (xdisplay, focus_window);
538 ensure_sync_counter (GdkWindow *window)
541 if (!GDK_WINDOW_DESTROYED (window))
543 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
544 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
545 GdkWindowObject *private = (GdkWindowObject *)window;
546 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
548 if (toplevel && impl->use_synchronized_configure &&
549 toplevel->update_counter == None &&
550 GDK_DISPLAY_X11 (display)->use_sync)
552 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
556 XSyncIntToValue (&value, 0);
558 toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
560 atom = gdk_x11_get_xatom_by_name_for_display (display,
561 "_NET_WM_SYNC_REQUEST_COUNTER");
563 XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
566 (guchar *)&toplevel->update_counter, 1);
568 XSyncIntToValue (&toplevel->current_counter_value, 0);
575 setup_toplevel_window (GdkWindow *window,
578 GdkWindowObject *obj = (GdkWindowObject *)window;
579 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
580 GdkWindowImplX11 *impl = (GdkWindowImplX11 *)obj->impl;
581 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
582 XID xid = GDK_WINDOW_XID (window);
583 XID xparent = GDK_WINDOW_XID (parent);
584 GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (parent));
585 XSizeHints size_hints;
588 if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
589 XSetTransientForHint (xdisplay, xid, xparent);
591 set_wm_protocols (window);
593 if (!obj->input_only)
595 /* The focus window is off the visible area, and serves to receive key
596 * press events so they don't get sent to child windows.
598 toplevel->focus_window = create_focus_window (xdisplay, xid);
599 _gdk_xid_table_insert (screen_x11->display, &toplevel->focus_window, window);
602 check_leader_window_title (screen_x11->display);
604 /* FIXME: Is there any point in doing this? Do any WM's pay
605 * attention to PSize, and even if they do, is this the
608 size_hints.flags = PSize;
609 size_hints.width = impl->width;
610 size_hints.height = impl->height;
612 XSetWMNormalHints (xdisplay, xid, &size_hints);
614 /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
615 XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
618 XChangeProperty (xdisplay, xid,
619 gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_PID"),
624 XChangeProperty (xdisplay, xid,
625 gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"),
626 XA_WINDOW, 32, PropModeReplace,
627 (guchar *) &GDK_DISPLAY_X11 (screen_x11->display)->leader_window, 1);
629 if (!obj->focus_on_map)
630 gdk_x11_window_set_user_time (window, 0);
631 else if (GDK_DISPLAY_X11 (screen_x11->display)->user_time != 0)
632 gdk_x11_window_set_user_time (window, GDK_DISPLAY_X11 (screen_x11->display)->user_time);
634 ensure_sync_counter (window);
639 * @parent: a #GdkWindow, or %NULL to create the window as a child of
640 * the default root window for the default display.
641 * @attributes: attributes of the new window
642 * @attributes_mask: mask indicating which fields in @attributes are valid
644 * Creates a new #GdkWindow using the attributes from
645 * @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
646 * more details. Note: to use this on displays other than the default
647 * display, @parent must be specified.
649 * Return value: the new #GdkWindow
652 gdk_window_new (GdkWindow *parent,
653 GdkWindowAttr *attributes,
654 gint attributes_mask)
657 GdkWindowObject *private;
658 GdkWindowImplX11 *impl;
659 GdkDrawableImplX11 *draw_impl;
660 GdkScreenX11 *screen_x11;
669 XSetWindowAttributes xattributes;
670 long xattributes_mask;
671 XClassHint *class_hint;
678 g_return_val_if_fail (attributes != NULL, NULL);
683 g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
685 screen = gdk_screen_get_default ();
686 parent = gdk_screen_get_root_window (screen);
689 screen = gdk_drawable_get_screen (parent);
691 screen_x11 = GDK_SCREEN_X11 (screen);
693 g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
695 if (GDK_WINDOW_DESTROYED (parent))
698 xparent = GDK_WINDOW_XID (parent);
700 window = g_object_new (GDK_TYPE_WINDOW, NULL);
701 private = (GdkWindowObject *)window;
702 impl = GDK_WINDOW_IMPL_X11 (private->impl);
703 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
704 draw_impl->wrapper = GDK_DRAWABLE (window);
706 draw_impl->screen = screen;
707 xdisplay = screen_x11->xdisplay;
709 /* Windows with a foreign parent are treated as if they are children
710 * of the root window, except for actual creation.
712 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
713 parent = gdk_screen_get_root_window (screen);
715 private->parent = (GdkWindowObject *)parent;
717 private->accept_focus = TRUE;
718 private->focus_on_map = TRUE;
720 xattributes_mask = 0;
722 if (attributes_mask & GDK_WA_X)
727 if (attributes_mask & GDK_WA_Y)
734 impl->width = (attributes->width > 1) ? (attributes->width) : (1);
735 impl->height = (attributes->height > 1) ? (attributes->height) : (1);
737 if (attributes->wclass == GDK_INPUT_ONLY)
739 /* Backwards compatiblity - we've always ignored
740 * attributes->window_type for input-only windows
743 if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
744 private->window_type = GDK_WINDOW_TEMP;
746 private->window_type = GDK_WINDOW_CHILD;
749 private->window_type = attributes->window_type;
751 _gdk_window_init_position (GDK_WINDOW (private));
752 if (impl->position_info.big)
753 private->guffaw_gravity = TRUE;
755 if (attributes_mask & GDK_WA_VISUAL)
756 visual = attributes->visual;
758 visual = gdk_screen_get_system_visual (screen);
759 xvisual = ((GdkVisualPrivate*) visual)->xvisual;
761 xattributes.event_mask = StructureNotifyMask | PropertyChangeMask;
762 for (i = 0; i < _gdk_nenvent_masks; i++)
764 if (attributes->event_mask & (1 << (i + 1)))
765 xattributes.event_mask |= _gdk_event_mask_table[i];
767 private->event_mask = attributes->event_mask;
769 if (xattributes.event_mask)
770 xattributes_mask |= CWEventMask;
772 if (attributes_mask & GDK_WA_NOREDIR)
774 xattributes.override_redirect =
775 (attributes->override_redirect == FALSE)?False:True;
776 xattributes_mask |= CWOverrideRedirect;
779 xattributes.override_redirect = False;
781 impl->override_redirect = xattributes.override_redirect;
783 if (private->parent && private->parent->guffaw_gravity)
785 xattributes.win_gravity = StaticGravity;
786 xattributes_mask |= CWWinGravity;
790 switch (private->window_type)
792 case GDK_WINDOW_TOPLEVEL:
793 case GDK_WINDOW_DIALOG:
794 case GDK_WINDOW_TEMP:
795 if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
797 g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
798 "of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
799 xparent = GDK_SCREEN_XROOTWIN (screen);
801 case GDK_WINDOW_CHILD:
804 g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
808 if (attributes->wclass == GDK_INPUT_OUTPUT)
811 depth = visual->depth;
813 private->input_only = FALSE;
814 private->depth = depth;
816 if (attributes_mask & GDK_WA_COLORMAP)
818 draw_impl->colormap = attributes->colormap;
819 g_object_ref (attributes->colormap);
823 if ((((GdkVisualPrivate *)gdk_screen_get_system_visual (screen))->xvisual) == xvisual)
825 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
826 g_object_ref (draw_impl->colormap);
830 draw_impl->colormap = gdk_colormap_new (visual, FALSE);
834 private->bg_color.pixel = BlackPixel (xdisplay, screen_x11->screen_num);
835 xattributes.background_pixel = private->bg_color.pixel;
837 private->bg_pixmap = NULL;
839 xattributes.border_pixel = BlackPixel (xdisplay, screen_x11->screen_num);
840 xattributes_mask |= CWBorderPixel | CWBackPixel;
842 if (private->guffaw_gravity)
843 xattributes.bit_gravity = StaticGravity;
845 xattributes.bit_gravity = NorthWestGravity;
847 xattributes_mask |= CWBitGravity;
849 xattributes.colormap = GDK_COLORMAP_XCOLORMAP (draw_impl->colormap);
850 xattributes_mask |= CWColormap;
852 if (private->window_type == GDK_WINDOW_TEMP)
854 xattributes.save_under = True;
855 xattributes.override_redirect = True;
856 xattributes.cursor = None;
857 xattributes_mask |= CWSaveUnder | CWOverrideRedirect;
859 impl->override_redirect = TRUE;
867 private->input_only = TRUE;
868 draw_impl->colormap = gdk_screen_get_system_colormap (screen);
869 g_object_ref (draw_impl->colormap);
872 xid = draw_impl->xid = XCreateWindow (xdisplay, xparent,
873 impl->position_info.x, impl->position_info.y,
874 impl->position_info.width, impl->position_info.height,
875 0, depth, class, xvisual,
876 xattributes_mask, &xattributes);
878 g_object_ref (window);
879 _gdk_xid_table_insert (screen_x11->display, &draw_impl->xid, window);
881 gdk_window_set_cursor (window, ((attributes_mask & GDK_WA_CURSOR) ?
882 (attributes->cursor) :
886 private->parent->children = g_list_prepend (private->parent->children, window);
888 switch (GDK_WINDOW_TYPE (private))
890 case GDK_WINDOW_DIALOG:
891 case GDK_WINDOW_TOPLEVEL:
892 case GDK_WINDOW_TEMP:
893 if (attributes_mask & GDK_WA_TITLE)
894 title = attributes->title;
896 title = get_default_title ();
898 gdk_window_set_title (window, title);
900 if (attributes_mask & GDK_WA_WMCLASS)
902 class_hint = XAllocClassHint ();
903 class_hint->res_name = attributes->wmclass_name;
904 class_hint->res_class = attributes->wmclass_class;
905 XSetClassHint (xdisplay, xid, class_hint);
909 setup_toplevel_window (window, parent);
912 case GDK_WINDOW_CHILD:
913 if ((attributes->wclass == GDK_INPUT_OUTPUT) &&
914 (draw_impl->colormap != gdk_screen_get_system_colormap (screen)) &&
915 (draw_impl->colormap != gdk_drawable_get_colormap (gdk_window_get_toplevel (window))))
917 GDK_NOTE (MISC, g_message ("adding colormap window\n"));
918 gdk_window_add_colormap_windows (window);
930 x_event_mask_to_gdk_event_mask (long mask)
932 GdkEventMask event_mask = 0;
935 for (i = 0; i < _gdk_nenvent_masks; i++)
937 if (mask & _gdk_event_mask_table[i])
938 event_mask |= 1 << (i + 1);
945 * gdk_window_foreign_new_for_display:
946 * @display: the #GdkDisplay where the window handle comes from.
947 * @anid: a native window handle.
949 * Wraps a native window in a #GdkWindow.
950 * This may fail if the window has been destroyed.
952 * For example in the X backend, a native window handle is an Xlib
955 * Return value: the newly-created #GdkWindow wrapper for the
956 * native window or %NULL if the window has been destroyed.
961 gdk_window_foreign_new_for_display (GdkDisplay *display,
962 GdkNativeWindow anid)
965 GdkWindowObject *private;
966 GdkWindowImplX11 *impl;
967 GdkDrawableImplX11 *draw_impl;
968 GdkDisplayX11 *display_x11;
969 XWindowAttributes attrs;
971 Window *children = NULL;
975 g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
977 display_x11 = GDK_DISPLAY_X11 (display);
979 gdk_error_trap_push ();
980 result = XGetWindowAttributes (display_x11->xdisplay, anid, &attrs);
981 if (gdk_error_trap_pop () || !result)
984 /* FIXME: This is pretty expensive. Maybe the caller should supply
986 gdk_error_trap_push ();
987 result = XQueryTree (display_x11->xdisplay, anid, &root, &parent, &children, &nchildren);
988 if (gdk_error_trap_pop () || !result)
994 window = g_object_new (GDK_TYPE_WINDOW, NULL);
995 private = (GdkWindowObject *)window;
996 impl = GDK_WINDOW_IMPL_X11 (private->impl);
997 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
998 draw_impl->wrapper = GDK_DRAWABLE (window);
999 draw_impl->screen = _gdk_x11_display_screen_for_xrootwin (display, root);
1001 private->parent = gdk_xid_table_lookup_for_display (display, parent);
1003 if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
1004 private->parent = (GdkWindowObject *) gdk_screen_get_root_window (draw_impl->screen);
1006 private->parent->children = g_list_prepend (private->parent->children, window);
1008 draw_impl->xid = anid;
1010 private->x = attrs.x;
1011 private->y = attrs.y;
1012 impl->width = attrs.width;
1013 impl->height = attrs.height;
1014 private->window_type = GDK_WINDOW_FOREIGN;
1015 private->destroyed = FALSE;
1017 private->event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
1019 if (attrs.map_state == IsUnmapped)
1020 private->state = GDK_WINDOW_STATE_WITHDRAWN;
1024 private->depth = attrs.depth;
1026 _gdk_window_init_position (GDK_WINDOW (private));
1028 g_object_ref (window);
1029 _gdk_xid_table_insert (display, &GDK_WINDOW_XID (window), window);
1034 * gdk_window_lookup_for_display:
1035 * @display: the #GdkDisplay corresponding to the window handle
1036 * @anid: a native window handle.
1038 * Looks up the #GdkWindow that wraps the given native window handle.
1040 * For example in the X backend, a native window handle is an Xlib
1043 * Return value: the #GdkWindow wrapper for the native window,
1044 * or %NULL if there is none.
1049 gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
1051 return (GdkWindow*) gdk_xid_table_lookup_for_display (display, anid);
1055 * gdk_window_lookup:
1056 * @anid: a native window handle.
1058 * Looks up the #GdkWindow that wraps the given native window handle.
1060 * For example in the X backend, a native window handle is an Xlib
1063 * Return value: the #GdkWindow wrapper for the native window,
1064 * or %NULL if there is none.
1067 gdk_window_lookup (GdkNativeWindow anid)
1069 return (GdkWindow*) gdk_xid_table_lookup (anid);
1073 gdk_toplevel_x11_free_contents (GdkDisplay *display,
1074 GdkToplevelX11 *toplevel)
1076 if (toplevel->icon_window)
1078 g_object_unref (toplevel->icon_window);
1079 toplevel->icon_window = NULL;
1081 if (toplevel->icon_pixmap)
1083 g_object_unref (toplevel->icon_pixmap);
1084 toplevel->icon_pixmap = NULL;
1086 if (toplevel->icon_mask)
1088 g_object_unref (toplevel->icon_mask);
1089 toplevel->icon_mask = NULL;
1091 if (toplevel->group_leader)
1093 g_object_unref (toplevel->group_leader);
1094 toplevel->group_leader = NULL;
1097 if (toplevel->update_counter != None)
1099 XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display),
1100 toplevel->update_counter);
1101 toplevel->update_counter = None;
1103 XSyncIntToValue (&toplevel->current_counter_value, 0);
1104 XSyncIntToValue (&toplevel->pending_counter_value, 0);
1110 _gdk_windowing_window_destroy (GdkWindow *window,
1112 gboolean foreign_destroy)
1114 GdkWindowObject *private = (GdkWindowObject *)window;
1115 GdkToplevelX11 *toplevel;
1116 GdkDrawableImplX11 *draw_impl;
1118 g_return_if_fail (GDK_IS_WINDOW (window));
1120 _gdk_selection_window_destroyed (window);
1122 if (private->extension_events != 0)
1123 _gdk_input_window_destroy (window);
1125 toplevel = _gdk_x11_window_get_toplevel (window);
1127 gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
1129 draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
1131 if (draw_impl->xft_draw)
1132 XftDrawDestroy (draw_impl->xft_draw);
1134 if (!recursing && !foreign_destroy)
1136 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1141 _gdk_windowing_window_destroy_foreign (GdkWindow *window)
1143 /* It's somebody else's window, but in our heirarchy,
1144 * so reparent it to the root window, and then send
1145 * it a delete event, as if we were a WM
1147 XClientMessageEvent xevent;
1149 gdk_error_trap_push ();
1150 gdk_window_hide (window);
1151 gdk_window_reparent (window, NULL, 0, 0);
1153 xevent.type = ClientMessage;
1154 xevent.window = GDK_WINDOW_XID (window);
1155 xevent.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
1158 xevent.data.l[0] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
1159 "WM_DELETE_WINDOW");
1160 xevent.data.l[1] = CurrentTime;
1161 xevent.data.l[2] = 0;
1162 xevent.data.l[3] = 0;
1163 xevent.data.l[4] = 0;
1165 XSendEvent (GDK_WINDOW_XDISPLAY (window),
1166 GDK_WINDOW_XID (window),
1167 False, 0, (XEvent *)&xevent);
1168 gdk_display_sync (GDK_WINDOW_DISPLAY (window));
1169 gdk_error_trap_pop ();
1173 get_root (GdkWindow *window)
1175 GdkScreen *screen = gdk_drawable_get_screen (window);
1177 return gdk_screen_get_root_window (screen);
1180 /* This function is called when the XWindow is really gone.
1183 gdk_window_destroy_notify (GdkWindow *window)
1185 GdkWindowImplX11 *window_impl;
1187 g_return_if_fail (window != NULL);
1189 window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
1191 if (!GDK_WINDOW_DESTROYED (window))
1193 if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
1194 g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
1196 _gdk_window_destroy (window, TRUE);
1199 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), GDK_WINDOW_XID (window));
1200 if (window_impl->toplevel && window_impl->toplevel->focus_window)
1201 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), window_impl->toplevel->focus_window);
1203 _gdk_xgrab_check_destroy (window);
1205 g_object_unref (window);
1209 update_wm_hints (GdkWindow *window,
1212 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
1213 GdkWindowObject *private = (GdkWindowObject *)window;
1214 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1218 private->state & GDK_WINDOW_STATE_WITHDRAWN)
1221 wm_hints.flags = StateHint | InputHint;
1222 wm_hints.input = private->accept_focus ? True : False;
1223 wm_hints.initial_state = NormalState;
1225 if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1227 wm_hints.flags |= StateHint;
1228 wm_hints.initial_state = IconicState;
1231 if (toplevel->icon_window && !GDK_WINDOW_DESTROYED (toplevel->icon_window))
1233 wm_hints.flags |= IconWindowHint;
1234 wm_hints.icon_window = GDK_WINDOW_XID (toplevel->icon_window);
1237 if (toplevel->icon_pixmap)
1239 wm_hints.flags |= IconPixmapHint;
1240 wm_hints.icon_pixmap = GDK_PIXMAP_XID (toplevel->icon_pixmap);
1243 if (toplevel->icon_mask)
1245 wm_hints.flags |= IconMaskHint;
1246 wm_hints.icon_mask = GDK_PIXMAP_XID (toplevel->icon_mask);
1249 wm_hints.flags |= WindowGroupHint;
1250 if (toplevel->group_leader && !GDK_WINDOW_DESTROYED (toplevel->group_leader))
1252 wm_hints.flags |= WindowGroupHint;
1253 wm_hints.window_group = GDK_WINDOW_XID (toplevel->group_leader);
1256 wm_hints.window_group = GDK_DISPLAY_X11 (display)->leader_window;
1258 XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1259 GDK_WINDOW_XID (window),
1264 set_initial_hints (GdkWindow *window)
1266 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1267 Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1268 Window xwindow = GDK_WINDOW_XID (window);
1269 GdkWindowObject *private;
1270 GdkToplevelX11 *toplevel;
1274 private = (GdkWindowObject*) window;
1275 toplevel = _gdk_x11_window_get_toplevel (window);
1280 update_wm_hints (window, TRUE);
1282 /* We set the spec hints regardless of whether the spec is supported,
1283 * since it can't hurt and it's kind of expensive to check whether
1289 if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1291 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1292 "_NET_WM_STATE_MAXIMIZED_VERT");
1294 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1295 "_NET_WM_STATE_MAXIMIZED_HORZ");
1299 if (private->state & GDK_WINDOW_STATE_ABOVE)
1301 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1302 "_NET_WM_STATE_ABOVE");
1306 if (private->state & GDK_WINDOW_STATE_BELOW)
1308 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1309 "_NET_WM_STATE_BELOW");
1313 if (private->state & GDK_WINDOW_STATE_STICKY)
1315 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1316 "_NET_WM_STATE_STICKY");
1320 if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1322 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1323 "_NET_WM_STATE_FULLSCREEN");
1327 if (private->modal_hint)
1329 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1330 "_NET_WM_STATE_MODAL");
1334 if (toplevel->skip_taskbar_hint)
1336 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1337 "_NET_WM_STATE_SKIP_TASKBAR");
1341 if (toplevel->skip_pager_hint)
1343 atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1344 "_NET_WM_STATE_SKIP_PAGER");
1350 XChangeProperty (xdisplay,
1352 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
1353 XA_ATOM, 32, PropModeReplace,
1354 (guchar*) atoms, i);
1358 XDeleteProperty (xdisplay,
1360 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"));
1363 if (private->state & GDK_WINDOW_STATE_STICKY)
1365 atoms[0] = 0xFFFFFFFF;
1366 XChangeProperty (xdisplay,
1368 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
1369 XA_CARDINAL, 32, PropModeReplace,
1370 (guchar*) atoms, 1);
1374 XDeleteProperty (xdisplay,
1376 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"));
1379 toplevel->map_serial = NextRequest (xdisplay);
1383 show_window_internal (GdkWindow *window,
1386 GdkWindowObject *private;
1387 GdkDisplay *display;
1388 GdkDisplayX11 *display_x11;
1389 GdkToplevelX11 *toplevel;
1391 g_return_if_fail (GDK_IS_WINDOW (window));
1393 private = (GdkWindowObject*) window;
1394 if (!private->destroyed)
1396 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1397 Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
1398 Window xwindow = GDK_WINDOW_XID (window);
1401 XRaiseWindow (xdisplay, xwindow);
1403 if (!GDK_WINDOW_IS_MAPPED (window))
1405 set_initial_hints (window);
1407 gdk_synthesize_window_state (window,
1408 GDK_WINDOW_STATE_WITHDRAWN,
1412 g_assert (GDK_WINDOW_IS_MAPPED (window));
1414 if (WINDOW_IS_TOPLEVEL (window))
1416 display = gdk_drawable_get_display (window);
1417 display_x11 = GDK_DISPLAY_X11 (display);
1418 toplevel = _gdk_x11_window_get_toplevel (window);
1420 if (toplevel->user_time != 0 &&
1421 display_x11->user_time != 0 &&
1422 XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time))
1423 gdk_x11_window_set_user_time (window, display_x11->user_time);
1426 if (impl->position_info.mapped)
1428 gboolean unset_bg = !private->input_only &&
1429 (private->window_type == GDK_WINDOW_CHILD ||
1430 impl->override_redirect) &&
1431 gdk_window_is_viewable (window);
1434 _gdk_x11_window_tmp_unset_bg (window, TRUE);
1436 XMapWindow (xdisplay, xwindow);
1440 _gdk_x11_window_tmp_reset_bg (window, TRUE);
1441 gdk_window_invalidate_rect (window, NULL, TRUE);
1448 * gdk_window_show_unraised:
1449 * @window: a #GdkWindow
1451 * Shows a #GdkWindow onscreen, but does not modify its stacking
1452 * order. In contrast, gdk_window_show() will raise the window
1453 * to the top of the window stack.
1455 * On the X11 platform, in Xlib terms, this function calls
1456 * XMapWindow() (it also updates some internal GDK state, which means
1457 * that you can't really use XMapWindow() directly on a GDK window).
1461 gdk_window_show_unraised (GdkWindow *window)
1463 g_return_if_fail (GDK_IS_WINDOW (window));
1465 show_window_internal (window, FALSE);
1470 * @window: a #GdkWindow
1472 * Like gdk_window_show_unraised(), but also raises the window to the
1473 * top of the window stack (moves the window to the front of the
1476 * This function maps a window so it's visible onscreen. Its opposite
1477 * is gdk_window_hide().
1479 * When implementing a #GtkWidget, you should call this function on the widget's
1480 * #GdkWindow as part of the "map" method.
1484 gdk_window_show (GdkWindow *window)
1486 g_return_if_fail (GDK_IS_WINDOW (window));
1488 show_window_internal (window, TRUE);
1492 pre_unmap (GdkWindow *window)
1494 GdkWindow *start_window = NULL;
1495 GdkWindowObject *private = (GdkWindowObject *)window;
1497 if (private->input_only)
1500 if (private->window_type == GDK_WINDOW_CHILD)
1501 start_window = (GdkWindow *)private->parent;
1502 else if (private->window_type == GDK_WINDOW_TEMP)
1503 start_window = get_root (window);
1506 _gdk_x11_window_tmp_unset_bg (start_window, TRUE);
1510 post_unmap (GdkWindow *window)
1512 GdkWindow *start_window = NULL;
1513 GdkWindowObject *private = (GdkWindowObject *)window;
1515 if (private->input_only)
1518 if (private->window_type == GDK_WINDOW_CHILD)
1519 start_window = (GdkWindow *)private->parent;
1520 else if (private->window_type == GDK_WINDOW_TEMP)
1521 start_window = get_root (window);
1525 _gdk_x11_window_tmp_reset_bg (start_window, TRUE);
1527 if (private->window_type == GDK_WINDOW_CHILD && private->parent)
1529 GdkRectangle invalid_rect;
1531 gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
1532 gdk_drawable_get_size (GDK_DRAWABLE (window),
1533 &invalid_rect.width, &invalid_rect.height);
1534 gdk_window_invalidate_rect ((GdkWindow *)private->parent,
1535 &invalid_rect, TRUE);
1542 * @window: a #GdkWindow
1544 * For toplevel windows, withdraws them, so they will no longer be
1545 * known to the window manager; for all windows, unmaps them, so
1546 * they won't be displayed. Normally done automatically as
1547 * part of gtk_widget_hide().
1551 gdk_window_hide (GdkWindow *window)
1553 GdkWindowObject *private;
1555 g_return_if_fail (window != NULL);
1557 private = (GdkWindowObject*) window;
1559 /* We'll get the unmap notify eventually, and handle it then,
1560 * but checking here makes things more consistent if we are
1561 * just doing stuff ourself.
1563 _gdk_xgrab_check_unmap (window,
1564 NextRequest (GDK_WINDOW_XDISPLAY (window)));
1566 /* You can't simply unmap toplevel windows. */
1567 switch (private->window_type)
1569 case GDK_WINDOW_TOPLEVEL:
1570 case GDK_WINDOW_DIALOG:
1571 case GDK_WINDOW_TEMP: /* ? */
1572 gdk_window_withdraw (window);
1576 case GDK_WINDOW_FOREIGN:
1577 case GDK_WINDOW_ROOT:
1578 case GDK_WINDOW_CHILD:
1582 if (!private->destroyed)
1584 if (GDK_WINDOW_IS_MAPPED (window))
1585 gdk_synthesize_window_state (window,
1587 GDK_WINDOW_STATE_WITHDRAWN);
1589 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1591 _gdk_window_clear_update_area (window);
1595 XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
1596 GDK_WINDOW_XID (window));
1598 post_unmap (window);
1603 * gdk_window_withdraw:
1604 * @window: a toplevel #GdkWindow
1606 * Withdraws a window (unmaps it and asks the window manager to forget about it).
1607 * This function is not really useful as gdk_window_hide() automatically
1608 * withdraws toplevel windows before hiding them.
1612 gdk_window_withdraw (GdkWindow *window)
1614 GdkWindowObject *private;
1616 g_return_if_fail (window != NULL);
1618 private = (GdkWindowObject*) window;
1619 if (!private->destroyed)
1621 if (GDK_WINDOW_IS_MAPPED (window))
1622 gdk_synthesize_window_state (window,
1624 GDK_WINDOW_STATE_WITHDRAWN);
1626 g_assert (!GDK_WINDOW_IS_MAPPED (window));
1630 XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
1631 GDK_WINDOW_XID (window), 0);
1633 post_unmap (window);
1639 * @window: a #GdkWindow
1640 * @x: X coordinate relative to window's parent
1641 * @y: Y coordinate relative to window's parent
1643 * Repositions a window relative to its parent window.
1644 * For toplevel windows, window managers may ignore or modify the move;
1645 * you should probably use gtk_window_move() on a #GtkWindow widget
1646 * anyway, instead of using GDK functions. For child windows,
1647 * the move will reliably succeed.
1649 * If you're also planning to resize the window, use gdk_window_move_resize()
1650 * to both move and resize simultaneously, for a nicer visual effect.
1653 gdk_window_move (GdkWindow *window,
1657 GdkWindowObject *private = (GdkWindowObject *)window;
1658 GdkWindowImplX11 *impl;
1660 g_return_if_fail (window != NULL);
1661 g_return_if_fail (GDK_IS_WINDOW (window));
1663 impl = GDK_WINDOW_IMPL_X11 (private->impl);
1665 if (!GDK_WINDOW_DESTROYED (window))
1667 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1669 _gdk_window_move_resize_child (window, x, y,
1670 impl->width, impl->height);
1674 XMoveWindow (GDK_WINDOW_XDISPLAY (window),
1675 GDK_WINDOW_XID (window),
1678 if (impl->override_redirect)
1688 * gdk_window_resize:
1689 * @window: a #GdkWindow
1690 * @width: new width of the window
1691 * @height: new height of the window
1693 * Resizes @window; for toplevel windows, asks the window manager to resize
1694 * the window. The window manager may not allow the resize. When using GTK+,
1695 * use gtk_window_resize() instead of this low-level GDK function.
1697 * Windows may not be resized below 1x1.
1699 * If you're also planning to move the window, use gdk_window_move_resize()
1700 * to both move and resize simultaneously, for a nicer visual effect.
1703 gdk_window_resize (GdkWindow *window,
1707 GdkWindowObject *private;
1709 g_return_if_fail (window != NULL);
1710 g_return_if_fail (GDK_IS_WINDOW (window));
1717 private = (GdkWindowObject*) window;
1719 if (!GDK_WINDOW_DESTROYED (window))
1721 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1723 _gdk_window_move_resize_child (window, private->x, private->y,
1728 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1730 XResizeWindow (GDK_WINDOW_XDISPLAY (window),
1731 GDK_WINDOW_XID (window),
1734 if (impl->override_redirect)
1736 impl->width = width;
1737 impl->height = height;
1741 if (width != impl->width || height != impl->height)
1742 private->resize_count += 1;
1749 * gdk_window_move_resize:
1750 * @window: a #GdkWindow
1751 * @x: new X position relative to window's parent
1752 * @y: new Y position relative to window's parent
1754 * @height: new height
1756 * Equivalent to calling gdk_window_move() and gdk_window_resize(),
1757 * except that both operations are performed at once, avoiding strange
1758 * visual effects. (i.e. the user may be able to see the window first
1759 * move, then resize, if you don't use gdk_window_move_resize().)
1762 gdk_window_move_resize (GdkWindow *window,
1768 GdkWindowObject *private;
1770 g_return_if_fail (window != NULL);
1771 g_return_if_fail (GDK_IS_WINDOW (window));
1778 private = (GdkWindowObject*) window;
1780 if (!GDK_WINDOW_DESTROYED (window))
1782 if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1784 _gdk_window_move_resize_child (window, x, y, width, height);
1788 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1790 XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
1791 GDK_WINDOW_XID (window),
1792 x, y, width, height);
1793 if (impl->override_redirect)
1797 impl->width = width;
1798 impl->height = height;
1802 if (width != impl->width || height != impl->height)
1803 private->resize_count += 1;
1810 * gdk_window_reparent:
1811 * @window: a #GdkWindow
1812 * @new_parent: new parent to move @window into
1813 * @x: X location inside the new parent
1814 * @y: Y location inside the new parent
1816 * Reparents @window into the given @new_parent. The window being
1817 * reparented will be unmapped as a side effect.
1821 gdk_window_reparent (GdkWindow *window,
1822 GdkWindow *new_parent,
1826 GdkDisplay *display;
1827 GdkWindowObject *window_private;
1828 GdkWindowObject *parent_private;
1829 GdkWindowObject *old_parent_private;
1830 GdkWindowImplX11 *impl;
1831 gboolean was_toplevel;
1833 g_return_if_fail (window != NULL);
1834 g_return_if_fail (GDK_IS_WINDOW (window));
1835 g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1836 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1838 if (GDK_WINDOW_DESTROYED (window) ||
1839 (new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1845 new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1847 display = GDK_WINDOW_DISPLAY (window);
1849 window_private = (GdkWindowObject*) window;
1850 old_parent_private = (GdkWindowObject*)window_private->parent;
1851 parent_private = (GdkWindowObject*) new_parent;
1852 impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
1854 XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1855 GDK_WINDOW_XID (window),
1856 GDK_WINDOW_XID (new_parent),
1859 window_private->x = x;
1860 window_private->y = y;
1862 /* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1865 if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1866 new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1868 window_private->parent = (GdkWindowObject *)new_parent;
1870 /* Switch the window type as appropriate */
1872 switch (GDK_WINDOW_TYPE (new_parent))
1874 case GDK_WINDOW_ROOT:
1875 case GDK_WINDOW_FOREIGN:
1876 was_toplevel = WINDOW_IS_TOPLEVEL (window);
1878 if (impl->toplevel_window_type != -1)
1879 GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1880 else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1881 GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1883 if (WINDOW_IS_TOPLEVEL (window) && !was_toplevel)
1884 setup_toplevel_window (window, new_parent);
1886 case GDK_WINDOW_TOPLEVEL:
1887 case GDK_WINDOW_CHILD:
1888 case GDK_WINDOW_DIALOG:
1889 case GDK_WINDOW_TEMP:
1890 if (WINDOW_IS_TOPLEVEL (window))
1892 /* Save the original window type so we can restore it if the
1893 * window is reparented back to be a toplevel
1895 impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1896 GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1899 if (impl->toplevel->focus_window)
1901 XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window);
1902 _gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
1905 gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window),
1907 g_free (impl->toplevel);
1908 impl->toplevel = NULL;
1913 if (old_parent_private)
1914 old_parent_private->children = g_list_remove (old_parent_private->children, window);
1916 if ((old_parent_private &&
1917 (!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1918 (!old_parent_private && parent_private->guffaw_gravity))
1919 gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1921 parent_private->children = g_list_prepend (parent_private->children, window);
1922 _gdk_window_init_position (GDK_WINDOW (window_private));
1926 _gdk_windowing_window_clear_area (GdkWindow *window,
1932 g_return_if_fail (window != NULL);
1933 g_return_if_fail (GDK_IS_WINDOW (window));
1935 if (!GDK_WINDOW_DESTROYED (window))
1936 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1937 x, y, width, height, False);
1941 _gdk_windowing_window_clear_area_e (GdkWindow *window,
1947 g_return_if_fail (window != NULL);
1948 g_return_if_fail (GDK_IS_WINDOW (window));
1950 if (!GDK_WINDOW_DESTROYED (window))
1951 XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1952 x, y, width, height, True);
1958 * @window: a #GdkWindow
1960 * Raises @window to the top of the Z-order (stacking order), so that
1961 * other windows with the same parent window appear below @window.
1962 * This is true whether or not the windows are visible.
1964 * If @window is a toplevel, the window manager may choose to deny the
1965 * request to move the window in the Z-order, gdk_window_raise() only
1966 * requests the restack, does not guarantee it.
1970 gdk_window_raise (GdkWindow *window)
1972 g_return_if_fail (window != NULL);
1973 g_return_if_fail (GDK_IS_WINDOW (window));
1975 if (!GDK_WINDOW_DESTROYED (window))
1976 XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1981 * @window: a #GdkWindow
1983 * Lowers @window to the bottom of the Z-order (stacking order), so that
1984 * other windows with the same parent window appear above @window.
1985 * This is true whether or not the other windows are visible.
1987 * If @window is a toplevel, the window manager may choose to deny the
1988 * request to move the window in the Z-order, gdk_window_lower() only
1989 * requests the restack, does not guarantee it.
1991 * Note that gdk_window_show() raises the window again, so don't call this
1992 * function before gdk_window_show(). (Try gdk_window_show_unraised().)
1996 gdk_window_lower (GdkWindow *window)
1998 g_return_if_fail (window != NULL);
1999 g_return_if_fail (GDK_IS_WINDOW (window));
2001 if (!GDK_WINDOW_DESTROYED (window))
2002 XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
2007 * @window: a #GdkWindow
2008 * @timestamp: timestamp of the event triggering the window focus
2010 * Sets keyboard focus to @window. If @window is not onscreen this
2011 * will not work. In most cases, gtk_window_present() should be used on
2012 * a #GtkWindow, rather than calling this function.
2016 gdk_window_focus (GdkWindow *window,
2019 GdkDisplay *display;
2021 g_return_if_fail (GDK_IS_WINDOW (window));
2023 if (GDK_WINDOW_DESTROYED (window))
2026 display = GDK_WINDOW_DISPLAY (window);
2028 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
2029 gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE)))
2033 xev.xclient.type = ClientMessage;
2034 xev.xclient.serial = 0;
2035 xev.xclient.send_event = True;
2036 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
2037 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
2038 "_NET_ACTIVE_WINDOW");
2039 xev.xclient.format = 32;
2040 xev.xclient.data.l[0] = 1; /* requestor type; we're an app */
2041 xev.xclient.data.l[1] = timestamp;
2042 xev.xclient.data.l[2] = None; /* currently active window */
2043 xev.xclient.data.l[3] = 0;
2044 xev.xclient.data.l[4] = 0;
2046 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
2047 SubstructureRedirectMask | SubstructureNotifyMask,
2052 XRaiseWindow (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window));
2054 /* There is no way of knowing reliably whether we are viewable;
2055 * _gdk_x11_set_input_focus_safe() traps errors asynchronously.
2057 _gdk_x11_set_input_focus_safe (display, GDK_WINDOW_XID (window),
2064 * gdk_window_set_hints:
2065 * @window: a #GdkWindow
2066 * @x: ignored field, does not matter
2067 * @y: ignored field, does not matter
2068 * @min_width: minimum width hint
2069 * @min_height: minimum height hint
2070 * @max_width: max width hint
2071 * @max_height: max height hint
2072 * @flags: logical OR of GDK_HINT_POS, GDK_HINT_MIN_SIZE, and/or GDK_HINT_MAX_SIZE
2074 * This function is broken and useless and you should ignore it.
2075 * If using GTK+, use functions such as gtk_window_resize(), gtk_window_set_size_request(),
2076 * gtk_window_move(), gtk_window_parse_geometry(), and gtk_window_set_geometry_hints(),
2077 * depending on what you're trying to do.
2079 * If using GDK directly, use gdk_window_set_geometry_hints().
2083 gdk_window_set_hints (GdkWindow *window,
2092 XSizeHints size_hints;
2094 g_return_if_fail (window != NULL);
2095 g_return_if_fail (GDK_IS_WINDOW (window));
2097 if (GDK_WINDOW_DESTROYED (window))
2100 size_hints.flags = 0;
2102 if (flags & GDK_HINT_POS)
2104 size_hints.flags |= PPosition;
2109 if (flags & GDK_HINT_MIN_SIZE)
2111 size_hints.flags |= PMinSize;
2112 size_hints.min_width = min_width;
2113 size_hints.min_height = min_height;
2116 if (flags & GDK_HINT_MAX_SIZE)
2118 size_hints.flags |= PMaxSize;
2119 size_hints.max_width = max_width;
2120 size_hints.max_height = max_height;
2123 /* FIXME: Would it be better to delete this property if
2124 * flags == 0? It would save space on the server
2126 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2127 GDK_WINDOW_XID (window),
2132 * gdk_window_set_type_hint:
2133 * @window: A toplevel #GdkWindow
2134 * @hint: A hint of the function this window will have
2136 * The application can use this call to provide a hint to the window
2137 * manager about the functionality of a window. The window manager
2138 * can use this information when determining the decoration and behaviour
2141 * The hint must be set before the window is mapped.
2144 gdk_window_set_type_hint (GdkWindow *window,
2145 GdkWindowTypeHint hint)
2147 GdkDisplay *display;
2150 g_return_if_fail (window != NULL);
2151 g_return_if_fail (GDK_IS_WINDOW (window));
2153 if (GDK_WINDOW_DESTROYED (window))
2156 display = gdk_drawable_get_display (window);
2160 case GDK_WINDOW_TYPE_HINT_DIALOG:
2161 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
2163 case GDK_WINDOW_TYPE_HINT_MENU:
2164 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU");
2166 case GDK_WINDOW_TYPE_HINT_TOOLBAR:
2167 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR");
2169 case GDK_WINDOW_TYPE_HINT_UTILITY:
2170 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
2172 case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2173 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
2175 case GDK_WINDOW_TYPE_HINT_DOCK:
2176 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
2178 case GDK_WINDOW_TYPE_HINT_DESKTOP:
2179 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
2182 g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
2184 case GDK_WINDOW_TYPE_HINT_NORMAL:
2185 atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL");
2189 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2190 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
2191 XA_ATOM, 32, PropModeReplace,
2192 (guchar *)&atom, 1);
2197 gdk_wmspec_change_state (gboolean add,
2202 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
2205 #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
2206 #define _NET_WM_STATE_ADD 1 /* add/set property */
2207 #define _NET_WM_STATE_TOGGLE 2 /* toggle property */
2209 xev.xclient.type = ClientMessage;
2210 xev.xclient.serial = 0;
2211 xev.xclient.send_event = True;
2212 xev.xclient.window = GDK_WINDOW_XID (window);
2213 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
2214 xev.xclient.format = 32;
2215 xev.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
2216 xev.xclient.data.l[1] = gdk_x11_atom_to_xatom_for_display (display, state1);
2217 xev.xclient.data.l[2] = gdk_x11_atom_to_xatom_for_display (display, state2);
2218 xev.xclient.data.l[3] = 0;
2219 xev.xclient.data.l[4] = 0;
2221 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
2222 SubstructureRedirectMask | SubstructureNotifyMask,
2227 * gdk_window_set_modal_hint:
2228 * @window: A toplevel #GdkWindow
2229 * @modal: TRUE if the window is modal, FALSE otherwise.
2231 * The application can use this hint to tell the window manager
2232 * that a certain window has modal behaviour. The window manager
2233 * can use this information to handle modal windows in a special
2236 * You should only use this on windows for which you have
2237 * previously called #gdk_window_set_transient_for()
2240 gdk_window_set_modal_hint (GdkWindow *window,
2243 GdkWindowObject *private;
2245 g_return_if_fail (window != NULL);
2246 g_return_if_fail (GDK_IS_WINDOW (window));
2248 if (GDK_WINDOW_DESTROYED (window))
2251 private = (GdkWindowObject*) window;
2253 private->modal_hint = modal;
2255 if (GDK_WINDOW_IS_MAPPED (window))
2256 gdk_wmspec_change_state (modal, window,
2257 gdk_atom_intern ("_NET_WM_STATE_MODAL", FALSE),
2262 * gdk_window_set_skip_taskbar_hint:
2263 * @window: a toplevel #GdkWindow
2264 * @skips_taskbar: %TRUE to skip the taskbar
2266 * Toggles whether a window should appear in a task list or window
2267 * list. If a window's semantic type as specified with
2268 * gdk_window_set_type_hint() already fully describes the window, this
2269 * function should NOT be called in addition, instead you should allow
2270 * the window to be treated according to standard policy for its
2276 gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2277 gboolean skips_taskbar)
2279 GdkToplevelX11 *toplevel;
2281 g_return_if_fail (window != NULL);
2282 g_return_if_fail (GDK_IS_WINDOW (window));
2283 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2285 if (GDK_WINDOW_DESTROYED (window))
2288 toplevel = _gdk_x11_window_get_toplevel (window);
2289 toplevel->skip_taskbar_hint = skips_taskbar;
2291 if (GDK_WINDOW_IS_MAPPED (window))
2292 gdk_wmspec_change_state (skips_taskbar, window,
2293 gdk_atom_intern ("_NET_WM_STATE_SKIP_TASKBAR", FALSE),
2298 * gdk_window_set_skip_pager_hint:
2299 * @window: a toplevel #GdkWindow
2300 * @skips_pager: %TRUE to skip the pager
2302 * Toggles whether a window should appear in a pager (workspace
2303 * switcher, or other desktop utility program that displays a small
2304 * thumbnail representation of the windows on the desktop). If a
2305 * window's semantic type as specified with gdk_window_set_type_hint()
2306 * already fully describes the window, this function should NOT be
2307 * called in addition, instead you should allow the window to be
2308 * treated according to standard policy for its semantic type.
2313 gdk_window_set_skip_pager_hint (GdkWindow *window,
2314 gboolean skips_pager)
2316 GdkToplevelX11 *toplevel;
2318 g_return_if_fail (window != NULL);
2319 g_return_if_fail (GDK_IS_WINDOW (window));
2320 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2322 if (GDK_WINDOW_DESTROYED (window))
2325 toplevel = _gdk_x11_window_get_toplevel (window);
2326 toplevel->skip_pager_hint = skips_pager;
2328 if (GDK_WINDOW_IS_MAPPED (window))
2329 gdk_wmspec_change_state (skips_pager, window,
2330 gdk_atom_intern ("_NET_WM_STATE_SKIP_PAGER", FALSE),
2335 * gdk_window_set_geometry_hints:
2336 * @window: a toplevel #GdkWindow
2337 * @geometry: geometry hints
2338 * @geom_mask: bitmask indicating fields of @geometry to pay attention to
2340 * Sets the geometry hints for @window. Hints flagged in @geom_mask
2341 * are set, hints not flagged in @geom_mask are unset.
2342 * To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
2344 * This function provides hints to the windowing system about
2345 * acceptable sizes for a toplevel window. The purpose of
2346 * this is to constrain user resizing, but the windowing system
2347 * will typically (but is not required to) also constrain the
2348 * current size of the window to the provided values and
2349 * constrain programatic resizing via gdk_window_resize() or
2350 * gdk_window_move_resize().
2352 * Note that on X11, this effect has no effect on windows
2353 * of type GDK_WINDOW_TEMP or windows where override_redirect
2354 * has been turned on via gdk_window_set_override_redirect()
2355 * since these windows are not resizable by the user.
2357 * Since you can't count on the windowing system doing the
2358 * constraints for programmatic resizes, you should generally
2359 * call gdk_window_constrain_size() yourself to determine
2360 * appropriate sizes.
2364 gdk_window_set_geometry_hints (GdkWindow *window,
2365 GdkGeometry *geometry,
2366 GdkWindowHints geom_mask)
2368 XSizeHints size_hints;
2370 g_return_if_fail (window != NULL);
2371 g_return_if_fail (GDK_IS_WINDOW (window));
2373 if (GDK_WINDOW_DESTROYED (window))
2376 size_hints.flags = 0;
2378 if (geom_mask & GDK_HINT_POS)
2380 size_hints.flags |= PPosition;
2381 /* We need to initialize the following obsolete fields because KWM
2382 * apparently uses these fields if they are non-zero.
2389 if (geom_mask & GDK_HINT_USER_POS)
2391 size_hints.flags |= USPosition;
2394 if (geom_mask & GDK_HINT_USER_SIZE)
2396 size_hints.flags |= USSize;
2399 if (geom_mask & GDK_HINT_MIN_SIZE)
2401 size_hints.flags |= PMinSize;
2402 size_hints.min_width = geometry->min_width;
2403 size_hints.min_height = geometry->min_height;
2406 if (geom_mask & GDK_HINT_MAX_SIZE)
2408 size_hints.flags |= PMaxSize;
2409 size_hints.max_width = MAX (geometry->max_width, 1);
2410 size_hints.max_height = MAX (geometry->max_height, 1);
2413 if (geom_mask & GDK_HINT_BASE_SIZE)
2415 size_hints.flags |= PBaseSize;
2416 size_hints.base_width = geometry->base_width;
2417 size_hints.base_height = geometry->base_height;
2420 if (geom_mask & GDK_HINT_RESIZE_INC)
2422 size_hints.flags |= PResizeInc;
2423 size_hints.width_inc = geometry->width_inc;
2424 size_hints.height_inc = geometry->height_inc;
2427 if (geom_mask & GDK_HINT_ASPECT)
2429 size_hints.flags |= PAspect;
2430 if (geometry->min_aspect <= 1)
2432 size_hints.min_aspect.x = 65536 * geometry->min_aspect;
2433 size_hints.min_aspect.y = 65536;
2437 size_hints.min_aspect.x = 65536;
2438 size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
2440 if (geometry->max_aspect <= 1)
2442 size_hints.max_aspect.x = 65536 * geometry->max_aspect;
2443 size_hints.max_aspect.y = 65536;
2447 size_hints.max_aspect.x = 65536;
2448 size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
2452 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2454 size_hints.flags |= PWinGravity;
2455 size_hints.win_gravity = geometry->win_gravity;
2458 /* FIXME: Would it be better to delete this property if
2459 * geom_mask == 0? It would save space on the server
2461 XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2462 GDK_WINDOW_XID (window),
2467 gdk_window_get_geometry_hints (GdkWindow *window,
2468 GdkGeometry *geometry,
2469 GdkWindowHints *geom_mask)
2471 XSizeHints size_hints;
2472 glong junk_size_mask = 0;
2474 g_return_if_fail (GDK_IS_WINDOW (window));
2475 g_return_if_fail (geometry != NULL);
2476 g_return_if_fail (geom_mask != NULL);
2480 if (GDK_WINDOW_DESTROYED (window))
2483 if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2484 GDK_WINDOW_XID (window),
2489 if (size_hints.flags & PMinSize)
2491 *geom_mask |= GDK_HINT_MIN_SIZE;
2492 geometry->min_width = size_hints.min_width;
2493 geometry->min_height = size_hints.min_height;
2496 if (size_hints.flags & PMaxSize)
2498 *geom_mask |= GDK_HINT_MAX_SIZE;
2499 geometry->max_width = MAX (size_hints.max_width, 1);
2500 geometry->max_height = MAX (size_hints.max_height, 1);
2503 if (size_hints.flags & PResizeInc)
2505 *geom_mask |= GDK_HINT_RESIZE_INC;
2506 geometry->width_inc = size_hints.width_inc;
2507 geometry->height_inc = size_hints.height_inc;
2510 if (size_hints.flags & PAspect)
2512 *geom_mask |= GDK_HINT_ASPECT;
2514 geometry->min_aspect = (gdouble) size_hints.min_aspect.x / (gdouble) size_hints.min_aspect.y;
2515 geometry->max_aspect = (gdouble) size_hints.max_aspect.x / (gdouble) size_hints.max_aspect.y;
2518 if (size_hints.flags & PWinGravity)
2520 *geom_mask |= GDK_HINT_WIN_GRAVITY;
2521 geometry->win_gravity = size_hints.win_gravity;
2526 utf8_is_latin1 (const gchar *str)
2528 const char *p = str;
2532 gunichar ch = g_utf8_get_char (p);
2537 p = g_utf8_next_char (p);
2543 /* Set the property to @utf8_str as STRING if the @utf8_str is fully
2544 * convertable to STRING, otherwise, set it as compound text
2547 set_text_property (GdkDisplay *display,
2550 const gchar *utf8_str)
2552 guchar *prop_text = NULL;
2556 gboolean is_compound_text;
2558 if (utf8_is_latin1 (utf8_str))
2560 prop_type = XA_STRING;
2561 prop_text = gdk_utf8_to_string_target (utf8_str);
2562 prop_length = prop_text ? strlen (prop_text) : 0;
2564 is_compound_text = FALSE;
2570 gdk_utf8_to_compound_text_for_display (display,
2571 utf8_str, &gdk_type, &prop_format,
2572 &prop_text, &prop_length);
2573 prop_type = gdk_x11_atom_to_xatom_for_display (display, gdk_type);
2574 is_compound_text = TRUE;
2579 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
2582 prop_type, prop_format,
2583 PropModeReplace, prop_text,
2586 if (is_compound_text)
2587 gdk_free_compound_text (prop_text);
2593 /* Set WM_NAME and _NET_WM_NAME
2596 set_wm_name (GdkDisplay *display,
2600 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
2601 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
2602 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2603 PropModeReplace, name, strlen (name));
2605 set_text_property (display, xwindow,
2606 gdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"),
2611 * gdk_window_set_title:
2612 * @window: a toplevel #GdkWindow
2613 * @title: title of @window
2615 * Sets the title of a toplevel window, to be displayed in the titlebar.
2616 * If you haven't explicitly set the icon name for the window
2617 * (using gdk_window_set_icon_name()), the icon name will be set to
2618 * @title as well. @title must be in UTF-8 encoding (as with all
2619 * user-readable strings in GDK/GTK+). @title may not be %NULL.
2622 gdk_window_set_title (GdkWindow *window,
2625 GdkDisplay *display;
2629 g_return_if_fail (window != NULL);
2630 g_return_if_fail (GDK_IS_WINDOW (window));
2631 g_return_if_fail (title != NULL);
2633 if (GDK_WINDOW_DESTROYED (window))
2636 display = gdk_drawable_get_display (window);
2637 xdisplay = GDK_DISPLAY_XDISPLAY (display);
2638 xwindow = GDK_WINDOW_XID (window);
2640 set_wm_name (display, xwindow, title);
2642 if (!gdk_window_icon_name_set (window))
2644 XChangeProperty (xdisplay, xwindow,
2645 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
2646 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2647 PropModeReplace, title, strlen (title));
2649 set_text_property (display, xwindow,
2650 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
2656 * gdk_window_set_role:
2657 * @window: a toplevel #GdkWindow
2658 * @role: a string indicating its role
2660 * When using GTK+, typically you should use gtk_window_set_role() instead
2661 * of this low-level function.
2663 * The window manager and session manager use a window's role to
2664 * distinguish it from other kinds of window in the same application.
2665 * When an application is restarted after being saved in a previous
2666 * session, all windows with the same title and role are treated as
2667 * interchangeable. So if you have two windows with the same title
2668 * that should be distinguished for session management purposes, you
2669 * should set the role on those windows. It doesn't matter what string
2670 * you use for the role, as long as you have a different role for each
2671 * non-interchangeable kind of window.
2675 gdk_window_set_role (GdkWindow *window,
2678 GdkDisplay *display;
2680 g_return_if_fail (window != NULL);
2681 g_return_if_fail (GDK_IS_WINDOW (window));
2683 display = gdk_drawable_get_display (window);
2685 if (!GDK_WINDOW_DESTROYED (window))
2688 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2689 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
2690 XA_STRING, 8, PropModeReplace, role, strlen (role));
2692 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2693 gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
2698 * gdk_window_set_transient_for:
2699 * @window: a toplevel #GdkWindow
2700 * @parent: another toplevel #GdkWindow
2702 * Indicates to the window manager that @window is a transient dialog
2703 * associated with the application window @parent. This allows the
2704 * window manager to do things like center @window on @parent and
2705 * keep @window above @parent.
2707 * See gtk_window_set_transient_for() if you're using #GtkWindow or
2712 gdk_window_set_transient_for (GdkWindow *window,
2715 GdkWindowObject *private;
2716 GdkWindowObject *parent_private;
2718 g_return_if_fail (window != NULL);
2719 g_return_if_fail (GDK_IS_WINDOW (window));
2721 private = (GdkWindowObject*) window;
2722 parent_private = (GdkWindowObject*) parent;
2724 if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
2725 XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
2726 GDK_WINDOW_XID (window),
2727 GDK_WINDOW_XID (parent));
2731 * gdk_window_set_background:
2732 * @window: a #GdkWindow
2733 * @color: an allocated #GdkColor
2735 * Sets the background color of @window. (However, when using GTK+,
2736 * set the background of a widget with gtk_widget_modify_bg() - if
2737 * you're an application - or gtk_style_set_background() - if you're
2738 * implementing a custom widget.)
2740 * The @color must be allocated; gdk_rgb_find_color() is the best way
2741 * to allocate a color.
2743 * See also gdk_window_set_back_pixmap().
2747 gdk_window_set_background (GdkWindow *window,
2748 const GdkColor *color)
2750 GdkWindowObject *private = (GdkWindowObject *)window;
2752 g_return_if_fail (window != NULL);
2753 g_return_if_fail (GDK_IS_WINDOW (window));
2755 if (!GDK_WINDOW_DESTROYED (window))
2756 XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
2757 GDK_WINDOW_XID (window), color->pixel);
2759 private->bg_color = *color;
2761 if (private->bg_pixmap &&
2762 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2763 private->bg_pixmap != GDK_NO_BG)
2764 g_object_unref (private->bg_pixmap);
2766 private->bg_pixmap = NULL;
2770 * gdk_window_set_back_pixmap:
2771 * @window: a #GdkWindow
2772 * @pixmap: a #GdkPixmap, or %NULL
2773 * @parent_relative: whether the tiling origin is at the origin of @window's parent
2775 * Sets the background pixmap of @window. May also be used to set a background of
2776 * "None" on @window, by setting a background pixmap of %NULL.
2777 * A background pixmap will be tiled, positioning the first tile at the origin of
2778 * @window, or if @parent_relative is %TRUE, the tiling will be done based on the
2779 * origin of the parent window (useful to align tiles in a parent with tiles
2782 * A background pixmap of %NULL means that the window will have no
2783 * background. A window with no background will never have its
2784 * background filled by the windowing system, instead the window will
2785 * contain whatever pixels were already in the corresponding area of
2788 * The windowing system will normally fill a window with its background
2789 * when the window is obscured then exposed, and when you call
2790 * gdk_window_clear().
2794 gdk_window_set_back_pixmap (GdkWindow *window,
2796 gboolean parent_relative)
2798 GdkWindowObject *private = (GdkWindowObject *)window;
2801 g_return_if_fail (window != NULL);
2802 g_return_if_fail (GDK_IS_WINDOW (window));
2803 g_return_if_fail (pixmap == NULL || !parent_relative);
2804 g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
2806 if (private->bg_pixmap &&
2807 private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2808 private->bg_pixmap != GDK_NO_BG)
2809 g_object_unref (private->bg_pixmap);
2811 if (parent_relative)
2813 xpixmap = ParentRelative;
2814 private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
2820 g_object_ref (pixmap);
2821 private->bg_pixmap = pixmap;
2822 xpixmap = GDK_PIXMAP_XID (pixmap);
2827 private->bg_pixmap = GDK_NO_BG;
2831 if (!GDK_WINDOW_DESTROYED (window))
2832 XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
2833 GDK_WINDOW_XID (window), xpixmap);
2837 * gdk_window_set_cursor:
2838 * @window: a #GdkWindow
2841 * Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new() or
2842 * gdk_cursor_new_from_pixmap() to create the cursor.
2843 * To make the cursor invisible, use gdk_cursor_new_from_pixmap() to create
2844 * a cursor with no pixels in it. Passing %NULL for the @cursor argument
2845 * to gdk_window_set_cursor() means that @window will use the cursor of
2846 * its parent window. Most windows should use this default.
2850 gdk_window_set_cursor (GdkWindow *window,
2853 GdkCursorPrivate *cursor_private;
2856 g_return_if_fail (window != NULL);
2857 g_return_if_fail (GDK_IS_WINDOW (window));
2859 cursor_private = (GdkCursorPrivate*) cursor;
2864 xcursor = cursor_private->xcursor;
2866 if (!GDK_WINDOW_DESTROYED (window))
2867 XDefineCursor (GDK_WINDOW_XDISPLAY (window),
2868 GDK_WINDOW_XID (window),
2873 * gdk_window_get_geometry:
2874 * @window: a #GdkWindow
2875 * @x: return location for X coordinate of window (relative to its parent)
2876 * @y: return location for Y coordinate of window (relative to its parent)
2877 * @width: return location for width of window
2878 * @height: return location for height of window
2879 * @depth: return location for bit depth of window
2881 * Any of the return location arguments to this function may be %NULL,
2882 * if you aren't interested in getting the value of that field.
2884 * The X and Y coordinates returned are relative to the parent window
2885 * of @window, which for toplevels usually means relative to the
2886 * window decorations (titlebar, etc.) rather than relative to the
2887 * root window (screen-size background window).
2889 * On the X11 platform, the geometry is obtained from the X server,
2890 * so reflects the latest position of @window; this may be out-of-sync
2891 * with the position of @window delivered in the most-recently-processed
2892 * #GdkEventConfigure. gdk_window_get_position() in contrast gets the
2893 * position from the most recent configure event.
2897 gdk_window_get_geometry (GdkWindow *window,
2909 guint tborder_width;
2912 g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
2916 GDK_NOTE (MULTIHEAD,
2917 g_message ("gdk_window_get_geometry(): Window needs to be non-NULL to be multi head safe"));
2918 window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
2921 if (!GDK_WINDOW_DESTROYED (window))
2923 XGetGeometry (GDK_WINDOW_XDISPLAY (window),
2924 GDK_WINDOW_XID (window),
2925 &root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
2941 * gdk_window_get_origin:
2942 * @window: a #GdkWindow
2943 * @x: return location for X coordinate
2944 * @y: return location for Y coordinate
2946 * Obtains the position of a window in root window coordinates.
2947 * (Compare with gdk_window_get_position() and
2948 * gdk_window_get_geometry() which return the position of a window
2949 * relative to its parent window.)
2951 * Return value: not meaningful, ignore
2954 gdk_window_get_origin (GdkWindow *window,
2963 g_return_val_if_fail (window != NULL, 0);
2965 if (!GDK_WINDOW_DESTROYED (window))
2967 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
2968 GDK_WINDOW_XID (window),
2969 GDK_WINDOW_XROOTWIN (window),
2985 * gdk_window_get_deskrelative_origin:
2986 * @window: a toplevel #GdkWindow
2987 * @x: return location for X coordinate
2988 * @y: return location for Y coordinate
2990 * This gets the origin of a #GdkWindow relative to
2991 * an Enlightenment-window-manager desktop. As long as you don't
2992 * assume that the user's desktop/workspace covers the entire
2993 * root window (i.e. you don't assume that the desktop begins
2994 * at root window coordinate 0,0) this function is not necessary.
2995 * It's deprecated for that reason.
2997 * Return value: not meaningful
3000 gdk_window_get_deskrelative_origin (GdkWindow *window,
3004 gboolean return_val = FALSE;
3005 gint num_children, format_return;
3006 Window win, *child, parent, root;
3011 gulong number_return, bytes_after_return;
3012 guchar *data_return;
3014 g_return_val_if_fail (window != NULL, FALSE);
3015 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
3017 if (!GDK_WINDOW_DESTROYED (window))
3019 atom = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
3020 "ENLIGHTENMENT_DESKTOP");
3021 win = GDK_WINDOW_XID (window);
3023 while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
3024 &child, (unsigned int *)&num_children))
3026 if ((child) && (num_children > 0))
3038 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
3039 False, XA_CARDINAL, &type_return, &format_return,
3040 &number_return, &bytes_after_return, &data_return);
3042 if (type_return == XA_CARDINAL)
3044 XFree (data_return);
3049 return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
3050 GDK_WINDOW_XID (window),
3065 * gdk_window_get_root_origin:
3066 * @window: a toplevel #GdkWindow
3067 * @x: return location for X position of window frame
3068 * @y: return location for Y position of window frame
3070 * Obtains the top-left corner of the window manager frame in root
3071 * window coordinates.
3075 gdk_window_get_root_origin (GdkWindow *window,
3081 g_return_if_fail (GDK_IS_WINDOW (window));
3083 gdk_window_get_frame_extents (window, &rect);
3093 * gdk_window_get_frame_extents:
3094 * @window: a toplevel #GdkWindow
3095 * @rect: rectangle to fill with bounding box of the window frame
3097 * Obtains the bounding box of the window, including window manager
3098 * titlebar/borders if any. The frame position is given in root window
3099 * coordinates. To get the position of the window itself (rather than
3100 * the frame) in root window coordinates, use gdk_window_get_origin().
3104 gdk_window_get_frame_extents (GdkWindow *window,
3107 GdkWindowObject *private;
3112 unsigned int nchildren;
3114 g_return_if_fail (GDK_IS_WINDOW (window));
3115 g_return_if_fail (rect != NULL);
3117 private = (GdkWindowObject*) window;
3124 if (GDK_WINDOW_DESTROYED (window))
3127 while (private->parent && ((GdkWindowObject*) private->parent)->parent)
3128 private = (GdkWindowObject*) private->parent;
3130 /* Refine our fallback answer a bit using local information */
3131 rect->x = private->x;
3132 rect->y = private->y;
3133 gdk_drawable_get_size ((GdkDrawable *)private, &rect->width, &rect->height);
3135 if (GDK_WINDOW_DESTROYED (private))
3138 gdk_error_trap_push();
3140 xparent = GDK_WINDOW_XID (window);
3144 if (!XQueryTree (GDK_WINDOW_XDISPLAY (window), xwindow,
3146 &children, &nchildren))
3152 while (xparent != root);
3154 if (xparent == root)
3156 unsigned int ww, wh, wb, wd;
3159 if (XGetGeometry (GDK_WINDOW_XDISPLAY (window), xwindow, &root, &wx, &wy, &ww, &wh, &wb, &wd))
3169 gdk_error_trap_pop ();
3173 _gdk_windowing_get_pointer (GdkDisplay *display,
3177 GdkModifierType *mask)
3179 GdkScreen *default_screen;
3187 if (display->closed)
3190 default_screen = gdk_display_get_default_screen (display);
3192 XQueryPointer (GDK_SCREEN_XDISPLAY (default_screen),
3193 GDK_SCREEN_XROOTWIN (default_screen),
3194 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3198 GdkWindow *gdk_root = gdk_window_lookup_for_display (display, root);
3199 *screen = gdk_drawable_get_screen (gdk_root);
3208 _gdk_windowing_window_get_pointer (GdkDisplay *display,
3212 GdkModifierType *mask)
3214 GdkWindow *return_val;
3220 unsigned int xmask = 0;
3221 gint xoffset, yoffset;
3223 g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
3225 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3228 if (!GDK_WINDOW_DESTROYED (window) &&
3229 XQueryPointer (GDK_WINDOW_XDISPLAY (window),
3230 GDK_WINDOW_XID (window),
3231 &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
3234 return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child);
3237 *x = winx + xoffset;
3238 *y = winy + yoffset;
3245 _gdk_windowing_window_at_pointer (GdkDisplay *display,
3254 Window xwindow_last = 0;
3256 int rootx = -1, rooty = -1;
3260 screen = gdk_display_get_default_screen (display);
3262 xwindow = GDK_SCREEN_XROOTWIN (screen);
3263 xdisplay = GDK_SCREEN_XDISPLAY (screen);
3265 /* This function really only works if the mouse pointer is held still
3266 * during its operation. If it moves from one leaf window to another
3267 * than we'll end up with inaccurate values for win_x, win_y
3270 gdk_x11_display_grab (display);
3271 XQueryPointer (xdisplay, xwindow,
3272 &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3274 if (root == xwindow)
3281 xwindow_last = xwindow;
3282 XQueryPointer (xdisplay, xwindow,
3283 &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
3285 gdk_x11_display_ungrab (display);
3287 window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen),
3289 *win_x = window ? winx : -1;
3290 *win_y = window ? winy : -1;
3296 * gdk_window_get_events:
3297 * @window: a #GdkWindow
3299 * Gets the event mask for @window. See gdk_window_set_events().
3301 * Return value: event mask for @window
3304 gdk_window_get_events (GdkWindow *window)
3306 XWindowAttributes attrs;
3307 GdkEventMask event_mask;
3309 g_return_val_if_fail (window != NULL, 0);
3310 g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
3312 if (GDK_WINDOW_DESTROYED (window))
3316 XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3317 GDK_WINDOW_XID (window),
3320 event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
3321 GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
3328 * gdk_window_set_events:
3329 * @window: a #GdkWindow
3330 * @event_mask: event mask for @window
3332 * The event mask for a window determines which events will be reported
3333 * for that window. For example, an event mask including #GDK_BUTTON_PRESS_MASK
3334 * means the window should report button press events. The event mask
3335 * is the bitwise OR of values from the #GdkEventMask enumeration.
3339 gdk_window_set_events (GdkWindow *window,
3340 GdkEventMask event_mask)
3345 g_return_if_fail (window != NULL);
3346 g_return_if_fail (GDK_IS_WINDOW (window));
3348 if (!GDK_WINDOW_DESTROYED (window))
3350 GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
3351 xevent_mask = StructureNotifyMask | PropertyChangeMask;
3352 for (i = 0; i < _gdk_nenvent_masks; i++)
3354 if (event_mask & (1 << (i + 1)))
3355 xevent_mask |= _gdk_event_mask_table[i];
3358 XSelectInput (GDK_WINDOW_XDISPLAY (window),
3359 GDK_WINDOW_XID (window),
3365 gdk_window_add_colormap_windows (GdkWindow *window)
3367 GdkWindow *toplevel;
3368 Window *old_windows;
3369 Window *new_windows;
3372 g_return_if_fail (window != NULL);
3373 g_return_if_fail (GDK_IS_WINDOW (window));
3375 if (GDK_WINDOW_DESTROYED (window))
3377 toplevel = gdk_window_get_toplevel (window);
3380 if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3381 GDK_WINDOW_XID (toplevel),
3382 &old_windows, &count))
3387 for (i = 0; i < count; i++)
3388 if (old_windows[i] == GDK_WINDOW_XID (window))
3390 XFree (old_windows);
3394 new_windows = g_new (Window, count + 1);
3396 for (i = 0; i < count; i++)
3397 new_windows[i] = old_windows[i];
3398 new_windows[count] = GDK_WINDOW_XID (window);
3400 XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3401 GDK_WINDOW_XID (toplevel),
3402 new_windows, count + 1);
3404 g_free (new_windows);
3406 XFree (old_windows);
3410 gdk_window_have_shape_ext (GdkDisplay *display)
3412 #ifdef HAVE_SHAPE_EXT
3415 return XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display),
3422 #define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
3425 * This needs the X11 shape extension.
3426 * If not available, shaped windows will look
3427 * ugly, but programs still work. Stefan Wille
3430 * gdk_window_shape_combine_mask:
3431 * @window: a #GdkWindow
3433 * @x: X position of shape mask with respect to @window
3434 * @y: Y position of shape mask with respect to @window
3436 * Applies a shape mask to @window. Pixels in @window corresponding to
3437 * set bits in the @mask will be visible; pixels in @window
3438 * corresponding to unset bits in the @mask will be transparent. This
3439 * gives a non-rectangular window.
3441 * If @mask is %NULL, the shape mask will be unset, and the @x/@y
3442 * parameters are not used.
3444 * On the X11 platform, this uses an X server extension which is
3445 * widely available on most common platforms, but not available on
3446 * very old X servers, and occasionally the implementation will be
3447 * buggy. On servers without the shape extension, this function
3450 * This function works on both toplevel and child windows.
3454 gdk_window_shape_combine_mask (GdkWindow *window,
3459 gint xoffset, yoffset;
3461 g_return_if_fail (window != NULL);
3462 g_return_if_fail (GDK_IS_WINDOW (window));
3464 #ifdef HAVE_SHAPE_EXT
3465 if (GDK_WINDOW_DESTROYED (window))
3468 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3470 if (xoffset != 0 || yoffset != 0)
3472 WARN_SHAPE_TOO_BIG ();
3476 if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
3480 pixmap = GDK_PIXMAP_XID (mask);
3489 XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
3490 GDK_WINDOW_XID (window),
3496 #endif /* HAVE_SHAPE_EXT */
3500 * gdk_window_shape_combine_region:
3501 * @window: a #GdkWindow
3502 * @shape_region: region of window to be non-transparent
3503 * @offset_x: X position of @shape_region in @window coordinates
3504 * @offset_y: Y position of @shape_region in @window coordinates
3506 * Makes pixels in @window outside @shape_region be transparent,
3507 * so that the window may be nonrectangular. See also
3508 * gdk_window_shape_combine_mask() to use a bitmap as the mask.
3510 * If @shape_region is %NULL, the shape will be unset, so the whole
3511 * window will be opaque again. @offset_x and @offset_y are ignored
3512 * if @shape_region is %NULL.
3514 * On the X11 platform, this uses an X server extension which is
3515 * widely available on most common platforms, but not available on
3516 * very old X servers, and occasionally the implementation will be
3517 * buggy. On servers without the shape extension, this function
3520 * This function works on both toplevel and child windows.
3524 gdk_window_shape_combine_region (GdkWindow *window,
3525 GdkRegion *shape_region,
3529 gint xoffset, yoffset;
3531 g_return_if_fail (GDK_IS_WINDOW (window));
3533 #ifdef HAVE_SHAPE_EXT
3534 if (GDK_WINDOW_DESTROYED (window))
3537 _gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3539 if (xoffset != 0 || yoffset != 0)
3541 WARN_SHAPE_TOO_BIG ();
3545 if (shape_region == NULL)
3547 /* Use NULL mask to unset the shape */
3548 gdk_window_shape_combine_mask (window, NULL, 0, 0);
3552 if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
3555 XRectangle *xrects = NULL;
3557 _gdk_region_get_xrectangles (shape_region,
3561 XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
3562 GDK_WINDOW_XID (window),
3571 #endif /* HAVE_SHAPE_EXT */
3576 * gdk_window_set_override_redirect:
3577 * @window: a toplevel #GdkWindow
3578 * @override_redirect: %TRUE if window should be override redirect
3580 * An override redirect window is not under the control of the window manager.
3581 * This means it won't have a titlebar, won't be minimizable, etc. - it will
3582 * be entirely under the control of the application. The window manager
3583 * can't see the override redirect window at all.
3585 * Override redirect should only be used for short-lived temporary
3586 * windows, such as popup menus. #GtkMenu uses an override redirect
3587 * window in its implementation, for example.
3591 gdk_window_set_override_redirect (GdkWindow *window,
3592 gboolean override_redirect)
3594 XSetWindowAttributes attr;
3596 g_return_if_fail (window != NULL);
3597 g_return_if_fail (GDK_IS_WINDOW (window));
3599 if (!GDK_WINDOW_DESTROYED (window))
3601 GdkWindowObject *private = (GdkWindowObject *)window;
3602 GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
3604 attr.override_redirect = (override_redirect? True : False);
3605 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3606 GDK_WINDOW_XID (window),
3610 impl->override_redirect = attr.override_redirect;
3615 * gdk_window_set_accept_focus:
3616 * @window: a toplevel #GdkWindow
3617 * @accept_focus: %TRUE if the window should receive input focus
3619 * Setting @accept_focus to %FALSE hints the desktop environment that the
3620 * window doesn't want to receive input focus.
3622 * On X, it is the responsibility of the window manager to interpret this
3623 * hint. ICCCM-compliant window manager usually respect it.
3628 gdk_window_set_accept_focus (GdkWindow *window,
3629 gboolean accept_focus)
3631 GdkWindowObject *private;
3632 g_return_if_fail (window != NULL);
3633 g_return_if_fail (GDK_IS_WINDOW (window));
3635 private = (GdkWindowObject *)window;
3637 accept_focus = accept_focus != FALSE;
3639 if (private->accept_focus != accept_focus)
3641 private->accept_focus = accept_focus;
3643 if (!GDK_WINDOW_DESTROYED (window))
3644 update_wm_hints (window, FALSE);
3649 * gdk_window_set_focus_on_map:
3650 * @window: a toplevel #GdkWindow
3651 * @focus_on_map: %TRUE if the window should receive input focus when mapped
3653 * Setting @focus_on_map to %FALSE hints the desktop environment that the
3654 * window doesn't want to receive input focus when it is mapped.
3655 * focus_on_map should be turned off for windows that aren't triggered
3656 * interactively (such as popups from network activity).
3658 * On X, it is the responsibility of the window manager to interpret
3659 * this hint. Window managers following the freedesktop.org window
3660 * manager extension specification should respect it.
3665 gdk_window_set_focus_on_map (GdkWindow *window,
3666 gboolean focus_on_map)
3668 GdkWindowObject *private;
3669 g_return_if_fail (window != NULL);
3670 g_return_if_fail (GDK_IS_WINDOW (window));
3672 private = (GdkWindowObject *)window;
3674 focus_on_map = focus_on_map != FALSE;
3676 if (private->focus_on_map != focus_on_map)
3678 private->focus_on_map = focus_on_map;
3680 if ((!GDK_WINDOW_DESTROYED (window)) && (!private->focus_on_map))
3681 gdk_x11_window_set_user_time (window, 0);
3686 * gdk_x11_window_set_user_time:
3687 * @window: A toplevel #GdkWindow
3688 * @timestamp: An XServer timestamp to which the property should be set
3690 * The application can use this call to update the _NET_WM_USER_TIME
3691 * property on a toplevel window. This property stores an Xserver
3692 * time which represents the time of the last user input event
3693 * received for this window. This property may be used by the window
3694 * manager to alter the focus, stacking, and/or placement behavior of
3695 * windows when they are mapped depending on whether the new window
3696 * was created by a user action or is a "pop-up" window activated by a
3697 * timer or some other event.
3699 * Note that this property is automatically updated by GDK, so this
3700 * function should only be used by applications which handle input
3701 * events bypassing GDK.
3706 gdk_x11_window_set_user_time (GdkWindow *window,
3709 GdkDisplay *display;
3710 GdkDisplayX11 *display_x11;
3711 GdkToplevelX11 *toplevel;
3712 glong timestamp_long = (glong)timestamp;
3714 g_return_if_fail (window != NULL);
3715 g_return_if_fail (GDK_IS_WINDOW (window));
3717 if (GDK_WINDOW_DESTROYED (window))
3720 display = gdk_drawable_get_display (window);
3721 display_x11 = GDK_DISPLAY_X11 (display);
3722 toplevel = _gdk_x11_window_get_toplevel (window);
3724 XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
3725 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
3726 XA_CARDINAL, 32, PropModeReplace,
3727 (guchar *)×tamp_long, 1);
3729 if (timestamp_long != GDK_CURRENT_TIME)
3730 display_x11->user_time = timestamp_long;
3732 toplevel->user_time = timestamp_long;
3736 * gdk_window_set_icon_list:
3737 * @window: The #GdkWindow toplevel window to set the icon of.
3738 * @pixbufs: A list of pixbufs, of different sizes.
3740 * Sets a list of icons for the window. One of these will be used
3741 * to represent the window when it has been iconified. The icon is
3742 * usually shown in an icon box or some sort of task bar. Which icon
3743 * size is shown depends on the window manager. The window manager
3744 * can scale the icon but setting several size icons can give better
3745 * image quality since the window manager may only need to scale the
3746 * icon by a small amount or not at all.
3750 gdk_window_set_icon_list (GdkWindow *window,
3759 gint width, height, stride;
3762 GdkDisplay *display;
3764 g_return_if_fail (GDK_IS_WINDOW (window));
3766 if (GDK_WINDOW_DESTROYED (window))
3769 display = gdk_drawable_get_display (window);
3777 g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
3779 width = gdk_pixbuf_get_width (pixbuf);
3780 height = gdk_pixbuf_get_height (pixbuf);
3782 size += 2 + width * height;
3784 l = g_list_next (l);
3787 data = g_malloc (size * sizeof (gulong));
3795 width = gdk_pixbuf_get_width (pixbuf);
3796 height = gdk_pixbuf_get_height (pixbuf);
3797 stride = gdk_pixbuf_get_rowstride (pixbuf);
3798 n_channels = gdk_pixbuf_get_n_channels (pixbuf);
3803 pixels = gdk_pixbuf_get_pixels (pixbuf);
3805 for (y = 0; y < height; y++)
3807 for (x = 0; x < width; x++)
3811 r = pixels[y*stride + x*n_channels + 0];
3812 g = pixels[y*stride + x*n_channels + 1];
3813 b = pixels[y*stride + x*n_channels + 2];
3814 if (n_channels >= 4)
3815 a = pixels[y*stride + x*n_channels + 3];
3819 *p++ = a << 24 | r << 16 | g << 8 | b ;
3823 l = g_list_next (l);
3828 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3829 GDK_WINDOW_XID (window),
3830 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"),
3833 (guchar*) data, size);
3837 XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
3838 GDK_WINDOW_XID (window),
3839 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"));
3846 * gdk_window_set_icon:
3847 * @window: a toplevel #GdkWindow
3848 * @icon_window: a #GdkWindow to use for the icon, or %NULL to unset
3849 * @pixmap: a #GdkPixmap to use as the icon, or %NULL to unset
3850 * @mask: a 1-bit pixmap (#GdkBitmap) to use as mask for @pixmap, or %NULL to have none
3852 * Sets the icon of @window as a pixmap or window. If using GTK+, investigate
3853 * gtk_window_set_default_icon_list() first, and then gtk_window_set_icon_list()
3854 * and gtk_window_set_icon(). If those don't meet your needs, look at
3855 * gdk_window_set_icon_list(). Only if all those are too high-level do you
3856 * want to fall back to gdk_window_set_icon().
3860 gdk_window_set_icon (GdkWindow *window,
3861 GdkWindow *icon_window,
3865 GdkToplevelX11 *toplevel;
3867 g_return_if_fail (window != NULL);
3868 g_return_if_fail (GDK_IS_WINDOW (window));
3869 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
3871 if (GDK_WINDOW_DESTROYED (window))
3874 toplevel = _gdk_x11_window_get_toplevel (window);
3876 if (toplevel->icon_window != icon_window)
3878 if (toplevel->icon_window)
3879 g_object_unref (toplevel->icon_window);
3880 toplevel->icon_window = g_object_ref (icon_window);
3883 if (toplevel->icon_pixmap != pixmap)
3886 g_object_ref (pixmap);
3887 if (toplevel->icon_pixmap)
3888 g_object_unref (toplevel->icon_pixmap);
3889 toplevel->icon_pixmap = pixmap;
3892 if (toplevel->icon_mask != mask)
3895 g_object_ref (mask);
3896 if (toplevel->icon_mask)
3897 g_object_unref (toplevel->icon_mask);
3898 toplevel->icon_mask = mask;
3901 update_wm_hints (window, FALSE);
3905 gdk_window_icon_name_set (GdkWindow *window)
3907 return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
3908 g_quark_from_static_string ("gdk-icon-name-set")));
3912 * gdk_window_set_icon_name:
3913 * @window: a toplevel #GdkWindow
3914 * @name: name of window while iconified (minimized)
3916 * Windows may have a name used while minimized, distinct from the
3917 * name they display in their titlebar. Most of the time this is a bad
3918 * idea from a user interface standpoint. But you can set such a name
3919 * with this function, if you like.
3923 gdk_window_set_icon_name (GdkWindow *window,
3926 GdkDisplay *display;
3928 g_return_if_fail (window != NULL);
3929 g_return_if_fail (GDK_IS_WINDOW (window));
3931 if (GDK_WINDOW_DESTROYED (window))
3934 display = gdk_drawable_get_display (window);
3936 g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
3937 GUINT_TO_POINTER (TRUE));
3939 XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
3940 GDK_WINDOW_XID (window),
3941 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
3942 gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
3943 PropModeReplace, name, strlen (name));
3945 set_text_property (display, GDK_WINDOW_XID (window),
3946 gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
3951 * gdk_window_iconify:
3952 * @window: a toplevel #GdkWindow
3954 * Asks to iconify (minimize) @window. The window manager may choose
3955 * to ignore the request, but normally will honor it. Using
3956 * gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
3958 * This function only makes sense when @window is a toplevel window.
3962 gdk_window_iconify (GdkWindow *window)
3964 GdkWindowObject *private;
3966 g_return_if_fail (window != NULL);
3967 g_return_if_fail (GDK_IS_WINDOW (window));
3969 if (GDK_WINDOW_DESTROYED (window))
3972 private = (GdkWindowObject*) window;
3974 if (GDK_WINDOW_IS_MAPPED (window))
3976 XIconifyWindow (GDK_WINDOW_XDISPLAY (window),
3977 GDK_WINDOW_XWINDOW (window),
3978 gdk_screen_get_number (GDK_WINDOW_SCREEN (window)));
3982 /* Flip our client side flag, the real work happens on map. */
3983 gdk_synthesize_window_state (window,
3985 GDK_WINDOW_STATE_ICONIFIED);
3990 * gdk_window_deiconify:
3991 * @window: a toplevel #GdkWindow
3993 * Attempt to deiconify (unminimize) @window. On X11 the window manager may
3994 * choose to ignore the request to deiconify. When using GTK+,
3995 * use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
3996 * you probably want to use gtk_window_present(), which raises the window, focuses it,
3997 * unminimizes it, and puts it on the current desktop.
4001 gdk_window_deiconify (GdkWindow *window)
4003 GdkWindowObject *private;
4005 g_return_if_fail (window != NULL);
4006 g_return_if_fail (GDK_IS_WINDOW (window));
4008 if (GDK_WINDOW_DESTROYED (window))
4011 private = (GdkWindowObject*) window;
4013 if (GDK_WINDOW_IS_MAPPED (window))
4015 gdk_window_show (window);
4019 /* Flip our client side flag, the real work happens on map. */
4020 gdk_synthesize_window_state (window,
4021 GDK_WINDOW_STATE_ICONIFIED,
4028 * @window: a toplevel #GdkWindow
4030 * "Pins" a window such that it's on all workspaces and does not scroll
4031 * with viewports, for window managers that have scrollable viewports.
4032 * (When using #GtkWindow, gtk_window_stick() may be more useful.)
4034 * On the X11 platform, this function depends on window manager
4035 * support, so may have no effect with many window managers. However,
4036 * GDK will do the best it can to convince the window manager to stick
4037 * the window. For window managers that don't support this operation,
4038 * there's nothing you can do to force it to happen.
4042 gdk_window_stick (GdkWindow *window)
4044 g_return_if_fail (GDK_IS_WINDOW (window));
4046 if (GDK_WINDOW_DESTROYED (window))
4049 if (GDK_WINDOW_IS_MAPPED (window))
4051 /* "stick" means stick to all desktops _and_ do not scroll with the
4052 * viewport. i.e. glue to the monitor glass in all cases.
4057 /* Request stick during viewport scroll */
4058 gdk_wmspec_change_state (TRUE, window,
4059 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
4062 /* Request desktop 0xFFFFFFFF */
4063 xev.xclient.type = ClientMessage;
4064 xev.xclient.serial = 0;
4065 xev.xclient.send_event = True;
4066 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
4067 xev.xclient.display = GDK_WINDOW_XDISPLAY (window);
4068 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
4070 xev.xclient.format = 32;
4072 xev.xclient.data.l[0] = 0xFFFFFFFF;
4073 xev.xclient.data.l[1] = 0;
4074 xev.xclient.data.l[2] = 0;
4075 xev.xclient.data.l[3] = 0;
4076 xev.xclient.data.l[4] = 0;
4078 XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
4079 SubstructureRedirectMask | SubstructureNotifyMask,
4084 /* Flip our client side flag, the real work happens on map. */
4085 gdk_synthesize_window_state (window,
4087 GDK_WINDOW_STATE_STICKY);
4092 * gdk_window_unstick:
4093 * @window: a toplevel #GdkWindow
4095 * Reverse operation for gdk_window_stick(); see gdk_window_stick(),
4096 * and gtk_window_unstick().
4100 gdk_window_unstick (GdkWindow *window)
4102 g_return_if_fail (GDK_IS_WINDOW (window));
4104 if (GDK_WINDOW_DESTROYED (window))
4107 if (GDK_WINDOW_IS_MAPPED (window))
4114 gulong *current_desktop;
4115 GdkDisplay *display = gdk_drawable_get_display (window);
4117 /* Request unstick from viewport */
4118 gdk_wmspec_change_state (FALSE, window,
4119 gdk_atom_intern ("_NET_WM_STATE_STICKY", FALSE),
4122 /* Get current desktop, then set it; this is a race, but not
4123 * one that matters much in practice.
4125 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window),
4126 gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
4128 False, XA_CARDINAL, &type, &format, &nitems,
4129 &bytes_after, (guchar **)¤t_desktop);
4131 if (type == XA_CARDINAL)
4133 xev.xclient.type = ClientMessage;
4134 xev.xclient.serial = 0;
4135 xev.xclient.send_event = True;
4136 xev.xclient.window = GDK_WINDOW_XWINDOW (window);
4137 xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
4138 xev.xclient.format = 32;
4140 xev.xclient.data.l[0] = *current_desktop;
4141 xev.xclient.data.l[1] = 0;
4142 xev.xclient.data.l[2] = 0;
4143 xev.xclient.data.l[3] = 0;
4144 xev.xclient.data.l[4] = 0;
4146 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
4147 SubstructureRedirectMask | SubstructureNotifyMask,
4150 XFree (current_desktop);
4155 /* Flip our client side flag, the real work happens on map. */
4156 gdk_synthesize_window_state (window,
4157 GDK_WINDOW_STATE_STICKY,
4164 * gdk_window_maximize:
4165 * @window: a toplevel #GdkWindow
4167 * Maximizes the window. If the window was already maximized, then
4168 * this function does nothing.
4170 * On X11, asks the window manager to maximize @window, if the window
4171 * manager supports this operation. Not all window managers support
4172 * this, and some deliberately ignore it or don't have a concept of
4173 * "maximized"; so you can't rely on the maximization actually
4174 * happening. But it will happen with most standard window managers,
4175 * and GDK makes a best effort to get it to happen.
4177 * On Windows, reliably maximizes the window.
4181 gdk_window_maximize (GdkWindow *window)
4183 g_return_if_fail (GDK_IS_WINDOW (window));
4185 if (GDK_WINDOW_DESTROYED (window))
4188 if (GDK_WINDOW_IS_MAPPED (window))
4189 gdk_wmspec_change_state (TRUE, window,
4190 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
4191 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
4193 gdk_synthesize_window_state (window,
4195 GDK_WINDOW_STATE_MAXIMIZED);
4199 * gdk_window_unmaximize:
4200 * @window: a toplevel #GdkWindow
4202 * Unmaximizes the window. If the window wasn't maximized, then this
4203 * function does nothing.
4205 * On X11, asks the window manager to unmaximize @window, if the
4206 * window manager supports this operation. Not all window managers
4207 * support this, and some deliberately ignore it or don't have a
4208 * concept of "maximized"; so you can't rely on the unmaximization
4209 * actually happening. But it will happen with most standard window
4210 * managers, and GDK makes a best effort to get it to happen.
4212 * On Windows, reliably unmaximizes the window.
4216 gdk_window_unmaximize (GdkWindow *window)
4218 g_return_if_fail (GDK_IS_WINDOW (window));
4220 if (GDK_WINDOW_DESTROYED (window))
4223 if (GDK_WINDOW_IS_MAPPED (window))
4224 gdk_wmspec_change_state (FALSE, window,
4225 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_VERT", FALSE),
4226 gdk_atom_intern ("_NET_WM_STATE_MAXIMIZED_HORZ", FALSE));
4228 gdk_synthesize_window_state (window,
4229 GDK_WINDOW_STATE_MAXIMIZED,
4234 * gdk_window_fullscreen:
4235 * @window: a toplevel #GdkWindow
4237 * Moves the window into fullscreen mode. This means the
4238 * window covers the entire screen and is above any panels
4241 * If the window was already fullscreen, then this function does nothing.
4243 * On X11, asks the window manager to put @window in a fullscreen
4244 * state, if the window manager supports this operation. Not all
4245 * window managers support this, and some deliberately ignore it or
4246 * don't have a concept of "fullscreen"; so you can't rely on the
4247 * fullscreenification actually happening. But it will happen with
4248 * most standard window managers, and GDK makes a best effort to get
4254 gdk_window_fullscreen (GdkWindow *window)
4256 g_return_if_fail (GDK_IS_WINDOW (window));
4258 if (GDK_WINDOW_DESTROYED (window))
4261 if (GDK_WINDOW_IS_MAPPED (window))
4262 gdk_wmspec_change_state (TRUE, window,
4263 gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
4267 gdk_synthesize_window_state (window,
4269 GDK_WINDOW_STATE_FULLSCREEN);
4273 * gdk_window_unfullscreen:
4274 * @window: a toplevel #GdkWindow
4276 * Moves the window out of fullscreen mode. If the window was not
4277 * fullscreen, does nothing.
4279 * On X11, asks the window manager to move @window out of the fullscreen
4280 * state, if the window manager supports this operation. Not all
4281 * window managers support this, and some deliberately ignore it or
4282 * don't have a concept of "fullscreen"; so you can't rely on the
4283 * unfullscreenification actually happening. But it will happen with
4284 * most standard window managers, and GDK makes a best effort to get
4290 gdk_window_unfullscreen (GdkWindow *window)
4292 g_return_if_fail (GDK_IS_WINDOW (window));
4294 if (GDK_WINDOW_DESTROYED (window))
4297 if (GDK_WINDOW_IS_MAPPED (window))
4298 gdk_wmspec_change_state (FALSE, window,
4299 gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", FALSE),
4303 gdk_synthesize_window_state (window,
4304 GDK_WINDOW_STATE_FULLSCREEN,
4309 * gdk_window_set_keep_above:
4310 * @window: a toplevel #GdkWindow
4311 * @setting: whether to keep @window above other windows
4313 * Set if @window must be kept above other windows. If the
4314 * window was already above, then this function does nothing.
4316 * On X11, asks the window manager to keep @window above, if the window
4317 * manager supports this operation. Not all window managers support
4318 * this, and some deliberately ignore it or don't have a concept of
4319 * "keep above"; so you can't rely on the window being kept above.
4320 * But it will happen with most standard window managers,
4321 * and GDK makes a best effort to get it to happen.
4326 gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
4328 g_return_if_fail (GDK_IS_WINDOW (window));
4330 if (GDK_WINDOW_DESTROYED (window))
4333 if (GDK_WINDOW_IS_MAPPED (window))
4336 gdk_wmspec_change_state (FALSE, window,
4337 gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE),
4339 gdk_wmspec_change_state (setting, window,
4340 gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE),
4344 gdk_synthesize_window_state (window,
4345 setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
4346 setting ? GDK_WINDOW_STATE_ABOVE : 0);
4350 * gdk_window_set_keep_below:
4351 * @window: a toplevel #GdkWindow
4352 * @setting: whether to keep @window below other windows
4354 * Set if @window must be kept below other windows. If the
4355 * window was already below, then this function does nothing.
4357 * On X11, asks the window manager to keep @window below, if the window
4358 * manager supports this operation. Not all window managers support
4359 * this, and some deliberately ignore it or don't have a concept of
4360 * "keep below"; so you can't rely on the window being kept below.
4361 * But it will happen with most standard window managers,
4362 * and GDK makes a best effort to get it to happen.
4367 gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
4369 g_return_if_fail (GDK_IS_WINDOW (window));
4371 if (GDK_WINDOW_DESTROYED (window))
4374 if (GDK_WINDOW_IS_MAPPED (window))
4377 gdk_wmspec_change_state (FALSE, window,
4378 gdk_atom_intern ("_NET_WM_STATE_ABOVE", FALSE),
4380 gdk_wmspec_change_state (setting, window,
4381 gdk_atom_intern ("_NET_WM_STATE_BELOW", FALSE),
4385 gdk_synthesize_window_state (window,
4386 setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
4387 setting ? GDK_WINDOW_STATE_BELOW : 0);
4391 * gdk_window_get_group:
4392 * @window: a toplevel #GdkWindow
4394 * Returns the group leader window for @window. See gdk_window_set_group().
4396 * Return value: the group leader window for @window
4401 gdk_window_get_group (GdkWindow *window)
4403 GdkToplevelX11 *toplevel;
4405 g_return_val_if_fail (window != NULL, NULL);
4406 g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4407 g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
4409 if (GDK_WINDOW_DESTROYED (window))
4412 toplevel = _gdk_x11_window_get_toplevel (window);
4414 return toplevel->group_leader;
4418 * gdk_window_set_group:
4419 * @window: a toplevel #GdkWindow
4420 * @leader: group leader window, or %NULL to restore the default group leader window
4422 * Sets the group leader window for @window. By default,
4423 * GDK sets the group leader for all toplevel windows
4424 * to a global window implicitly created by GDK. With this function
4425 * you can override this default.
4427 * The group leader window allows the window manager to distinguish
4428 * all windows that belong to a single application. It may for example
4429 * allow users to minimize/unminimize all windows belonging to an
4430 * application at once. You should only set a non-default group window
4431 * if your application pretends to be multiple applications.
4434 gdk_window_set_group (GdkWindow *window,
4437 GdkToplevelX11 *toplevel;
4439 g_return_if_fail (window != NULL);
4440 g_return_if_fail (GDK_IS_WINDOW (window));
4441 g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
4442 g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
4444 if (GDK_WINDOW_DESTROYED (window) || (leader != NULL && GDK_WINDOW_DESTROYED (leader)))
4447 toplevel = _gdk_x11_window_get_toplevel (window);
4450 leader = gdk_display_get_default_group (gdk_drawable_get_display (window));
4452 if (toplevel->group_leader != leader)
4454 if (toplevel->group_leader)
4455 g_object_unref (toplevel->group_leader);
4456 toplevel->group_leader = g_object_ref (leader);
4459 update_wm_hints (window, FALSE);
4462 static MotifWmHints *
4463 gdk_window_get_mwm_hints (GdkWindow *window)
4465 GdkDisplay *display;
4466 Atom hints_atom = None;
4467 MotifWmHints *hints;
4473 if (GDK_WINDOW_DESTROYED (window))
4476 display = gdk_drawable_get_display (window);
4478 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4480 XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
4481 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4482 False, AnyPropertyType, &type, &format, &nitems,
4483 &bytes_after, (guchar **)&hints);
4492 gdk_window_set_mwm_hints (GdkWindow *window,
4493 MotifWmHints *new_hints)
4495 GdkDisplay *display;
4496 Atom hints_atom = None;
4497 MotifWmHints *hints;
4503 if (GDK_WINDOW_DESTROYED (window))
4506 display = gdk_drawable_get_display (window);
4508 hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4510 XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
4511 hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4512 False, AnyPropertyType, &type, &format, &nitems,
4513 &bytes_after, (guchar **)&hints);
4519 if (new_hints->flags & MWM_HINTS_FUNCTIONS)
4521 hints->flags |= MWM_HINTS_FUNCTIONS;
4522 hints->functions = new_hints->functions;
4524 if (new_hints->flags & MWM_HINTS_DECORATIONS)
4526 hints->flags |= MWM_HINTS_DECORATIONS;
4527 hints->decorations = new_hints->decorations;
4531 XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
4532 hints_atom, hints_atom, 32, PropModeReplace,
4533 (guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
4535 if (hints != new_hints)
4540 * gdk_window_set_decorations:
4541 * @window: a toplevel #GdkWindow
4542 * @decorations: decoration hint mask
4544 * "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
4545 * This function sets the traditional Motif window manager hints that tell the
4546 * window manager which decorations you would like your window to have.
4547 * Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
4548 * using the GDK function directly.
4550 * The @decorations argument is the logical OR of the fields in
4551 * the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
4552 * mask, the other bits indicate which decorations should be turned off.
4553 * If #GDK_DECOR_ALL is not included, then the other bits indicate
4554 * which decorations should be turned on.
4556 * Most window managers honor a decorations hint of 0 to disable all decorations,
4557 * but very few honor all possible combinations of bits.
4561 gdk_window_set_decorations (GdkWindow *window,
4562 GdkWMDecoration decorations)
4566 g_return_if_fail (window != NULL);
4567 g_return_if_fail (GDK_IS_WINDOW (window));
4569 hints.flags = MWM_HINTS_DECORATIONS;
4570 hints.decorations = decorations;
4572 gdk_window_set_mwm_hints (window, &hints);
4576 * gdk_window_get_decorations:
4577 * @window: The toplevel #GdkWindow to get the decorations from
4578 * @decorations: The window decorations will be written here
4580 * Returns the decorations set on the GdkWindow with #gdk_window_set_decorations
4581 * Returns: TRUE if the window has decorations set, FALSE otherwise.
4584 gdk_window_get_decorations(GdkWindow *window,
4585 GdkWMDecoration *decorations)
4587 MotifWmHints *hints;
4588 gboolean result = FALSE;
4590 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
4592 hints = gdk_window_get_mwm_hints (window);
4596 if (hints->flags & MWM_HINTS_DECORATIONS)
4599 *decorations = hints->decorations;
4610 * gdk_window_set_functions:
4611 * @window: a toplevel #GdkWindow
4612 * @functions: bitmask of operations to allow on @window
4614 * This function isn't really good for much. It sets the traditional
4615 * Motif window manager hint for which operations the window manager
4616 * should allow on a toplevel window. However, few window managers do
4617 * anything reliable or interesting with this hint. Many ignore it
4620 * The @functions argument is the logical OR of values from the
4621 * #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
4622 * then the other bits indicate which functions to disable; if
4623 * it doesn't include #GDK_FUNC_ALL, it indicates which functions to
4628 gdk_window_set_functions (GdkWindow *window,
4629 GdkWMFunction functions)
4633 g_return_if_fail (window != NULL);
4634 g_return_if_fail (GDK_IS_WINDOW (window));
4636 hints.flags = MWM_HINTS_FUNCTIONS;
4637 hints.functions = functions;
4639 gdk_window_set_mwm_hints (window, &hints);
4642 #ifdef HAVE_SHAPE_EXT
4645 * propagate the shapes from all child windows of a GDK window to the parent
4646 * window. Shamelessly ripped from Enlightenment's code
4654 struct _gdk_span *next;
4658 gdk_add_to_span (struct _gdk_span **s,
4662 struct _gdk_span *ptr1, *ptr2, *noo, *ss;
4669 /* scan the spans for this line */
4672 /* -- -> new span */
4673 /* == -> existing span */
4674 /* ## -> spans intersect */
4675 /* if we are in the middle of spanning the span into the line */
4678 /* case: ---- ==== */
4679 if (xx < ptr1->start - 1)
4681 /* ends before next span - extend to here */
4685 /* case: ----##=== */
4686 else if (xx <= ptr1->end)
4688 /* crosses into next span - delete next span and append */
4689 ss->end = ptr1->end;
4690 ss->next = ptr1->next;
4694 /* case: ---###--- */
4697 /* overlaps next span - delete and keep checking */
4698 ss->next = ptr1->next;
4703 /* otherwise havent started spanning it in yet */
4706 /* case: ---- ==== */
4707 if (xx < ptr1->start - 1)
4709 /* insert span here in list */
4710 noo = g_malloc (sizeof (struct _gdk_span));
4724 /* case: ----##=== */
4725 else if ((x < ptr1->start) && (xx <= ptr1->end))
4727 /* expand this span to the left point of the new one */
4731 /* case: ===###=== */
4732 else if ((x >= ptr1->start) && (xx <= ptr1->end))
4734 /* throw the span away */
4737 /* case: ---###--- */
4738 else if ((x < ptr1->start) && (xx > ptr1->end))
4745 /* case: ===##---- */
4746 else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
4752 /* case: ==== ---- */
4753 /* case handled by next loop iteration - first case */
4758 /* it started in the middle but spans beyond your current list */
4764 /* it does not start inside a span or in the middle, so add it to the end */
4765 noo = g_malloc (sizeof (struct _gdk_span));
4773 noo->next = ptr2->next;
4786 gdk_add_rectangles (Display *disp,
4788 struct _gdk_span **spans,
4795 gint x1, y1, x2, y2;
4799 rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
4802 /* go through all clip rects in this window's shape */
4803 for (k = 0; k < rn; k++)
4805 /* for each clip rect, add it to each line's spans */
4807 x2 = x + rl[k].x + (rl[k].width - 1);
4809 y2 = y + rl[k].y + (rl[k].height - 1);
4818 for (a = y1; a <= y2; a++)
4821 gdk_add_to_span (&spans[a], x1, x2);
4829 gdk_propagate_shapes (Display *disp,
4833 Window rt, par, *list = NULL;
4834 gint i, j, num = 0, num_rects = 0;
4838 XRectangle *rects = NULL;
4839 struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
4840 XWindowAttributes xatt;
4842 XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
4847 spans = g_malloc (sizeof (struct _gdk_span *) * h);
4849 for (i = 0; i < h; i++)
4851 XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
4854 /* go through all child windows and create/insert spans */
4855 for (i = 0; i < num; i++)
4857 if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
4858 if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
4859 gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
4862 gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
4864 /* go through the spans list and build a list of rects */
4865 rects = g_malloc (sizeof (XRectangle) * 256);
4867 for (i = 0; i < baseh; i++)
4870 /* go through the line for all spans */
4873 rects[num_rects].x = ptr1->start;
4874 rects[num_rects].y = i;
4875 rects[num_rects].width = ptr1->end - ptr1->start + 1;
4876 rects[num_rects].height = 1;
4878 /* if there are more lines */
4880 /* while contigous rects (same start/end coords) exist */
4881 while ((contig) && (j < baseh))
4883 /* search next line for spans matching this one */
4889 /* if we have an exact span match set contig */
4890 if ((ptr2->start == ptr1->start) &&
4891 (ptr2->end == ptr1->end))
4894 /* remove the span - not needed */
4897 ptr3->next = ptr2->next;
4903 spans[j] = ptr2->next;
4909 /* gone past the span point no point looking */
4910 else if (ptr2->start < ptr1->start)
4918 /* if a contiguous span was found increase the rect h */
4921 rects[num_rects].height++;
4925 /* up the rect count */
4927 /* every 256 new rects increase the rect array */
4928 if ((num_rects % 256) == 0)
4929 rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
4933 /* set the rects as the shape mask */
4936 XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
4937 ShapeSet, YXSorted);
4942 /* free up all the spans we made */
4943 for (i = 0; i < baseh; i++)
4956 #endif /* HAVE_SHAPE_EXT */
4959 * gdk_window_set_child_shapes:
4960 * @window: a #GdkWindow
4962 * Sets the shape mask of @window to the union of shape masks
4963 * for all children of @window, ignoring the shape mask of @window
4964 * itself. Contrast with gdk_window_merge_child_shapes() which includes
4965 * the shape mask of @window in the masks to be merged.
4968 gdk_window_set_child_shapes (GdkWindow *window)
4970 g_return_if_fail (window != NULL);
4971 g_return_if_fail (GDK_IS_WINDOW (window));
4973 #ifdef HAVE_SHAPE_EXT
4974 if (!GDK_WINDOW_DESTROYED (window) &&
4975 gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
4976 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
4977 GDK_WINDOW_XID (window), FALSE);
4982 * gdk_window_merge_child_shapes:
4983 * @window: a #GdkWindow
4985 * Merges the shape masks for any child windows into the
4986 * shape mask for @window. i.e. the union of all masks
4987 * for @window and its children will become the new mask
4988 * for @window. See gdk_window_shape_combine_mask().
4990 * This function is distinct from gdk_window_set_child_shapes()
4991 * because it includes @window's shape mask in the set of shapes to
4996 gdk_window_merge_child_shapes (GdkWindow *window)
4998 g_return_if_fail (window != NULL);
4999 g_return_if_fail (GDK_IS_WINDOW (window));
5001 #ifdef HAVE_SHAPE_EXT
5002 if (!GDK_WINDOW_DESTROYED (window) &&
5003 gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
5004 gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
5005 GDK_WINDOW_XID (window), TRUE);
5010 gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
5012 XSetWindowAttributes xattributes;
5013 GdkWindowObject *private;
5014 guint xattributes_mask = 0;
5016 g_return_if_fail (window != NULL);
5018 private = GDK_WINDOW_OBJECT (window);
5019 if (private->input_only)
5022 xattributes.bit_gravity = StaticGravity;
5023 xattributes_mask |= CWBitGravity;
5024 xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
5025 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
5026 GDK_WINDOW_XID (window),
5027 CWBitGravity, &xattributes);
5031 gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
5033 XSetWindowAttributes xattributes;
5035 g_return_if_fail (window != NULL);
5037 xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
5039 XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
5040 GDK_WINDOW_XID (window),
5041 CWWinGravity, &xattributes);
5045 * gdk_window_set_static_gravities:
5046 * @window: a #GdkWindow
5047 * @use_static: %TRUE to turn on static gravity
5049 * Set the bit gravity of the given window to static, and flag it so
5050 * all children get static subwindow gravity. This is used if you are
5051 * implementing scary features that involve deep knowledge of the
5052 * windowing system. Don't worry about it unless you have to.
5054 * Return value: %TRUE if the server supports static gravity
5057 gdk_window_set_static_gravities (GdkWindow *window,
5058 gboolean use_static)
5060 GdkWindowObject *private = (GdkWindowObject *)window;
5063 g_return_val_if_fail (window != NULL, FALSE);
5064 g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
5066 if (!use_static == !private->guffaw_gravity)
5069 private->guffaw_gravity = use_static;
5071 if (!GDK_WINDOW_DESTROYED (window))
5073 gdk_window_set_static_bit_gravity (window, use_static);
5075 tmp_list = private->children;
5078 gdk_window_set_static_win_gravity (tmp_list->data, use_static);
5080 tmp_list = tmp_list->next;
5088 wmspec_moveresize (GdkWindow *window,
5094 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
5098 /* Release passive grab */
5099 gdk_display_pointer_ungrab (display, timestamp);
5101 xev.xclient.type = ClientMessage;
5102 xev.xclient.serial = 0;
5103 xev.xclient.send_event = True;
5104 xev.xclient.window = GDK_WINDOW_XID (window);
5105 xev.xclient.message_type =
5106 gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
5107 xev.xclient.format = 32;
5108 xev.xclient.data.l[0] = root_x;
5109 xev.xclient.data.l[1] = root_y;
5110 xev.xclient.data.l[2] = direction;
5111 xev.xclient.data.l[3] = 0;
5112 xev.xclient.data.l[4] = 0;
5114 XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
5115 SubstructureRedirectMask | SubstructureNotifyMask,
5119 typedef struct _MoveResizeData MoveResizeData;
5121 struct _MoveResizeData
5123 GdkDisplay *display;
5125 GdkWindow *moveresize_window;
5126 GdkWindow *moveresize_emulation_window;
5128 GdkWindowEdge resize_edge;
5129 gint moveresize_button;
5132 gint moveresize_orig_x;
5133 gint moveresize_orig_y;
5134 gint moveresize_orig_width;
5135 gint moveresize_orig_height;
5136 GdkWindowHints moveresize_geom_mask;
5137 GdkGeometry moveresize_geometry;
5138 Time moveresize_process_time;
5139 XEvent *moveresize_pending_event;
5142 /* From the WM spec */
5143 #define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
5144 #define _NET_WM_MOVERESIZE_SIZE_TOP 1
5145 #define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
5146 #define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
5147 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
5148 #define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
5149 #define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
5150 #define _NET_WM_MOVERESIZE_SIZE_LEFT 7
5151 #define _NET_WM_MOVERESIZE_MOVE 8
5154 wmspec_resize_drag (GdkWindow *window,
5163 /* Let the compiler turn a switch into a table, instead
5164 * of doing the table manually, this way is easier to verify.
5168 case GDK_WINDOW_EDGE_NORTH_WEST:
5169 direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
5172 case GDK_WINDOW_EDGE_NORTH:
5173 direction = _NET_WM_MOVERESIZE_SIZE_TOP;
5176 case GDK_WINDOW_EDGE_NORTH_EAST:
5177 direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
5180 case GDK_WINDOW_EDGE_WEST:
5181 direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
5184 case GDK_WINDOW_EDGE_EAST:
5185 direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
5188 case GDK_WINDOW_EDGE_SOUTH_WEST:
5189 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
5192 case GDK_WINDOW_EDGE_SOUTH:
5193 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
5196 case GDK_WINDOW_EDGE_SOUTH_EAST:
5197 direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
5201 g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
5207 wmspec_moveresize (window, direction, root_x, root_y, timestamp);
5210 static MoveResizeData *
5211 get_move_resize_data (GdkDisplay *display,
5214 MoveResizeData *mv_resize;
5215 static GQuark move_resize_quark = 0;
5217 if (!move_resize_quark)
5218 move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize");
5220 mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark);
5222 if (!mv_resize && create)
5224 mv_resize = g_new0 (MoveResizeData, 1);
5225 mv_resize->display = display;
5227 g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize);
5234 update_pos (MoveResizeData *mv_resize,
5240 dx = new_root_x - mv_resize->moveresize_x;
5241 dy = new_root_y - mv_resize->moveresize_y;
5243 if (mv_resize->is_resize)
5247 x = mv_resize->moveresize_orig_x;
5248 y = mv_resize->moveresize_orig_y;
5250 w = mv_resize->moveresize_orig_width;
5251 h = mv_resize->moveresize_orig_height;
5253 switch (mv_resize->resize_edge)
5255 case GDK_WINDOW_EDGE_NORTH_WEST:
5261 case GDK_WINDOW_EDGE_NORTH:
5265 case GDK_WINDOW_EDGE_NORTH_EAST:
5270 case GDK_WINDOW_EDGE_SOUTH_WEST:
5275 case GDK_WINDOW_EDGE_SOUTH_EAST:
5279 case GDK_WINDOW_EDGE_SOUTH:
5282 case GDK_WINDOW_EDGE_EAST:
5285 case GDK_WINDOW_EDGE_WEST:
5296 if (mv_resize->moveresize_geom_mask)
5298 gdk_window_constrain_size (&mv_resize->moveresize_geometry,
5299 mv_resize->moveresize_geom_mask,
5303 gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
5309 x = mv_resize->moveresize_orig_x + dx;
5310 y = mv_resize->moveresize_orig_y + dy;
5312 gdk_window_move (mv_resize->moveresize_window, x, y);
5317 finish_drag (MoveResizeData *mv_resize)
5319 gdk_window_destroy (mv_resize->moveresize_emulation_window);
5320 mv_resize->moveresize_emulation_window = NULL;
5321 mv_resize->moveresize_window = NULL;
5323 if (mv_resize->moveresize_pending_event)
5325 g_free (mv_resize->moveresize_pending_event);
5326 mv_resize->moveresize_pending_event = NULL;
5331 lookahead_motion_predicate (Display *xdisplay,
5335 gboolean *seen_release = (gboolean *)arg;
5336 GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
5337 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5342 switch (event->xany.type)
5345 *seen_release = TRUE;
5348 mv_resize->moveresize_process_time = event->xmotion.time;
5358 moveresize_lookahead (MoveResizeData *mv_resize,
5362 gboolean seen_release = FALSE;
5364 if (mv_resize->moveresize_process_time)
5366 if (event->xmotion.time == mv_resize->moveresize_process_time)
5368 mv_resize->moveresize_process_time = 0;
5375 XCheckIfEvent (event->xany.display, &tmp_event,
5376 lookahead_motion_predicate, (XPointer) & seen_release);
5378 return mv_resize->moveresize_process_time == 0;
5382 _gdk_moveresize_handle_event (XEvent *event)
5384 guint button_mask = 0;
5385 GdkWindowObject *window_private;
5386 GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
5387 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5389 if (!mv_resize || !mv_resize->moveresize_window)
5392 window_private = (GdkWindowObject *) mv_resize->moveresize_window;
5394 button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
5396 switch (event->xany.type)
5399 if (window_private->resize_count > 0)
5401 if (mv_resize->moveresize_pending_event)
5402 *mv_resize->moveresize_pending_event = *event;
5404 mv_resize->moveresize_pending_event =
5405 g_memdup (event, sizeof (XEvent));
5409 if (!moveresize_lookahead (mv_resize, event))
5412 update_pos (mv_resize,
5413 event->xmotion.x_root,
5414 event->xmotion.y_root);
5416 /* This should never be triggered in normal cases, but in the
5417 * case where the drag started without an implicit grab being
5418 * in effect, we could miss the release if it occurs before
5419 * we grab the pointer; this ensures that we will never
5420 * get a permanently stuck grab.
5422 if ((event->xmotion.state & button_mask) == 0)
5423 finish_drag (mv_resize);
5427 update_pos (mv_resize,
5428 event->xbutton.x_root,
5429 event->xbutton.y_root);
5431 if (event->xbutton.button == mv_resize->moveresize_button)
5432 finish_drag (mv_resize);
5439 _gdk_moveresize_configure_done (GdkDisplay *display,
5443 MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5445 if (!mv_resize || window != mv_resize->moveresize_window)
5448 if (mv_resize->moveresize_pending_event)
5450 tmp_event = mv_resize->moveresize_pending_event;
5451 mv_resize->moveresize_pending_event = NULL;
5452 _gdk_moveresize_handle_event (tmp_event);
5460 create_moveresize_window (MoveResizeData *mv_resize,
5463 GdkWindowAttr attributes;
5464 gint attributes_mask;
5465 GdkGrabStatus status;
5467 g_assert (mv_resize->moveresize_emulation_window == NULL);
5469 attributes.x = -100;
5470 attributes.y = -100;
5471 attributes.width = 10;
5472 attributes.height = 10;
5473 attributes.window_type = GDK_WINDOW_TEMP;
5474 attributes.wclass = GDK_INPUT_ONLY;
5475 attributes.override_redirect = TRUE;
5476 attributes.event_mask = 0;
5478 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
5480 mv_resize->moveresize_emulation_window =
5481 gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)),
5485 gdk_window_show (mv_resize->moveresize_emulation_window);
5487 status = gdk_pointer_grab (mv_resize->moveresize_emulation_window,
5489 GDK_BUTTON_RELEASE_MASK |
5490 GDK_POINTER_MOTION_MASK,
5495 if (status != GDK_GRAB_SUCCESS)
5497 /* If this fails, some other client has grabbed the window
5500 gdk_window_destroy (mv_resize->moveresize_emulation_window);
5501 mv_resize->moveresize_emulation_window = NULL;
5504 mv_resize->moveresize_process_time = 0;
5508 Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
5509 so that calling XMoveWindow with these coordinates will not move the
5511 Note that this depends on the WM to implement ICCCM-compliant reference
5515 calculate_unmoving_origin (MoveResizeData *mv_resize)
5520 if (mv_resize->moveresize_geom_mask & GDK_HINT_WIN_GRAVITY &&
5521 mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC)
5523 gdk_window_get_origin (mv_resize->moveresize_window,
5524 &mv_resize->moveresize_orig_x,
5525 &mv_resize->moveresize_orig_y);
5529 gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
5530 gdk_window_get_geometry (mv_resize->moveresize_window,
5531 NULL, NULL, &width, &height, NULL);
5533 switch (mv_resize->moveresize_geometry.win_gravity)
5535 case GDK_GRAVITY_NORTH_WEST:
5536 mv_resize->moveresize_orig_x = rect.x;
5537 mv_resize->moveresize_orig_y = rect.y;
5539 case GDK_GRAVITY_NORTH:
5540 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5541 mv_resize->moveresize_orig_y = rect.y;
5543 case GDK_GRAVITY_NORTH_EAST:
5544 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5545 mv_resize->moveresize_orig_y = rect.y;
5547 case GDK_GRAVITY_WEST:
5548 mv_resize->moveresize_orig_x = rect.x;
5549 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5551 case GDK_GRAVITY_CENTER:
5552 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5553 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5555 case GDK_GRAVITY_EAST:
5556 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5557 mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
5559 case GDK_GRAVITY_SOUTH_WEST:
5560 mv_resize->moveresize_orig_x = rect.x;
5561 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5563 case GDK_GRAVITY_SOUTH:
5564 mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
5565 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5567 case GDK_GRAVITY_SOUTH_EAST:
5568 mv_resize->moveresize_orig_x = rect.x + rect.width - width;
5569 mv_resize->moveresize_orig_y = rect.y + rect.height - height;
5572 mv_resize->moveresize_orig_x = rect.x;
5573 mv_resize->moveresize_orig_y = rect.y;
5580 emulate_resize_drag (GdkWindow *window,
5587 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
5589 mv_resize->is_resize = TRUE;
5590 mv_resize->moveresize_button = button;
5591 mv_resize->resize_edge = edge;
5592 mv_resize->moveresize_x = root_x;
5593 mv_resize->moveresize_y = root_y;
5594 mv_resize->moveresize_window = g_object_ref (window);
5596 gdk_drawable_get_size (window,
5597 &mv_resize->moveresize_orig_width,
5598 &mv_resize->moveresize_orig_height);
5600 mv_resize->moveresize_geom_mask = 0;
5601 gdk_window_get_geometry_hints (window,
5602 &mv_resize->moveresize_geometry,
5603 &mv_resize->moveresize_geom_mask);
5605 calculate_unmoving_origin (mv_resize);
5607 create_moveresize_window (mv_resize, timestamp);
5611 emulate_move_drag (GdkWindow *window,
5617 MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
5619 mv_resize->is_resize = FALSE;
5620 mv_resize->moveresize_button = button;
5621 mv_resize->moveresize_x = root_x;
5622 mv_resize->moveresize_y = root_y;
5624 mv_resize->moveresize_window = g_object_ref (window);
5626 calculate_unmoving_origin (mv_resize);
5628 create_moveresize_window (mv_resize, timestamp);
5632 * gdk_window_begin_resize_drag:
5633 * @window: a toplevel #GdkWindow
5634 * @edge: the edge or corner from which the drag is started
5635 * @button: the button being used to drag
5636 * @root_x: root window X coordinate of mouse click that began the drag
5637 * @root_y: root window Y coordinate of mouse click that began the drag
5638 * @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
5640 * Begins a window resize operation (for a toplevel window).
5641 * You might use this function to implement a "window resize grip," for
5642 * example; in fact #GtkStatusbar uses it. The function works best
5643 * with window managers that support the Extended Window Manager Hints spec
5644 * (see http://www.freedesktop.org), but has a fallback implementation
5645 * for other window managers.
5649 gdk_window_begin_resize_drag (GdkWindow *window,
5656 g_return_if_fail (GDK_IS_WINDOW (window));
5658 if (GDK_WINDOW_DESTROYED (window))
5661 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
5662 gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
5663 wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
5665 emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
5669 * gdk_window_begin_move_drag:
5670 * @window: a toplevel #GdkWindow
5671 * @button: the button being used to drag
5672 * @root_x: root window X coordinate of mouse click that began the drag
5673 * @root_y: root window Y coordinate of mouse click that began the drag
5674 * @timestamp: timestamp of mouse click that began the drag
5676 * Begins a window move operation (for a toplevel window). You might
5677 * use this function to implement a "window move grip," for
5678 * example. The function works best with window managers that support
5679 * the Extended Window Manager Hints spec (see
5680 * http://www.freedesktop.org), but has a fallback implementation for
5681 * other window managers.
5685 gdk_window_begin_move_drag (GdkWindow *window,
5691 g_return_if_fail (GDK_IS_WINDOW (window));
5693 if (GDK_WINDOW_DESTROYED (window))
5696 if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
5697 gdk_atom_intern ("_NET_WM_MOVERESIZE", FALSE)))
5698 wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, root_x, root_y,
5701 emulate_move_drag (window, button, root_x, root_y, timestamp);
5705 * gdk_window_enable_synchronized_configure:
5706 * @window: a toplevel #GdkWindow
5708 * Indicates that the application will cooperate with the window
5709 * system in synchronizing the window repaint with the window
5710 * manager during resizing operations. After an application calls
5711 * this function, it must call gdk_window_configure_finished() every
5712 * time it has finished all processing associated with a set of
5713 * Configure events. Toplevel GTK+ windows automatically use this
5716 * On X, calling this function makes @window participate in the
5717 * _NET_WM_SYNC_REQUEST window manager protocol.
5722 gdk_window_enable_synchronized_configure (GdkWindow *window)
5724 GdkWindowObject *private = (GdkWindowObject *)window;
5725 GdkWindowImplX11 *impl;
5727 g_return_if_fail (GDK_IS_WINDOW (window));
5729 impl = GDK_WINDOW_IMPL_X11 (private->impl);
5731 if (!impl->use_synchronized_configure)
5733 impl->use_synchronized_configure = TRUE;
5734 ensure_sync_counter (window);
5739 * gdk_window_configure_finished:
5740 * @window: a toplevel #GdkWindow
5742 * Signal to the window system that the application has finished
5743 * handling Configure events it has received. Window Managers can
5744 * use this to better synchronize the frame repaint with the
5745 * application. GTK+ applications will automatically call this
5746 * function when appropriate.
5748 * This function can only be called if gdk_window_use_configure()
5749 * was called previously.
5754 gdk_window_configure_finished (GdkWindow *window)
5756 GdkWindowImplX11 *impl;
5758 g_return_if_fail (GDK_IS_WINDOW (window));
5760 impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
5761 if (!impl->use_synchronized_configure)
5765 if (!GDK_WINDOW_DESTROYED (window))
5767 GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
5768 GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
5770 if (toplevel && toplevel->update_counter != None &&
5771 GDK_DISPLAY_X11 (display)->use_sync &&
5772 !XSyncValueIsZero (toplevel->current_counter_value))
5774 XSyncSetCounter (GDK_WINDOW_XDISPLAY (window),
5775 toplevel->update_counter,
5776 toplevel->current_counter_value);
5778 XSyncIntToValue (&toplevel->current_counter_value, 0);