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>
37
#include "gdkwindow.h"
39
#include "gdkinputprivate.h"
40
#include "gdkdisplay-x11.h"
41
#include "gdkprivate-x11.h"
42
#include "gdkregion.h"
43
#include "gdkinternals.h"
45
#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_icon_name_set (GdkWindow *window);
87
static void gdk_window_add_colormap_windows (GdkWindow *window);
88
static void set_wm_name (GdkDisplay *display,
91
static void move_to_current_desktop (GdkWindow *window);
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_finalize (GObject *object);
102
#define WINDOW_IS_TOPLEVEL(window) \
103
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
104
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
106
/* Return whether time1 is considered later than time2 as far as xserver
107
* time is concerned. Accounts for wraparound.
109
#define XSERVER_TIME_IS_LATER(time1, time2) \
110
( (( time1 > time2 ) && ( time1 - time2 < ((guint32)-1)/2 )) || \
111
(( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
114
G_DEFINE_TYPE (GdkWindowImplX11, gdk_window_impl_x11, GDK_TYPE_DRAWABLE_IMPL_X11)
117
_gdk_window_impl_get_type (void)
119
return gdk_window_impl_x11_get_type ();
123
gdk_window_impl_x11_init (GdkWindowImplX11 *impl)
127
impl->toplevel_window_type = -1;
131
_gdk_x11_window_get_toplevel (GdkWindow *window)
133
GdkWindowObject *private;
134
GdkWindowImplX11 *impl;
136
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
138
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
141
private = (GdkWindowObject *)window;
142
impl = GDK_WINDOW_IMPL_X11 (private->impl);
145
impl->toplevel = g_new0 (GdkToplevelX11, 1);
147
return impl->toplevel;
151
gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass)
153
GObjectClass *object_class = G_OBJECT_CLASS (klass);
154
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
156
object_class->finalize = gdk_window_impl_x11_finalize;
158
drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
159
drawable_class->get_colormap = gdk_window_impl_x11_get_colormap;
160
drawable_class->get_size = gdk_window_impl_x11_get_size;
162
/* Visible and clip regions are the same */
163
drawable_class->get_clip_region = gdk_window_impl_x11_get_visible_region;
164
drawable_class->get_visible_region = gdk_window_impl_x11_get_visible_region;
168
gdk_window_impl_x11_finalize (GObject *object)
170
GdkWindowObject *wrapper;
171
GdkDrawableImplX11 *draw_impl;
172
GdkWindowImplX11 *window_impl;
174
g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (object));
176
draw_impl = GDK_DRAWABLE_IMPL_X11 (object);
177
window_impl = GDK_WINDOW_IMPL_X11 (object);
179
wrapper = (GdkWindowObject*) draw_impl->wrapper;
181
_gdk_xgrab_check_destroy (GDK_WINDOW (wrapper));
183
if (!GDK_WINDOW_DESTROYED (wrapper))
185
GdkDisplay *display = GDK_WINDOW_DISPLAY (wrapper);
187
_gdk_xid_table_remove (display, draw_impl->xid);
188
if (window_impl->toplevel && window_impl->toplevel->focus_window)
189
_gdk_xid_table_remove (display, window_impl->toplevel->focus_window);
192
if (window_impl->toplevel)
193
g_free (window_impl->toplevel);
195
if (window_impl->cursor)
196
gdk_cursor_unref (window_impl->cursor);
198
G_OBJECT_CLASS (gdk_window_impl_x11_parent_class)->finalize (object);
202
tmp_unset_bg (GdkWindow *window)
204
GdkWindowImplX11 *impl;
205
GdkWindowObject *obj;
207
obj = (GdkWindowObject *) window;
208
impl = GDK_WINDOW_IMPL_X11 (obj->impl);
210
/* For windows without EXPOSURE_MASK, we can't do this
211
* unsetting because such windows depend on the drawing
212
* that the X server is going to do
214
if (!(obj->event_mask & GDK_EXPOSURE_MASK))
217
impl->position_info.no_bg = TRUE;
219
if (obj->bg_pixmap != GDK_NO_BG)
220
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
221
GDK_DRAWABLE_XID (window), None);
225
tmp_reset_bg (GdkWindow *window)
227
GdkWindowImplX11 *impl;
228
GdkWindowObject *obj;
230
obj = (GdkWindowObject *) window;
231
impl = GDK_WINDOW_IMPL_X11 (obj->impl);
233
if (!(obj->event_mask & GDK_EXPOSURE_MASK))
236
impl->position_info.no_bg = FALSE;
238
if (obj->bg_pixmap == GDK_NO_BG)
245
if (obj->bg_pixmap == GDK_PARENT_RELATIVE_BG)
246
xpixmap = ParentRelative;
248
xpixmap = GDK_DRAWABLE_XID (obj->bg_pixmap);
250
XSetWindowBackgroundPixmap (GDK_DRAWABLE_XDISPLAY (window),
251
GDK_DRAWABLE_XID (window), xpixmap);
255
XSetWindowBackground (GDK_DRAWABLE_XDISPLAY (window),
256
GDK_DRAWABLE_XID (window),
257
obj->bg_color.pixel);
261
/* Unsetting and resetting window backgrounds.
263
* In many cases it is possible to avoid flicker by unsetting the
264
* background of windows. For example if the background of the
265
* parent window is unset when a window is unmapped, a brief flicker
266
* of background painting is avoided.
269
_gdk_x11_window_tmp_unset_bg (GdkWindow *window,
272
GdkWindowObject *private;
274
g_return_if_fail (GDK_IS_WINDOW (window));
276
private = (GdkWindowObject *)window;
278
if (private->input_only || private->destroyed ||
279
(private->window_type != GDK_WINDOW_ROOT &&
280
!GDK_WINDOW_IS_MAPPED (window)))
285
if (private->window_type != GDK_WINDOW_ROOT &&
286
private->window_type != GDK_WINDOW_FOREIGN)
288
tmp_unset_bg (window);
295
for (l = private->children; l != NULL; l = l->next)
296
_gdk_x11_window_tmp_unset_bg (l->data, TRUE);
301
_gdk_x11_window_tmp_reset_bg (GdkWindow *window,
304
GdkWindowObject *private;
306
g_return_if_fail (GDK_IS_WINDOW (window));
308
private = (GdkWindowObject *)window;
310
if (private->input_only || private->destroyed ||
311
(private->window_type != GDK_WINDOW_ROOT &&
312
!GDK_WINDOW_IS_MAPPED (window)))
317
if (private->window_type != GDK_WINDOW_ROOT &&
318
private->window_type != GDK_WINDOW_FOREIGN)
320
tmp_reset_bg (window);
327
for (l = private->children; l != NULL; l = l->next)
328
_gdk_x11_window_tmp_reset_bg (l->data, TRUE);
333
gdk_window_impl_x11_get_colormap (GdkDrawable *drawable)
335
GdkDrawableImplX11 *drawable_impl;
337
g_return_val_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable), NULL);
339
drawable_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
341
if (!((GdkWindowObject *) drawable_impl->wrapper)->input_only &&
342
drawable_impl->colormap == NULL)
344
XWindowAttributes window_attributes;
347
XGetWindowAttributes (GDK_SCREEN_XDISPLAY (drawable_impl->screen),
351
visual = gdk_x11_screen_lookup_visual (drawable_impl->screen,
352
window_attributes.visual->visualid);
353
drawable_impl->colormap = gdk_x11_colormap_foreign_new (visual,
354
window_attributes.colormap);
357
return drawable_impl->colormap;
361
gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
364
GdkDrawableImplX11 *draw_impl;
366
g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
368
draw_impl = GDK_DRAWABLE_IMPL_X11 (drawable);
370
if (cmap && GDK_WINDOW_DESTROYED (draw_impl->wrapper))
374
GDK_DRAWABLE_CLASS (gdk_window_impl_x11_parent_class)->set_colormap (drawable, cmap);
378
XSetWindowColormap (GDK_SCREEN_XDISPLAY (draw_impl->screen),
380
GDK_COLORMAP_XCOLORMAP (cmap));
382
if (((GdkWindowObject*)draw_impl->wrapper)->window_type !=
384
gdk_window_add_colormap_windows (GDK_WINDOW (draw_impl->wrapper));
390
gdk_window_impl_x11_get_size (GdkDrawable *drawable,
394
g_return_if_fail (GDK_IS_WINDOW_IMPL_X11 (drawable));
397
*width = GDK_WINDOW_IMPL_X11 (drawable)->width;
399
*height = GDK_WINDOW_IMPL_X11 (drawable)->height;
403
gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable)
405
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (drawable);
406
GdkRectangle result_rect;
410
result_rect.width = impl->width;
411
result_rect.height = impl->height;
413
gdk_rectangle_intersect (&result_rect, &impl->position_info.clip_rect, &result_rect);
415
return gdk_region_rectangle (&result_rect);
419
_gdk_windowing_window_init (GdkScreen * screen)
421
GdkWindowObject *private;
422
GdkWindowImplX11 *impl;
423
GdkDrawableImplX11 *draw_impl;
424
GdkScreenX11 *screen_x11;
426
screen_x11 = GDK_SCREEN_X11 (screen);
428
g_assert (screen_x11->root_window == NULL);
430
gdk_screen_set_default_colormap (screen,
431
gdk_screen_get_system_colormap (screen));
433
screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL);
434
private = (GdkWindowObject *)screen_x11->root_window;
435
impl = GDK_WINDOW_IMPL_X11 (private->impl);
436
draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
438
draw_impl->screen = screen;
439
draw_impl->xid = screen_x11->xroot_window;
440
draw_impl->wrapper = GDK_DRAWABLE (private);
441
draw_impl->colormap = gdk_screen_get_system_colormap (screen);
442
g_object_ref (draw_impl->colormap);
444
private->window_type = GDK_WINDOW_ROOT;
445
private->depth = DefaultDepthOfScreen (screen_x11->xscreen);
447
impl->width = WidthOfScreen (screen_x11->xscreen);
448
impl->height = HeightOfScreen (screen_x11->xscreen);
450
_gdk_window_init_position (GDK_WINDOW (private));
452
_gdk_xid_table_insert (screen_x11->display,
453
&screen_x11->xroot_window,
454
screen_x11->root_window);
458
set_wm_protocols (GdkWindow *window)
460
GdkDisplay *display = gdk_drawable_get_display (window);
464
protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_DELETE_WINDOW");
465
protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "WM_TAKE_FOCUS");
466
protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_PING");
469
if (GDK_DISPLAY_X11 (display)->use_sync)
470
protocols[n++] = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_SYNC_REQUEST");
473
XSetWMProtocols (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window), protocols, n);
477
get_default_title (void)
481
title = g_get_application_name ();
483
title = g_get_prgname ();
489
check_leader_window_title (GdkDisplay *display)
491
GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
493
if (display_x11->leader_window && !display_x11->leader_window_title_set)
495
set_wm_name (display,
496
display_x11->leader_window,
497
get_default_title ());
499
display_x11->leader_window_title_set = TRUE;
504
create_focus_window (Display *xdisplay,
507
Window focus_window = XCreateSimpleWindow (xdisplay, parent,
511
/* FIXME: probably better to actually track the requested event mask for the toplevel
513
XSelectInput (xdisplay, focus_window,
514
KeyPressMask | KeyReleaseMask | FocusChangeMask);
516
XMapWindow (xdisplay, focus_window);
522
ensure_sync_counter (GdkWindow *window)
525
if (!GDK_WINDOW_DESTROYED (window))
527
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
528
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
529
GdkWindowObject *private = (GdkWindowObject *)window;
530
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
532
if (toplevel && impl->use_synchronized_configure &&
533
toplevel->update_counter == None &&
534
GDK_DISPLAY_X11 (display)->use_sync)
536
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
540
XSyncIntToValue (&value, 0);
542
toplevel->update_counter = XSyncCreateCounter (xdisplay, value);
544
atom = gdk_x11_get_xatom_by_name_for_display (display,
545
"_NET_WM_SYNC_REQUEST_COUNTER");
547
XChangeProperty (xdisplay, GDK_WINDOW_XID (window),
550
(guchar *)&toplevel->update_counter, 1);
552
XSyncIntToValue (&toplevel->current_counter_value, 0);
559
setup_toplevel_window (GdkWindow *window,
562
GdkWindowObject *obj = (GdkWindowObject *)window;
563
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
564
GdkWindowImplX11 *impl = (GdkWindowImplX11 *)obj->impl;
565
Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
566
XID xid = GDK_WINDOW_XID (window);
567
XID xparent = GDK_WINDOW_XID (parent);
568
GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (GDK_WINDOW_SCREEN (parent));
569
XSizeHints size_hints;
571
Window leader_window;
573
if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_DIALOG)
574
XSetTransientForHint (xdisplay, xid, xparent);
576
set_wm_protocols (window);
578
if (!obj->input_only)
580
/* The focus window is off the visible area, and serves to receive key
581
* press events so they don't get sent to child windows.
583
toplevel->focus_window = create_focus_window (xdisplay, xid);
584
_gdk_xid_table_insert (screen_x11->display, &toplevel->focus_window, window);
587
check_leader_window_title (screen_x11->display);
589
/* FIXME: Is there any point in doing this? Do any WM's pay
590
* attention to PSize, and even if they do, is this the
593
size_hints.flags = PSize;
594
size_hints.width = impl->width;
595
size_hints.height = impl->height;
597
XSetWMNormalHints (xdisplay, xid, &size_hints);
599
/* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */
600
XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL);
603
XChangeProperty (xdisplay, xid,
604
gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "_NET_WM_PID"),
609
leader_window = GDK_DISPLAY_X11 (screen_x11->display)->leader_window;
612
XChangeProperty (xdisplay, xid,
613
gdk_x11_get_xatom_by_name_for_display (screen_x11->display, "WM_CLIENT_LEADER"),
614
XA_WINDOW, 32, PropModeReplace,
615
(guchar *) &leader_window, 1);
617
if (!obj->focus_on_map)
618
gdk_x11_window_set_user_time (window, 0);
619
else if (GDK_DISPLAY_X11 (screen_x11->display)->user_time != 0)
620
gdk_x11_window_set_user_time (window, GDK_DISPLAY_X11 (screen_x11->display)->user_time);
622
ensure_sync_counter (window);
627
* @parent: a #GdkWindow, or %NULL to create the window as a child of
628
* the default root window for the default display.
629
* @attributes: attributes of the new window
630
* @attributes_mask: mask indicating which fields in @attributes are valid
632
* Creates a new #GdkWindow using the attributes from
633
* @attributes. See #GdkWindowAttr and #GdkWindowAttributesType for
634
* more details. Note: to use this on displays other than the default
635
* display, @parent must be specified.
637
* Return value: the new #GdkWindow
640
gdk_window_new (GdkWindow *parent,
641
GdkWindowAttr *attributes,
642
gint attributes_mask)
645
GdkWindowObject *private;
646
GdkWindowImplX11 *impl;
647
GdkDrawableImplX11 *draw_impl;
648
GdkScreenX11 *screen_x11;
657
XSetWindowAttributes xattributes;
658
long xattributes_mask;
659
XClassHint *class_hint;
666
g_return_val_if_fail (attributes != NULL, NULL);
671
g_warning ("gdk_window_new(): no parent specified reverting to parent = default root window"));
673
screen = gdk_screen_get_default ();
674
parent = gdk_screen_get_root_window (screen);
677
screen = gdk_drawable_get_screen (parent);
679
screen_x11 = GDK_SCREEN_X11 (screen);
681
g_return_val_if_fail (GDK_IS_WINDOW (parent), NULL);
683
if (GDK_WINDOW_DESTROYED (parent))
686
xparent = GDK_WINDOW_XID (parent);
688
window = g_object_new (GDK_TYPE_WINDOW, NULL);
689
private = (GdkWindowObject *)window;
690
impl = GDK_WINDOW_IMPL_X11 (private->impl);
691
draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
692
draw_impl->wrapper = GDK_DRAWABLE (window);
694
draw_impl->screen = screen;
695
xdisplay = screen_x11->xdisplay;
697
/* Windows with a foreign parent are treated as if they are children
698
* of the root window, except for actual creation.
700
if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_FOREIGN)
701
parent = gdk_screen_get_root_window (screen);
703
private->parent = (GdkWindowObject *)parent;
705
private->accept_focus = TRUE;
706
private->focus_on_map = TRUE;
708
xattributes_mask = 0;
710
if (attributes_mask & GDK_WA_X)
715
if (attributes_mask & GDK_WA_Y)
722
impl->width = (attributes->width > 1) ? (attributes->width) : (1);
723
impl->height = (attributes->height > 1) ? (attributes->height) : (1);
725
if (attributes->wclass == GDK_INPUT_ONLY)
727
/* Backwards compatiblity - we've always ignored
728
* attributes->window_type for input-only windows
731
if (GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT)
732
private->window_type = GDK_WINDOW_TEMP;
734
private->window_type = GDK_WINDOW_CHILD;
737
private->window_type = attributes->window_type;
739
/* Work around a bug where Xorg refuses to map toplevel InputOnly windows
740
* from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
742
if (attributes->wclass == GDK_INPUT_ONLY &&
743
GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT &&
744
!G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
746
g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
747
attributes->wclass = GDK_INPUT_OUTPUT;
750
_gdk_window_init_position (GDK_WINDOW (private));
751
if (impl->position_info.big)
752
private->guffaw_gravity = TRUE;
754
if (attributes_mask & GDK_WA_VISUAL)
755
visual = attributes->visual;
757
visual = gdk_screen_get_system_visual (screen);
758
xvisual = ((GdkVisualPrivate*) visual)->xvisual;
760
xattributes.event_mask = StructureNotifyMask | PropertyChangeMask;
761
for (i = 0; i < _gdk_nenvent_masks; i++)
763
if (attributes->event_mask & (1 << (i + 1)))
764
xattributes.event_mask |= _gdk_event_mask_table[i];
766
private->event_mask = attributes->event_mask;
768
if (xattributes.event_mask)
769
xattributes_mask |= CWEventMask;
771
if (attributes_mask & GDK_WA_NOREDIR)
773
xattributes.override_redirect =
774
(attributes->override_redirect == FALSE)?False:True;
775
xattributes_mask |= CWOverrideRedirect;
778
xattributes.override_redirect = False;
780
impl->override_redirect = xattributes.override_redirect;
782
if (private->parent && private->parent->guffaw_gravity)
784
xattributes.win_gravity = StaticGravity;
785
xattributes_mask |= CWWinGravity;
789
switch (private->window_type)
791
case GDK_WINDOW_TOPLEVEL:
792
case GDK_WINDOW_DIALOG:
793
case GDK_WINDOW_TEMP:
794
if (GDK_WINDOW_TYPE (parent) != GDK_WINDOW_ROOT)
796
g_warning (G_STRLOC "Toplevel windows must be created as children of\n"
797
"of a window of type GDK_WINDOW_ROOT or GDK_WINDOW_FOREIGN");
798
xparent = GDK_SCREEN_XROOTWIN (screen);
800
case GDK_WINDOW_CHILD:
803
g_warning (G_STRLOC "cannot make windows of type %d", private->window_type);
807
if (attributes->wclass == GDK_INPUT_OUTPUT)
810
depth = visual->depth;
812
private->input_only = FALSE;
813
private->depth = depth;
815
if (attributes_mask & GDK_WA_COLORMAP)
817
draw_impl->colormap = attributes->colormap;
818
g_object_ref (attributes->colormap);
822
if ((((GdkVisualPrivate *)gdk_screen_get_system_visual (screen))->xvisual) == xvisual)
824
draw_impl->colormap = gdk_screen_get_system_colormap (screen);
825
g_object_ref (draw_impl->colormap);
829
draw_impl->colormap = gdk_colormap_new (visual, FALSE);
833
private->bg_color.pixel = BlackPixel (xdisplay, screen_x11->screen_num);
834
private->bg_color.red = private->bg_color.green = private->bg_color.blue = 0;
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);
926
if (attributes_mask & GDK_WA_TYPE_HINT)
927
gdk_window_set_type_hint (window, attributes->type_hint);
933
x_event_mask_to_gdk_event_mask (long mask)
935
GdkEventMask event_mask = 0;
938
for (i = 0; i < _gdk_nenvent_masks; i++)
940
if (mask & _gdk_event_mask_table[i])
941
event_mask |= 1 << (i + 1);
948
* gdk_window_foreign_new_for_display:
949
* @display: the #GdkDisplay where the window handle comes from.
950
* @anid: a native window handle.
952
* Wraps a native window in a #GdkWindow.
953
* This may fail if the window has been destroyed. If the window
954
* was already known to GDK, a new reference to the existing
955
* #GdkWindow is returned.
957
* For example in the X backend, a native window handle is an Xlib
960
* Return value: a #GdkWindow wrapper for the native window or
961
* %NULL if the window has been destroyed. The wrapper will be
962
* newly created, if one doesn't exist already.
967
gdk_window_foreign_new_for_display (GdkDisplay *display,
968
GdkNativeWindow anid)
971
GdkWindowObject *private;
972
GdkWindowImplX11 *impl;
973
GdkDrawableImplX11 *draw_impl;
974
GdkDisplayX11 *display_x11;
975
XWindowAttributes attrs;
977
Window *children = NULL;
981
g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
983
display_x11 = GDK_DISPLAY_X11 (display);
985
if ((window = gdk_xid_table_lookup_for_display (display, anid)) != NULL)
986
return g_object_ref (window);
988
gdk_error_trap_push ();
989
result = XGetWindowAttributes (display_x11->xdisplay, anid, &attrs);
990
if (gdk_error_trap_pop () || !result)
993
/* FIXME: This is pretty expensive. Maybe the caller should supply
995
gdk_error_trap_push ();
996
result = XQueryTree (display_x11->xdisplay, anid, &root, &parent, &children, &nchildren);
997
if (gdk_error_trap_pop () || !result)
1003
window = g_object_new (GDK_TYPE_WINDOW, NULL);
1004
private = (GdkWindowObject *)window;
1005
impl = GDK_WINDOW_IMPL_X11 (private->impl);
1006
draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl);
1007
draw_impl->wrapper = GDK_DRAWABLE (window);
1008
draw_impl->screen = _gdk_x11_display_screen_for_xrootwin (display, root);
1010
private->parent = gdk_xid_table_lookup_for_display (display, parent);
1012
if (!private->parent || GDK_WINDOW_TYPE (private->parent) == GDK_WINDOW_FOREIGN)
1013
private->parent = (GdkWindowObject *) gdk_screen_get_root_window (draw_impl->screen);
1015
private->parent->children = g_list_prepend (private->parent->children, window);
1017
draw_impl->xid = anid;
1019
private->x = attrs.x;
1020
private->y = attrs.y;
1021
impl->width = attrs.width;
1022
impl->height = attrs.height;
1023
private->window_type = GDK_WINDOW_FOREIGN;
1024
private->destroyed = FALSE;
1026
private->event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
1028
if (attrs.map_state == IsUnmapped)
1029
private->state = GDK_WINDOW_STATE_WITHDRAWN;
1033
private->depth = attrs.depth;
1035
_gdk_window_init_position (GDK_WINDOW (private));
1037
g_object_ref (window);
1038
_gdk_xid_table_insert (display, &GDK_WINDOW_XID (window), window);
1043
* gdk_window_lookup_for_display:
1044
* @display: the #GdkDisplay corresponding to the window handle
1045
* @anid: a native window handle.
1047
* Looks up the #GdkWindow that wraps the given native window handle.
1049
* For example in the X backend, a native window handle is an Xlib
1052
* Return value: the #GdkWindow wrapper for the native window,
1053
* or %NULL if there is none.
1058
gdk_window_lookup_for_display (GdkDisplay *display, GdkNativeWindow anid)
1060
return (GdkWindow*) gdk_xid_table_lookup_for_display (display, anid);
1064
* gdk_window_lookup:
1065
* @anid: a native window handle.
1067
* Looks up the #GdkWindow that wraps the given native window handle.
1069
* For example in the X backend, a native window handle is an Xlib
1072
* Return value: the #GdkWindow wrapper for the native window,
1073
* or %NULL if there is none.
1076
gdk_window_lookup (GdkNativeWindow anid)
1078
return (GdkWindow*) gdk_xid_table_lookup (anid);
1082
gdk_toplevel_x11_free_contents (GdkDisplay *display,
1083
GdkToplevelX11 *toplevel)
1085
if (toplevel->icon_window)
1087
g_object_unref (toplevel->icon_window);
1088
toplevel->icon_window = NULL;
1090
if (toplevel->icon_pixmap)
1092
g_object_unref (toplevel->icon_pixmap);
1093
toplevel->icon_pixmap = NULL;
1095
if (toplevel->icon_mask)
1097
g_object_unref (toplevel->icon_mask);
1098
toplevel->icon_mask = NULL;
1100
if (toplevel->group_leader)
1102
g_object_unref (toplevel->group_leader);
1103
toplevel->group_leader = NULL;
1106
if (toplevel->update_counter != None)
1108
XSyncDestroyCounter (GDK_DISPLAY_XDISPLAY (display),
1109
toplevel->update_counter);
1110
toplevel->update_counter = None;
1112
XSyncIntToValue (&toplevel->current_counter_value, 0);
1118
_gdk_windowing_window_destroy (GdkWindow *window,
1120
gboolean foreign_destroy)
1122
GdkWindowObject *private = (GdkWindowObject *)window;
1123
GdkToplevelX11 *toplevel;
1125
g_return_if_fail (GDK_IS_WINDOW (window));
1127
_gdk_selection_window_destroyed (window);
1129
if (private->extension_events != 0)
1130
_gdk_input_window_destroy (window);
1132
toplevel = _gdk_x11_window_get_toplevel (window);
1134
gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window), toplevel);
1136
_gdk_x11_drawable_finish (private->impl);
1138
if (!recursing && !foreign_destroy)
1140
XDestroyWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1145
_gdk_windowing_window_destroy_foreign (GdkWindow *window)
1147
/* It's somebody else's window, but in our heirarchy,
1148
* so reparent it to the root window, and then send
1149
* it a delete event, as if we were a WM
1151
XClientMessageEvent xclient;
1153
gdk_error_trap_push ();
1154
gdk_window_hide (window);
1155
gdk_window_reparent (window, NULL, 0, 0);
1157
memset (&xclient, 0, sizeof (xclient));
1158
xclient.type = ClientMessage;
1159
xclient.window = GDK_WINDOW_XID (window);
1160
xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
1162
xclient.format = 32;
1163
xclient.data.l[0] = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
1164
"WM_DELETE_WINDOW");
1165
xclient.data.l[1] = CurrentTime;
1166
xclient.data.l[2] = 0;
1167
xclient.data.l[3] = 0;
1168
xclient.data.l[4] = 0;
1170
XSendEvent (GDK_WINDOW_XDISPLAY (window),
1171
GDK_WINDOW_XID (window),
1172
False, 0, (XEvent *)&xclient);
1173
gdk_display_sync (GDK_WINDOW_DISPLAY (window));
1174
gdk_error_trap_pop ();
1178
get_root (GdkWindow *window)
1180
GdkScreen *screen = gdk_drawable_get_screen (window);
1182
return gdk_screen_get_root_window (screen);
1185
/* This function is called when the XWindow is really gone.
1188
gdk_window_destroy_notify (GdkWindow *window)
1190
GdkWindowImplX11 *window_impl;
1192
g_return_if_fail (GDK_IS_WINDOW (window));
1194
window_impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
1196
if (!GDK_WINDOW_DESTROYED (window))
1198
if (GDK_WINDOW_TYPE(window) != GDK_WINDOW_FOREIGN)
1199
g_warning ("GdkWindow %#lx unexpectedly destroyed", GDK_WINDOW_XID (window));
1201
_gdk_window_destroy (window, TRUE);
1204
_gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), GDK_WINDOW_XID (window));
1205
if (window_impl->toplevel && window_impl->toplevel->focus_window)
1206
_gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), window_impl->toplevel->focus_window);
1208
_gdk_xgrab_check_destroy (window);
1210
g_object_unref (window);
1214
update_wm_hints (GdkWindow *window,
1217
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
1218
GdkWindowObject *private = (GdkWindowObject *)window;
1219
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1223
!toplevel->is_leader &&
1224
private->state & GDK_WINDOW_STATE_WITHDRAWN)
1227
wm_hints.flags = StateHint | InputHint;
1228
wm_hints.input = private->accept_focus ? True : False;
1229
wm_hints.initial_state = NormalState;
1231
if (private->state & GDK_WINDOW_STATE_ICONIFIED)
1233
wm_hints.flags |= StateHint;
1234
wm_hints.initial_state = IconicState;
1237
if (toplevel->icon_window && !GDK_WINDOW_DESTROYED (toplevel->icon_window))
1239
wm_hints.flags |= IconWindowHint;
1240
wm_hints.icon_window = GDK_WINDOW_XID (toplevel->icon_window);
1243
if (toplevel->icon_pixmap)
1245
wm_hints.flags |= IconPixmapHint;
1246
wm_hints.icon_pixmap = GDK_PIXMAP_XID (toplevel->icon_pixmap);
1249
if (toplevel->icon_mask)
1251
wm_hints.flags |= IconMaskHint;
1252
wm_hints.icon_mask = GDK_PIXMAP_XID (toplevel->icon_mask);
1255
wm_hints.flags |= WindowGroupHint;
1256
if (toplevel->group_leader && !GDK_WINDOW_DESTROYED (toplevel->group_leader))
1258
wm_hints.flags |= WindowGroupHint;
1259
wm_hints.window_group = GDK_WINDOW_XID (toplevel->group_leader);
1262
wm_hints.window_group = GDK_DISPLAY_X11 (display)->leader_window;
1264
if (toplevel->urgency_hint)
1265
wm_hints.flags |= XUrgencyHint;
1267
XSetWMHints (GDK_WINDOW_XDISPLAY (window),
1268
GDK_WINDOW_XID (window),
1273
set_initial_hints (GdkWindow *window)
1275
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
1276
Display *xdisplay = GDK_DISPLAY_XDISPLAY (display);
1277
Window xwindow = GDK_WINDOW_XID (window);
1278
GdkWindowObject *private;
1279
GdkToplevelX11 *toplevel;
1283
private = (GdkWindowObject*) window;
1284
toplevel = _gdk_x11_window_get_toplevel (window);
1289
update_wm_hints (window, TRUE);
1291
/* We set the spec hints regardless of whether the spec is supported,
1292
* since it can't hurt and it's kind of expensive to check whether
1298
if (private->state & GDK_WINDOW_STATE_MAXIMIZED)
1300
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1301
"_NET_WM_STATE_MAXIMIZED_VERT");
1303
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1304
"_NET_WM_STATE_MAXIMIZED_HORZ");
1308
if (private->state & GDK_WINDOW_STATE_ABOVE)
1310
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1311
"_NET_WM_STATE_ABOVE");
1315
if (private->state & GDK_WINDOW_STATE_BELOW)
1317
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1318
"_NET_WM_STATE_BELOW");
1322
if (private->state & GDK_WINDOW_STATE_STICKY)
1324
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1325
"_NET_WM_STATE_STICKY");
1329
if (private->state & GDK_WINDOW_STATE_FULLSCREEN)
1331
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1332
"_NET_WM_STATE_FULLSCREEN");
1336
if (private->modal_hint)
1338
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1339
"_NET_WM_STATE_MODAL");
1343
if (toplevel->skip_taskbar_hint)
1345
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1346
"_NET_WM_STATE_SKIP_TASKBAR");
1350
if (toplevel->skip_pager_hint)
1352
atoms[i] = gdk_x11_get_xatom_by_name_for_display (display,
1353
"_NET_WM_STATE_SKIP_PAGER");
1359
XChangeProperty (xdisplay,
1361
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"),
1362
XA_ATOM, 32, PropModeReplace,
1363
(guchar*) atoms, i);
1367
XDeleteProperty (xdisplay,
1369
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE"));
1372
if (private->state & GDK_WINDOW_STATE_STICKY)
1374
atoms[0] = 0xFFFFFFFF;
1375
XChangeProperty (xdisplay,
1377
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"),
1378
XA_CARDINAL, 32, PropModeReplace,
1379
(guchar*) atoms, 1);
1383
XDeleteProperty (xdisplay,
1385
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP"));
1388
toplevel->map_serial = NextRequest (xdisplay);
1392
show_window_internal (GdkWindow *window,
1395
GdkWindowObject *private;
1396
GdkDisplay *display;
1397
GdkDisplayX11 *display_x11;
1398
GdkToplevelX11 *toplevel;
1400
g_return_if_fail (GDK_IS_WINDOW (window));
1402
private = (GdkWindowObject*) window;
1403
if (!private->destroyed)
1405
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1406
Display *xdisplay = GDK_WINDOW_XDISPLAY (window);
1407
Window xwindow = GDK_WINDOW_XID (window);
1410
XRaiseWindow (xdisplay, xwindow);
1412
if (!GDK_WINDOW_IS_MAPPED (window))
1414
set_initial_hints (window);
1416
gdk_synthesize_window_state (window,
1417
GDK_WINDOW_STATE_WITHDRAWN,
1421
g_assert (GDK_WINDOW_IS_MAPPED (window));
1423
if (WINDOW_IS_TOPLEVEL (window))
1425
display = gdk_drawable_get_display (window);
1426
display_x11 = GDK_DISPLAY_X11 (display);
1427
toplevel = _gdk_x11_window_get_toplevel (window);
1429
if (toplevel->user_time != 0 &&
1430
display_x11->user_time != 0 &&
1431
XSERVER_TIME_IS_LATER (display_x11->user_time, toplevel->user_time))
1432
gdk_x11_window_set_user_time (window, display_x11->user_time);
1435
if (impl->position_info.mapped)
1437
gboolean unset_bg = !private->input_only &&
1438
(private->window_type == GDK_WINDOW_CHILD ||
1439
impl->override_redirect) &&
1440
gdk_window_is_viewable (window);
1443
_gdk_x11_window_tmp_unset_bg (window, TRUE);
1445
XMapWindow (xdisplay, xwindow);
1449
_gdk_x11_window_tmp_reset_bg (window, TRUE);
1450
gdk_window_invalidate_rect (window, NULL, TRUE);
1457
* gdk_window_show_unraised:
1458
* @window: a #GdkWindow
1460
* Shows a #GdkWindow onscreen, but does not modify its stacking
1461
* order. In contrast, gdk_window_show() will raise the window
1462
* to the top of the window stack.
1464
* On the X11 platform, in Xlib terms, this function calls
1465
* XMapWindow() (it also updates some internal GDK state, which means
1466
* that you can't really use XMapWindow() directly on a GDK window).
1470
gdk_window_show_unraised (GdkWindow *window)
1472
g_return_if_fail (GDK_IS_WINDOW (window));
1474
show_window_internal (window, FALSE);
1479
* @window: a #GdkWindow
1481
* Like gdk_window_show_unraised(), but also raises the window to the
1482
* top of the window stack (moves the window to the front of the
1485
* This function maps a window so it's visible onscreen. Its opposite
1486
* is gdk_window_hide().
1488
* When implementing a #GtkWidget, you should call this function on the widget's
1489
* #GdkWindow as part of the "map" method.
1493
gdk_window_show (GdkWindow *window)
1495
g_return_if_fail (GDK_IS_WINDOW (window));
1497
show_window_internal (window, TRUE);
1501
pre_unmap (GdkWindow *window)
1503
GdkWindow *start_window = NULL;
1504
GdkWindowObject *private = (GdkWindowObject *)window;
1506
if (private->input_only)
1509
if (private->window_type == GDK_WINDOW_CHILD)
1510
start_window = (GdkWindow *)private->parent;
1511
else if (private->window_type == GDK_WINDOW_TEMP)
1512
start_window = get_root (window);
1515
_gdk_x11_window_tmp_unset_bg (start_window, TRUE);
1519
post_unmap (GdkWindow *window)
1521
GdkWindow *start_window = NULL;
1522
GdkWindowObject *private = (GdkWindowObject *)window;
1524
if (private->input_only)
1527
if (private->window_type == GDK_WINDOW_CHILD)
1528
start_window = (GdkWindow *)private->parent;
1529
else if (private->window_type == GDK_WINDOW_TEMP)
1530
start_window = get_root (window);
1534
_gdk_x11_window_tmp_reset_bg (start_window, TRUE);
1536
if (private->window_type == GDK_WINDOW_CHILD && private->parent)
1538
GdkRectangle invalid_rect;
1540
gdk_window_get_position (window, &invalid_rect.x, &invalid_rect.y);
1541
gdk_drawable_get_size (GDK_DRAWABLE (window),
1542
&invalid_rect.width, &invalid_rect.height);
1543
gdk_window_invalidate_rect ((GdkWindow *)private->parent,
1544
&invalid_rect, TRUE);
1551
* @window: a #GdkWindow
1553
* For toplevel windows, withdraws them, so they will no longer be
1554
* known to the window manager; for all windows, unmaps them, so
1555
* they won't be displayed. Normally done automatically as
1556
* part of gtk_widget_hide().
1560
gdk_window_hide (GdkWindow *window)
1562
GdkWindowObject *private;
1564
g_return_if_fail (GDK_IS_WINDOW (window));
1566
private = (GdkWindowObject*) window;
1568
/* We'll get the unmap notify eventually, and handle it then,
1569
* but checking here makes things more consistent if we are
1570
* just doing stuff ourself.
1572
_gdk_xgrab_check_unmap (window,
1573
NextRequest (GDK_WINDOW_XDISPLAY (window)));
1575
/* You can't simply unmap toplevel windows. */
1576
switch (private->window_type)
1578
case GDK_WINDOW_TOPLEVEL:
1579
case GDK_WINDOW_DIALOG:
1580
case GDK_WINDOW_TEMP: /* ? */
1581
gdk_window_withdraw (window);
1585
case GDK_WINDOW_FOREIGN:
1586
case GDK_WINDOW_ROOT:
1587
case GDK_WINDOW_CHILD:
1591
if (!private->destroyed)
1593
if (GDK_WINDOW_IS_MAPPED (window))
1594
gdk_synthesize_window_state (window,
1596
GDK_WINDOW_STATE_WITHDRAWN);
1598
g_assert (!GDK_WINDOW_IS_MAPPED (window));
1600
_gdk_window_clear_update_area (window);
1604
XUnmapWindow (GDK_WINDOW_XDISPLAY (window),
1605
GDK_WINDOW_XID (window));
1607
post_unmap (window);
1612
* gdk_window_withdraw:
1613
* @window: a toplevel #GdkWindow
1615
* Withdraws a window (unmaps it and asks the window manager to forget about it).
1616
* This function is not really useful as gdk_window_hide() automatically
1617
* withdraws toplevel windows before hiding them.
1621
gdk_window_withdraw (GdkWindow *window)
1623
GdkWindowObject *private;
1625
g_return_if_fail (GDK_IS_WINDOW (window));
1627
private = (GdkWindowObject*) window;
1628
if (!private->destroyed)
1630
if (GDK_WINDOW_IS_MAPPED (window))
1631
gdk_synthesize_window_state (window,
1633
GDK_WINDOW_STATE_WITHDRAWN);
1635
g_assert (!GDK_WINDOW_IS_MAPPED (window));
1639
XWithdrawWindow (GDK_WINDOW_XDISPLAY (window),
1640
GDK_WINDOW_XID (window), 0);
1642
post_unmap (window);
1648
* @window: a #GdkWindow
1649
* @x: X coordinate relative to window's parent
1650
* @y: Y coordinate relative to window's parent
1652
* Repositions a window relative to its parent window.
1653
* For toplevel windows, window managers may ignore or modify the move;
1654
* you should probably use gtk_window_move() on a #GtkWindow widget
1655
* anyway, instead of using GDK functions. For child windows,
1656
* the move will reliably succeed.
1658
* If you're also planning to resize the window, use gdk_window_move_resize()
1659
* to both move and resize simultaneously, for a nicer visual effect.
1662
gdk_window_move (GdkWindow *window,
1666
GdkWindowObject *private = (GdkWindowObject *)window;
1667
GdkWindowImplX11 *impl;
1669
g_return_if_fail (GDK_IS_WINDOW (window));
1671
impl = GDK_WINDOW_IMPL_X11 (private->impl);
1673
if (!GDK_WINDOW_DESTROYED (window))
1675
if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1677
_gdk_window_move_resize_child (window, x, y,
1678
impl->width, impl->height);
1682
XMoveWindow (GDK_WINDOW_XDISPLAY (window),
1683
GDK_WINDOW_XID (window),
1686
if (impl->override_redirect)
1696
* gdk_window_resize:
1697
* @window: a #GdkWindow
1698
* @width: new width of the window
1699
* @height: new height of the window
1701
* Resizes @window; for toplevel windows, asks the window manager to resize
1702
* the window. The window manager may not allow the resize. When using GTK+,
1703
* use gtk_window_resize() instead of this low-level GDK function.
1705
* Windows may not be resized below 1x1.
1707
* If you're also planning to move the window, use gdk_window_move_resize()
1708
* to both move and resize simultaneously, for a nicer visual effect.
1711
gdk_window_resize (GdkWindow *window,
1715
GdkWindowObject *private;
1717
g_return_if_fail (GDK_IS_WINDOW (window));
1724
private = (GdkWindowObject*) window;
1726
if (!GDK_WINDOW_DESTROYED (window))
1728
if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1730
_gdk_window_move_resize_child (window, private->x, private->y,
1732
_gdk_x11_drawable_update_size (private->impl);
1736
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1738
XResizeWindow (GDK_WINDOW_XDISPLAY (window),
1739
GDK_WINDOW_XID (window),
1742
if (impl->override_redirect)
1744
impl->width = width;
1745
impl->height = height;
1746
_gdk_x11_drawable_update_size (private->impl);
1750
if (width != impl->width || height != impl->height)
1751
private->resize_count += 1;
1755
_gdk_x11_drawable_update_size (private->impl);
1760
* gdk_window_move_resize:
1761
* @window: a #GdkWindow
1762
* @x: new X position relative to window's parent
1763
* @y: new Y position relative to window's parent
1765
* @height: new height
1767
* Equivalent to calling gdk_window_move() and gdk_window_resize(),
1768
* except that both operations are performed at once, avoiding strange
1769
* visual effects. (i.e. the user may be able to see the window first
1770
* move, then resize, if you don't use gdk_window_move_resize().)
1773
gdk_window_move_resize (GdkWindow *window,
1779
GdkWindowObject *private;
1781
g_return_if_fail (GDK_IS_WINDOW (window));
1788
private = (GdkWindowObject*) window;
1790
if (!GDK_WINDOW_DESTROYED (window))
1792
if (GDK_WINDOW_TYPE (private) == GDK_WINDOW_CHILD)
1794
_gdk_window_move_resize_child (window, x, y, width, height);
1795
_gdk_x11_drawable_update_size (private->impl);
1799
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
1801
XMoveResizeWindow (GDK_WINDOW_XDISPLAY (window),
1802
GDK_WINDOW_XID (window),
1803
x, y, width, height);
1804
if (impl->override_redirect)
1808
impl->width = width;
1809
impl->height = height;
1811
_gdk_x11_drawable_update_size (private->impl);
1815
if (width != impl->width || height != impl->height)
1816
private->resize_count += 1;
1823
* gdk_window_reparent:
1824
* @window: a #GdkWindow
1825
* @new_parent: new parent to move @window into
1826
* @x: X location inside the new parent
1827
* @y: Y location inside the new parent
1829
* Reparents @window into the given @new_parent. The window being
1830
* reparented will be unmapped as a side effect.
1834
gdk_window_reparent (GdkWindow *window,
1835
GdkWindow *new_parent,
1839
GdkWindowObject *window_private;
1840
GdkWindowObject *parent_private;
1841
GdkWindowObject *old_parent_private;
1842
GdkWindowImplX11 *impl;
1843
gboolean was_toplevel;
1845
g_return_if_fail (GDK_IS_WINDOW (window));
1846
g_return_if_fail (new_parent == NULL || GDK_IS_WINDOW (new_parent));
1847
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_ROOT);
1849
if (GDK_WINDOW_DESTROYED (window) ||
1850
(new_parent && GDK_WINDOW_DESTROYED (new_parent)))
1856
new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1858
window_private = (GdkWindowObject*) window;
1859
old_parent_private = (GdkWindowObject*)window_private->parent;
1860
parent_private = (GdkWindowObject*) new_parent;
1861
impl = GDK_WINDOW_IMPL_X11 (window_private->impl);
1863
XReparentWindow (GDK_WINDOW_XDISPLAY (window),
1864
GDK_WINDOW_XID (window),
1865
GDK_WINDOW_XID (new_parent),
1868
window_private->x = x;
1869
window_private->y = y;
1871
/* From here on, we treat parents of type GDK_WINDOW_FOREIGN like
1874
if (GDK_WINDOW_TYPE (new_parent) == GDK_WINDOW_FOREIGN)
1875
new_parent = gdk_screen_get_root_window (GDK_WINDOW_SCREEN (window));
1877
window_private->parent = (GdkWindowObject *)new_parent;
1879
/* Switch the window type as appropriate */
1881
switch (GDK_WINDOW_TYPE (new_parent))
1883
case GDK_WINDOW_ROOT:
1884
case GDK_WINDOW_FOREIGN:
1885
was_toplevel = WINDOW_IS_TOPLEVEL (window);
1887
if (impl->toplevel_window_type != -1)
1888
GDK_WINDOW_TYPE (window) = impl->toplevel_window_type;
1889
else if (GDK_WINDOW_TYPE (window) == GDK_WINDOW_CHILD)
1890
GDK_WINDOW_TYPE (window) = GDK_WINDOW_TOPLEVEL;
1892
if (WINDOW_IS_TOPLEVEL (window) && !was_toplevel)
1893
setup_toplevel_window (window, new_parent);
1895
case GDK_WINDOW_TOPLEVEL:
1896
case GDK_WINDOW_CHILD:
1897
case GDK_WINDOW_DIALOG:
1898
case GDK_WINDOW_TEMP:
1899
if (WINDOW_IS_TOPLEVEL (window))
1901
/* Save the original window type so we can restore it if the
1902
* window is reparented back to be a toplevel
1904
impl->toplevel_window_type = GDK_WINDOW_TYPE (window);
1905
GDK_WINDOW_TYPE (window) = GDK_WINDOW_CHILD;
1908
if (impl->toplevel->focus_window)
1910
XDestroyWindow (GDK_WINDOW_XDISPLAY (window), impl->toplevel->focus_window);
1911
_gdk_xid_table_remove (GDK_WINDOW_DISPLAY (window), impl->toplevel->focus_window);
1914
gdk_toplevel_x11_free_contents (GDK_WINDOW_DISPLAY (window),
1916
g_free (impl->toplevel);
1917
impl->toplevel = NULL;
1922
if (old_parent_private)
1923
old_parent_private->children = g_list_remove (old_parent_private->children, window);
1925
if ((old_parent_private &&
1926
(!old_parent_private->guffaw_gravity != !parent_private->guffaw_gravity)) ||
1927
(!old_parent_private && parent_private->guffaw_gravity))
1928
gdk_window_set_static_win_gravity (window, parent_private->guffaw_gravity);
1930
parent_private->children = g_list_prepend (parent_private->children, window);
1931
_gdk_window_init_position (GDK_WINDOW (window_private));
1935
_gdk_windowing_window_clear_area (GdkWindow *window,
1941
g_return_if_fail (GDK_IS_WINDOW (window));
1943
if (!GDK_WINDOW_DESTROYED (window))
1944
XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1945
x, y, width, height, False);
1949
_gdk_windowing_window_clear_area_e (GdkWindow *window,
1955
g_return_if_fail (GDK_IS_WINDOW (window));
1957
if (!GDK_WINDOW_DESTROYED (window))
1958
XClearArea (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
1959
x, y, width, height, True);
1965
* @window: a #GdkWindow
1967
* Raises @window to the top of the Z-order (stacking order), so that
1968
* other windows with the same parent window appear below @window.
1969
* This is true whether or not the windows are visible.
1971
* If @window is a toplevel, the window manager may choose to deny the
1972
* request to move the window in the Z-order, gdk_window_raise() only
1973
* requests the restack, does not guarantee it.
1977
gdk_window_raise (GdkWindow *window)
1979
g_return_if_fail (GDK_IS_WINDOW (window));
1981
if (!GDK_WINDOW_DESTROYED (window))
1982
XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
1987
* @window: a #GdkWindow
1989
* Lowers @window to the bottom of the Z-order (stacking order), so that
1990
* other windows with the same parent window appear above @window.
1991
* This is true whether or not the other windows are visible.
1993
* If @window is a toplevel, the window manager may choose to deny the
1994
* request to move the window in the Z-order, gdk_window_lower() only
1995
* requests the restack, does not guarantee it.
1997
* Note that gdk_window_show() raises the window again, so don't call this
1998
* function before gdk_window_show(). (Try gdk_window_show_unraised().)
2002
gdk_window_lower (GdkWindow *window)
2004
g_return_if_fail (GDK_IS_WINDOW (window));
2006
if (!GDK_WINDOW_DESTROYED (window))
2007
XLowerWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window));
2011
* gdk_x11_window_move_to_current_desktop:
2012
* @window: a #GdkWindow
2014
* Moves the window to the correct workspace when running under a
2015
* window manager that supports multiple workspaces, as described
2016
* in the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
2017
* Window Manager Hints</ulink>. Will not do anything if the
2018
* window is already on all workspaces.
2023
gdk_x11_window_move_to_current_desktop (GdkWindow *window)
2025
GdkToplevelX11 *toplevel;
2027
g_return_if_fail (GDK_IS_WINDOW (window));
2028
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2030
toplevel = _gdk_x11_window_get_toplevel (window);
2032
if (toplevel->on_all_desktops)
2035
move_to_current_desktop (window);
2039
move_to_current_desktop (GdkWindow *window)
2041
if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
2042
gdk_atom_intern_static_string ("_NET_WM_DESKTOP")))
2049
gulong *current_desktop;
2050
GdkDisplay *display;
2052
display = gdk_drawable_get_display (window);
2054
/* Get current desktop, then set it; this is a race, but not
2055
* one that matters much in practice.
2057
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
2058
GDK_WINDOW_XROOTWIN (window),
2059
gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
2061
False, XA_CARDINAL, &type, &format, &nitems,
2062
&bytes_after, &data);
2064
if (type == XA_CARDINAL)
2066
XClientMessageEvent xclient;
2067
current_desktop = (gulong *)data;
2069
memset (&xclient, 0, sizeof (xclient));
2070
xclient.type = ClientMessage;
2072
xclient.send_event = True;
2073
xclient.window = GDK_WINDOW_XWINDOW (window);
2074
xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_DESKTOP");
2075
xclient.format = 32;
2077
xclient.data.l[0] = *current_desktop;
2078
xclient.data.l[1] = 0;
2079
xclient.data.l[2] = 0;
2080
xclient.data.l[3] = 0;
2081
xclient.data.l[4] = 0;
2083
XSendEvent (GDK_DISPLAY_XDISPLAY (display),
2084
GDK_WINDOW_XROOTWIN (window),
2086
SubstructureRedirectMask | SubstructureNotifyMask,
2087
(XEvent *)&xclient);
2089
XFree (current_desktop);
2096
* @window: a #GdkWindow
2097
* @timestamp: timestamp of the event triggering the window focus
2099
* Sets keyboard focus to @window. In most cases, gtk_window_present()
2100
* should be used on a #GtkWindow, rather than calling this function.
2104
gdk_window_focus (GdkWindow *window,
2107
GdkDisplay *display;
2109
g_return_if_fail (GDK_IS_WINDOW (window));
2111
if (GDK_WINDOW_DESTROYED (window))
2114
display = GDK_WINDOW_DISPLAY (window);
2116
if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
2117
gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
2119
XClientMessageEvent xclient;
2121
memset (&xclient, 0, sizeof (xclient));
2122
xclient.type = ClientMessage;
2123
xclient.window = GDK_WINDOW_XWINDOW (window);
2124
xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display,
2125
"_NET_ACTIVE_WINDOW");
2126
xclient.format = 32;
2127
xclient.data.l[0] = 1; /* requestor type; we're an app */
2128
xclient.data.l[1] = timestamp;
2129
xclient.data.l[2] = None; /* currently active window */
2130
xclient.data.l[3] = 0;
2131
xclient.data.l[4] = 0;
2133
XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
2134
SubstructureRedirectMask | SubstructureNotifyMask,
2135
(XEvent *)&xclient);
2139
XRaiseWindow (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window));
2141
/* There is no way of knowing reliably whether we are viewable;
2142
* _gdk_x11_set_input_focus_safe() traps errors asynchronously.
2144
_gdk_x11_set_input_focus_safe (display, GDK_WINDOW_XID (window),
2151
* gdk_window_set_hints:
2152
* @window: a #GdkWindow
2153
* @x: ignored field, does not matter
2154
* @y: ignored field, does not matter
2155
* @min_width: minimum width hint
2156
* @min_height: minimum height hint
2157
* @max_width: max width hint
2158
* @max_height: max height hint
2159
* @flags: logical OR of GDK_HINT_POS, GDK_HINT_MIN_SIZE, and/or GDK_HINT_MAX_SIZE
2161
* This function is broken and useless and you should ignore it.
2162
* If using GTK+, use functions such as gtk_window_resize(), gtk_window_set_size_request(),
2163
* gtk_window_move(), gtk_window_parse_geometry(), and gtk_window_set_geometry_hints(),
2164
* depending on what you're trying to do.
2166
* If using GDK directly, use gdk_window_set_geometry_hints().
2170
gdk_window_set_hints (GdkWindow *window,
2179
XSizeHints size_hints;
2181
g_return_if_fail (GDK_IS_WINDOW (window));
2183
if (GDK_WINDOW_DESTROYED (window))
2186
size_hints.flags = 0;
2188
if (flags & GDK_HINT_POS)
2190
size_hints.flags |= PPosition;
2195
if (flags & GDK_HINT_MIN_SIZE)
2197
size_hints.flags |= PMinSize;
2198
size_hints.min_width = min_width;
2199
size_hints.min_height = min_height;
2202
if (flags & GDK_HINT_MAX_SIZE)
2204
size_hints.flags |= PMaxSize;
2205
size_hints.max_width = max_width;
2206
size_hints.max_height = max_height;
2209
/* FIXME: Would it be better to delete this property if
2210
* flags == 0? It would save space on the server
2212
XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2213
GDK_WINDOW_XID (window),
2218
* gdk_window_set_type_hint:
2219
* @window: A toplevel #GdkWindow
2220
* @hint: A hint of the function this window will have
2222
* The application can use this call to provide a hint to the window
2223
* manager about the functionality of a window. The window manager
2224
* can use this information when determining the decoration and behaviour
2227
* The hint must be set before the window is mapped.
2230
gdk_window_set_type_hint (GdkWindow *window,
2231
GdkWindowTypeHint hint)
2233
GdkDisplay *display;
2236
g_return_if_fail (GDK_IS_WINDOW (window));
2238
if (GDK_WINDOW_DESTROYED (window))
2241
display = gdk_drawable_get_display (window);
2245
case GDK_WINDOW_TYPE_HINT_DIALOG:
2246
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG");
2248
case GDK_WINDOW_TYPE_HINT_MENU:
2249
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU");
2251
case GDK_WINDOW_TYPE_HINT_TOOLBAR:
2252
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR");
2254
case GDK_WINDOW_TYPE_HINT_UTILITY:
2255
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY");
2257
case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
2258
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH");
2260
case GDK_WINDOW_TYPE_HINT_DOCK:
2261
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK");
2263
case GDK_WINDOW_TYPE_HINT_DESKTOP:
2264
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
2266
case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
2267
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
2269
case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
2270
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
2272
case GDK_WINDOW_TYPE_HINT_TOOLTIP:
2273
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
2275
case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
2276
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
2278
case GDK_WINDOW_TYPE_HINT_COMBO:
2279
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
2281
case GDK_WINDOW_TYPE_HINT_DND:
2282
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
2285
g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
2287
case GDK_WINDOW_TYPE_HINT_NORMAL:
2288
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NORMAL");
2292
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2293
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
2294
XA_ATOM, 32, PropModeReplace,
2295
(guchar *)&atom, 1);
2299
* gdk_window_get_type_hint:
2300
* @window: A toplevel #GdkWindow
2302
* This function returns the type hint set for a window.
2304
* Return value: The type hint set for @window
2309
gdk_window_get_type_hint (GdkWindow *window)
2311
GdkDisplay *display;
2312
GdkWindowTypeHint type;
2315
gulong nitems_return;
2316
gulong bytes_after_return;
2317
guchar *data = NULL;
2319
g_return_val_if_fail (GDK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2321
if (GDK_WINDOW_DESTROYED (window))
2322
return GDK_WINDOW_TYPE_HINT_NORMAL;
2324
type = GDK_WINDOW_TYPE_HINT_NORMAL;
2326
display = gdk_drawable_get_display (window);
2328
if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2329
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE"),
2330
0, G_MAXLONG, False, XA_ATOM, &type_return,
2331
&format_return, &nitems_return, &bytes_after_return,
2334
if ((type_return == XA_ATOM) && (format_return == 32) &&
2335
(data) && (nitems_return == 1))
2337
Atom atom = *(Atom*)data;
2339
if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG"))
2340
type = GDK_WINDOW_TYPE_HINT_DIALOG;
2341
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_MENU"))
2342
type = GDK_WINDOW_TYPE_HINT_MENU;
2343
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLBAR"))
2344
type = GDK_WINDOW_TYPE_HINT_TOOLBAR;
2345
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_UTILITY"))
2346
type = GDK_WINDOW_TYPE_HINT_UTILITY;
2347
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_SPLASH"))
2348
type = GDK_WINDOW_TYPE_HINT_SPLASHSCREEN;
2349
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DOCK"))
2350
type = GDK_WINDOW_TYPE_HINT_DOCK;
2351
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
2352
type = GDK_WINDOW_TYPE_HINT_DESKTOP;
2353
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
2354
type = GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
2355
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
2356
type = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
2357
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
2358
type = GDK_WINDOW_TYPE_HINT_TOOLTIP;
2359
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
2360
type = GDK_WINDOW_TYPE_HINT_NOTIFICATION;
2361
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
2362
type = GDK_WINDOW_TYPE_HINT_COMBO;
2363
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
2364
type = GDK_WINDOW_TYPE_HINT_DND;
2367
if (type_return != None && data != NULL)
2375
gdk_wmspec_change_state (gboolean add,
2380
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
2381
XClientMessageEvent xclient;
2383
#define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
2384
#define _NET_WM_STATE_ADD 1 /* add/set property */
2385
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
2387
memset (&xclient, 0, sizeof (xclient));
2388
xclient.type = ClientMessage;
2389
xclient.window = GDK_WINDOW_XID (window);
2390
xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_STATE");
2391
xclient.format = 32;
2392
xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
2393
xclient.data.l[1] = gdk_x11_atom_to_xatom_for_display (display, state1);
2394
xclient.data.l[2] = gdk_x11_atom_to_xatom_for_display (display, state2);
2395
xclient.data.l[3] = 0;
2396
xclient.data.l[4] = 0;
2398
XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
2399
SubstructureRedirectMask | SubstructureNotifyMask,
2400
(XEvent *)&xclient);
2404
* gdk_window_set_modal_hint:
2405
* @window: A toplevel #GdkWindow
2406
* @modal: %TRUE if the window is modal, %FALSE otherwise.
2408
* The application can use this hint to tell the window manager
2409
* that a certain window has modal behaviour. The window manager
2410
* can use this information to handle modal windows in a special
2413
* You should only use this on windows for which you have
2414
* previously called gdk_window_set_transient_for()
2417
gdk_window_set_modal_hint (GdkWindow *window,
2420
GdkWindowObject *private;
2422
g_return_if_fail (GDK_IS_WINDOW (window));
2424
if (GDK_WINDOW_DESTROYED (window))
2427
private = (GdkWindowObject*) window;
2429
private->modal_hint = modal;
2431
if (GDK_WINDOW_IS_MAPPED (window))
2432
gdk_wmspec_change_state (modal, window,
2433
gdk_atom_intern_static_string ("_NET_WM_STATE_MODAL"),
2438
* gdk_window_set_skip_taskbar_hint:
2439
* @window: a toplevel #GdkWindow
2440
* @skips_taskbar: %TRUE to skip the taskbar
2442
* Toggles whether a window should appear in a task list or window
2443
* list. If a window's semantic type as specified with
2444
* gdk_window_set_type_hint() already fully describes the window, this
2445
* function should <emphasis>not</emphasis> be called in addition,
2446
* instead you should allow the window to be treated according to
2447
* standard policy for its semantic type.
2452
gdk_window_set_skip_taskbar_hint (GdkWindow *window,
2453
gboolean skips_taskbar)
2455
GdkToplevelX11 *toplevel;
2457
g_return_if_fail (GDK_IS_WINDOW (window));
2458
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2460
if (GDK_WINDOW_DESTROYED (window))
2463
toplevel = _gdk_x11_window_get_toplevel (window);
2464
toplevel->skip_taskbar_hint = skips_taskbar;
2466
if (GDK_WINDOW_IS_MAPPED (window))
2467
gdk_wmspec_change_state (skips_taskbar, window,
2468
gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_TASKBAR"),
2473
* gdk_window_set_skip_pager_hint:
2474
* @window: a toplevel #GdkWindow
2475
* @skips_pager: %TRUE to skip the pager
2477
* Toggles whether a window should appear in a pager (workspace
2478
* switcher, or other desktop utility program that displays a small
2479
* thumbnail representation of the windows on the desktop). If a
2480
* window's semantic type as specified with gdk_window_set_type_hint()
2481
* already fully describes the window, this function should
2482
* <emphasis>not</emphasis> be called in addition, instead you should
2483
* allow the window to be treated according to standard policy for
2484
* its semantic type.
2489
gdk_window_set_skip_pager_hint (GdkWindow *window,
2490
gboolean skips_pager)
2492
GdkToplevelX11 *toplevel;
2494
g_return_if_fail (GDK_IS_WINDOW (window));
2495
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2497
if (GDK_WINDOW_DESTROYED (window))
2500
toplevel = _gdk_x11_window_get_toplevel (window);
2501
toplevel->skip_pager_hint = skips_pager;
2503
if (GDK_WINDOW_IS_MAPPED (window))
2504
gdk_wmspec_change_state (skips_pager, window,
2505
gdk_atom_intern_static_string ("_NET_WM_STATE_SKIP_PAGER"),
2510
* gdk_window_set_urgency_hint:
2511
* @window: a toplevel #GdkWindow
2512
* @urgent: %TRUE if the window is urgent
2514
* Toggles whether a window needs the user's
2520
gdk_window_set_urgency_hint (GdkWindow *window,
2523
GdkToplevelX11 *toplevel;
2525
g_return_if_fail (GDK_IS_WINDOW (window));
2526
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
2528
if (GDK_WINDOW_DESTROYED (window))
2531
toplevel = _gdk_x11_window_get_toplevel (window);
2532
toplevel->urgency_hint = urgent;
2534
update_wm_hints (window, FALSE);
2538
* gdk_window_set_geometry_hints:
2539
* @window: a toplevel #GdkWindow
2540
* @geometry: geometry hints
2541
* @geom_mask: bitmask indicating fields of @geometry to pay attention to
2543
* Sets the geometry hints for @window. Hints flagged in @geom_mask
2544
* are set, hints not flagged in @geom_mask are unset.
2545
* To unset all hints, use a @geom_mask of 0 and a @geometry of %NULL.
2547
* This function provides hints to the windowing system about
2548
* acceptable sizes for a toplevel window. The purpose of
2549
* this is to constrain user resizing, but the windowing system
2550
* will typically (but is not required to) also constrain the
2551
* current size of the window to the provided values and
2552
* constrain programatic resizing via gdk_window_resize() or
2553
* gdk_window_move_resize().
2555
* Note that on X11, this effect has no effect on windows
2556
* of type %GDK_WINDOW_TEMP or windows where override redirect
2557
* has been turned on via gdk_window_set_override_redirect()
2558
* since these windows are not resizable by the user.
2560
* Since you can't count on the windowing system doing the
2561
* constraints for programmatic resizes, you should generally
2562
* call gdk_window_constrain_size() yourself to determine
2563
* appropriate sizes.
2567
gdk_window_set_geometry_hints (GdkWindow *window,
2568
GdkGeometry *geometry,
2569
GdkWindowHints geom_mask)
2571
XSizeHints size_hints;
2573
g_return_if_fail (GDK_IS_WINDOW (window));
2575
if (GDK_WINDOW_DESTROYED (window))
2578
size_hints.flags = 0;
2580
if (geom_mask & GDK_HINT_POS)
2582
size_hints.flags |= PPosition;
2583
/* We need to initialize the following obsolete fields because KWM
2584
* apparently uses these fields if they are non-zero.
2591
if (geom_mask & GDK_HINT_USER_POS)
2593
size_hints.flags |= USPosition;
2596
if (geom_mask & GDK_HINT_USER_SIZE)
2598
size_hints.flags |= USSize;
2601
if (geom_mask & GDK_HINT_MIN_SIZE)
2603
size_hints.flags |= PMinSize;
2604
size_hints.min_width = geometry->min_width;
2605
size_hints.min_height = geometry->min_height;
2608
if (geom_mask & GDK_HINT_MAX_SIZE)
2610
size_hints.flags |= PMaxSize;
2611
size_hints.max_width = MAX (geometry->max_width, 1);
2612
size_hints.max_height = MAX (geometry->max_height, 1);
2615
if (geom_mask & GDK_HINT_BASE_SIZE)
2617
size_hints.flags |= PBaseSize;
2618
size_hints.base_width = geometry->base_width;
2619
size_hints.base_height = geometry->base_height;
2622
if (geom_mask & GDK_HINT_RESIZE_INC)
2624
size_hints.flags |= PResizeInc;
2625
size_hints.width_inc = geometry->width_inc;
2626
size_hints.height_inc = geometry->height_inc;
2629
if (geom_mask & GDK_HINT_ASPECT)
2631
size_hints.flags |= PAspect;
2632
if (geometry->min_aspect <= 1)
2634
size_hints.min_aspect.x = 65536 * geometry->min_aspect;
2635
size_hints.min_aspect.y = 65536;
2639
size_hints.min_aspect.x = 65536;
2640
size_hints.min_aspect.y = 65536 / geometry->min_aspect;;
2642
if (geometry->max_aspect <= 1)
2644
size_hints.max_aspect.x = 65536 * geometry->max_aspect;
2645
size_hints.max_aspect.y = 65536;
2649
size_hints.max_aspect.x = 65536;
2650
size_hints.max_aspect.y = 65536 / geometry->max_aspect;;
2654
if (geom_mask & GDK_HINT_WIN_GRAVITY)
2656
size_hints.flags |= PWinGravity;
2657
size_hints.win_gravity = geometry->win_gravity;
2660
/* FIXME: Would it be better to delete this property if
2661
* geom_mask == 0? It would save space on the server
2663
XSetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2664
GDK_WINDOW_XID (window),
2669
gdk_window_get_geometry_hints (GdkWindow *window,
2670
GdkGeometry *geometry,
2671
GdkWindowHints *geom_mask)
2673
XSizeHints *size_hints;
2674
glong junk_supplied_mask = 0;
2676
g_return_if_fail (GDK_IS_WINDOW (window));
2677
g_return_if_fail (geometry != NULL);
2678
g_return_if_fail (geom_mask != NULL);
2682
if (GDK_WINDOW_DESTROYED (window))
2685
size_hints = XAllocSizeHints ();
2689
if (!XGetWMNormalHints (GDK_WINDOW_XDISPLAY (window),
2690
GDK_WINDOW_XID (window),
2692
&junk_supplied_mask))
2693
size_hints->flags = 0;
2695
if (size_hints->flags & PMinSize)
2697
*geom_mask |= GDK_HINT_MIN_SIZE;
2698
geometry->min_width = size_hints->min_width;
2699
geometry->min_height = size_hints->min_height;
2702
if (size_hints->flags & PMaxSize)
2704
*geom_mask |= GDK_HINT_MAX_SIZE;
2705
geometry->max_width = MAX (size_hints->max_width, 1);
2706
geometry->max_height = MAX (size_hints->max_height, 1);
2709
if (size_hints->flags & PResizeInc)
2711
*geom_mask |= GDK_HINT_RESIZE_INC;
2712
geometry->width_inc = size_hints->width_inc;
2713
geometry->height_inc = size_hints->height_inc;
2716
if (size_hints->flags & PAspect)
2718
*geom_mask |= GDK_HINT_ASPECT;
2720
geometry->min_aspect = (gdouble) size_hints->min_aspect.x / (gdouble) size_hints->min_aspect.y;
2721
geometry->max_aspect = (gdouble) size_hints->max_aspect.x / (gdouble) size_hints->max_aspect.y;
2724
if (size_hints->flags & PWinGravity)
2726
*geom_mask |= GDK_HINT_WIN_GRAVITY;
2727
geometry->win_gravity = size_hints->win_gravity;
2734
utf8_is_latin1 (const gchar *str)
2736
const char *p = str;
2740
gunichar ch = g_utf8_get_char (p);
2745
p = g_utf8_next_char (p);
2751
/* Set the property to @utf8_str as STRING if the @utf8_str is fully
2752
* convertable to STRING, otherwise, set it as compound text
2755
set_text_property (GdkDisplay *display,
2758
const gchar *utf8_str)
2760
gchar *prop_text = NULL;
2764
gboolean is_compound_text;
2766
if (utf8_is_latin1 (utf8_str))
2768
prop_type = XA_STRING;
2769
prop_text = gdk_utf8_to_string_target (utf8_str);
2770
prop_length = prop_text ? strlen (prop_text) : 0;
2772
is_compound_text = FALSE;
2778
gdk_utf8_to_compound_text_for_display (display,
2779
utf8_str, &gdk_type, &prop_format,
2780
(guchar **)&prop_text, &prop_length);
2781
prop_type = gdk_x11_atom_to_xatom_for_display (display, gdk_type);
2782
is_compound_text = TRUE;
2787
XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
2790
prop_type, prop_format,
2791
PropModeReplace, (guchar *)prop_text,
2794
if (is_compound_text)
2795
gdk_free_compound_text ((guchar *)prop_text);
2801
/* Set WM_NAME and _NET_WM_NAME
2804
set_wm_name (GdkDisplay *display,
2808
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
2809
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_NAME"),
2810
gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2811
PropModeReplace, (guchar *)name, strlen (name));
2813
set_text_property (display, xwindow,
2814
gdk_x11_get_xatom_by_name_for_display (display, "WM_NAME"),
2819
* gdk_window_set_title:
2820
* @window: a toplevel #GdkWindow
2821
* @title: title of @window
2823
* Sets the title of a toplevel window, to be displayed in the titlebar.
2824
* If you haven't explicitly set the icon name for the window
2825
* (using gdk_window_set_icon_name()), the icon name will be set to
2826
* @title as well. @title must be in UTF-8 encoding (as with all
2827
* user-readable strings in GDK/GTK+). @title may not be %NULL.
2830
gdk_window_set_title (GdkWindow *window,
2833
GdkDisplay *display;
2837
g_return_if_fail (GDK_IS_WINDOW (window));
2838
g_return_if_fail (title != NULL);
2840
if (GDK_WINDOW_DESTROYED (window))
2843
display = gdk_drawable_get_display (window);
2844
xdisplay = GDK_DISPLAY_XDISPLAY (display);
2845
xwindow = GDK_WINDOW_XID (window);
2847
set_wm_name (display, xwindow, title);
2849
if (!gdk_window_icon_name_set (window))
2851
XChangeProperty (xdisplay, xwindow,
2852
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
2853
gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
2854
PropModeReplace, (guchar *)title, strlen (title));
2856
set_text_property (display, xwindow,
2857
gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
2863
* gdk_window_set_role:
2864
* @window: a toplevel #GdkWindow
2865
* @role: a string indicating its role
2867
* When using GTK+, typically you should use gtk_window_set_role() instead
2868
* of this low-level function.
2870
* The window manager and session manager use a window's role to
2871
* distinguish it from other kinds of window in the same application.
2872
* When an application is restarted after being saved in a previous
2873
* session, all windows with the same title and role are treated as
2874
* interchangeable. So if you have two windows with the same title
2875
* that should be distinguished for session management purposes, you
2876
* should set the role on those windows. It doesn't matter what string
2877
* you use for the role, as long as you have a different role for each
2878
* non-interchangeable kind of window.
2882
gdk_window_set_role (GdkWindow *window,
2885
GdkDisplay *display;
2887
g_return_if_fail (GDK_IS_WINDOW (window));
2889
display = gdk_drawable_get_display (window);
2891
if (!GDK_WINDOW_DESTROYED (window))
2894
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2895
gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"),
2896
XA_STRING, 8, PropModeReplace, (guchar *)role, strlen (role));
2898
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
2899
gdk_x11_get_xatom_by_name_for_display (display, "WM_WINDOW_ROLE"));
2904
* gdk_window_set_transient_for:
2905
* @window: a toplevel #GdkWindow
2906
* @parent: another toplevel #GdkWindow
2908
* Indicates to the window manager that @window is a transient dialog
2909
* associated with the application window @parent. This allows the
2910
* window manager to do things like center @window on @parent and
2911
* keep @window above @parent.
2913
* See gtk_window_set_transient_for() if you're using #GtkWindow or
2918
gdk_window_set_transient_for (GdkWindow *window,
2921
g_return_if_fail (GDK_IS_WINDOW (window));
2923
if (!GDK_WINDOW_DESTROYED (window) && !GDK_WINDOW_DESTROYED (parent))
2924
XSetTransientForHint (GDK_WINDOW_XDISPLAY (window),
2925
GDK_WINDOW_XID (window),
2926
GDK_WINDOW_XID (parent));
2930
* gdk_window_set_background:
2931
* @window: a #GdkWindow
2932
* @color: an allocated #GdkColor
2934
* Sets the background color of @window. (However, when using GTK+,
2935
* set the background of a widget with gtk_widget_modify_bg() - if
2936
* you're an application - or gtk_style_set_background() - if you're
2937
* implementing a custom widget.)
2939
* The @color must be allocated; gdk_rgb_find_color() is the best way
2940
* to allocate a color.
2942
* See also gdk_window_set_back_pixmap().
2946
gdk_window_set_background (GdkWindow *window,
2947
const GdkColor *color)
2949
GdkWindowObject *private = (GdkWindowObject *)window;
2950
GdkColormap *colormap = gdk_drawable_get_colormap (window);
2952
g_return_if_fail (GDK_IS_WINDOW (window));
2954
if (!GDK_WINDOW_DESTROYED (window))
2955
XSetWindowBackground (GDK_WINDOW_XDISPLAY (window),
2956
GDK_WINDOW_XID (window), color->pixel);
2958
private->bg_color = *color;
2959
gdk_colormap_query_color (colormap, private->bg_color.pixel, &private->bg_color);
2961
if (private->bg_pixmap &&
2962
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
2963
private->bg_pixmap != GDK_NO_BG)
2964
g_object_unref (private->bg_pixmap);
2966
private->bg_pixmap = NULL;
2970
* gdk_window_set_back_pixmap:
2971
* @window: a #GdkWindow
2972
* @pixmap: a #GdkPixmap, or %NULL
2973
* @parent_relative: whether the tiling origin is at the origin of @window's parent
2975
* Sets the background pixmap of @window. May also be used to set a background of
2976
* "None" on @window, by setting a background pixmap of %NULL.
2977
* A background pixmap will be tiled, positioning the first tile at the origin of
2978
* @window, or if @parent_relative is %TRUE, the tiling will be done based on the
2979
* origin of the parent window (useful to align tiles in a parent with tiles
2982
* A background pixmap of %NULL means that the window will have no
2983
* background. A window with no background will never have its
2984
* background filled by the windowing system, instead the window will
2985
* contain whatever pixels were already in the corresponding area of
2988
* The windowing system will normally fill a window with its background
2989
* when the window is obscured then exposed, and when you call
2990
* gdk_window_clear().
2994
gdk_window_set_back_pixmap (GdkWindow *window,
2996
gboolean parent_relative)
2998
GdkWindowObject *private = (GdkWindowObject *)window;
3001
g_return_if_fail (GDK_IS_WINDOW (window));
3002
g_return_if_fail (pixmap == NULL || !parent_relative);
3003
g_return_if_fail (pixmap == NULL || gdk_drawable_get_depth (window) == gdk_drawable_get_depth (pixmap));
3005
if (pixmap && !gdk_drawable_get_colormap (pixmap))
3007
g_warning ("gdk_window_set_back_pixmap(): pixmap must have a colormap");
3011
if (private->bg_pixmap &&
3012
private->bg_pixmap != GDK_PARENT_RELATIVE_BG &&
3013
private->bg_pixmap != GDK_NO_BG)
3014
g_object_unref (private->bg_pixmap);
3016
if (parent_relative)
3018
xpixmap = ParentRelative;
3019
private->bg_pixmap = GDK_PARENT_RELATIVE_BG;
3025
g_object_ref (pixmap);
3026
private->bg_pixmap = pixmap;
3027
xpixmap = GDK_PIXMAP_XID (pixmap);
3032
private->bg_pixmap = GDK_NO_BG;
3036
if (!GDK_WINDOW_DESTROYED (window))
3037
XSetWindowBackgroundPixmap (GDK_WINDOW_XDISPLAY (window),
3038
GDK_WINDOW_XID (window), xpixmap);
3042
* gdk_window_set_cursor:
3043
* @window: a #GdkWindow
3046
* Sets the mouse pointer for a #GdkWindow. Use gdk_cursor_new() or
3047
* gdk_cursor_new_from_pixmap() to create the cursor.
3048
* To make the cursor invisible, use gdk_cursor_new_from_pixmap() to create
3049
* a cursor with no pixels in it. Passing %NULL for the @cursor argument
3050
* to gdk_window_set_cursor() means that @window will use the cursor of
3051
* its parent window. Most windows should use this default.
3055
gdk_window_set_cursor (GdkWindow *window,
3058
GdkWindowObject *private;
3059
GdkWindowImplX11 *impl;
3060
GdkCursorPrivate *cursor_private;
3063
g_return_if_fail (GDK_IS_WINDOW (window));
3065
private = (GdkWindowObject *)window;
3066
impl = GDK_WINDOW_IMPL_X11 (private->impl);
3067
cursor_private = (GdkCursorPrivate*) cursor;
3071
gdk_cursor_unref (impl->cursor);
3072
impl->cursor = NULL;
3079
_gdk_x11_cursor_update_theme (cursor);
3080
xcursor = cursor_private->xcursor;
3083
if (!GDK_WINDOW_DESTROYED (window))
3085
XDefineCursor (GDK_WINDOW_XDISPLAY (window),
3086
GDK_WINDOW_XID (window),
3090
impl->cursor = gdk_cursor_ref (cursor);
3095
_gdk_x11_window_get_cursor (GdkWindow *window)
3097
GdkWindowObject *private;
3098
GdkWindowImplX11 *impl;
3100
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
3102
private = (GdkWindowObject *)window;
3103
impl = GDK_WINDOW_IMPL_X11 (private->impl);
3105
return impl->cursor;
3109
* gdk_window_get_geometry:
3110
* @window: a #GdkWindow
3111
* @x: return location for X coordinate of window (relative to its parent)
3112
* @y: return location for Y coordinate of window (relative to its parent)
3113
* @width: return location for width of window
3114
* @height: return location for height of window
3115
* @depth: return location for bit depth of window
3117
* Any of the return location arguments to this function may be %NULL,
3118
* if you aren't interested in getting the value of that field.
3120
* The X and Y coordinates returned are relative to the parent window
3121
* of @window, which for toplevels usually means relative to the
3122
* window decorations (titlebar, etc.) rather than relative to the
3123
* root window (screen-size background window).
3125
* On the X11 platform, the geometry is obtained from the X server,
3126
* so reflects the latest position of @window; this may be out-of-sync
3127
* with the position of @window delivered in the most-recently-processed
3128
* #GdkEventConfigure. gdk_window_get_position() in contrast gets the
3129
* position from the most recent configure event.
3132
* If @window is not a toplevel, it is <emphasis>much</emphasis> better
3133
* to call gdk_window_get_position() and gdk_drawable_get_size() instead,
3134
* because it avoids the roundtrip to the X server and because
3135
* gdk_drawable_get_size() supports the full 32-bit coordinate space,
3136
* whereas gdk_window_get_geometry() is restricted to the 16-bit
3137
* coordinates of X11.
3141
gdk_window_get_geometry (GdkWindow *window,
3153
guint tborder_width;
3156
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
3160
GDK_NOTE (MULTIHEAD,
3161
g_message ("gdk_window_get_geometry(): Window needs to be non-NULL to be multi head safe"));
3162
window = gdk_screen_get_root_window ((gdk_screen_get_default ()));
3165
if (!GDK_WINDOW_DESTROYED (window))
3167
XGetGeometry (GDK_WINDOW_XDISPLAY (window),
3168
GDK_WINDOW_XID (window),
3169
&root, &tx, &ty, &twidth, &theight, &tborder_width, &tdepth);
3185
* gdk_window_get_origin:
3186
* @window: a #GdkWindow
3187
* @x: return location for X coordinate
3188
* @y: return location for Y coordinate
3190
* Obtains the position of a window in root window coordinates.
3191
* (Compare with gdk_window_get_position() and
3192
* gdk_window_get_geometry() which return the position of a window
3193
* relative to its parent window.)
3195
* Return value: not meaningful, ignore
3198
gdk_window_get_origin (GdkWindow *window,
3207
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
3209
if (!GDK_WINDOW_DESTROYED (window))
3211
return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
3212
GDK_WINDOW_XID (window),
3213
GDK_WINDOW_XROOTWIN (window),
3229
* gdk_window_get_deskrelative_origin:
3230
* @window: a toplevel #GdkWindow
3231
* @x: return location for X coordinate
3232
* @y: return location for Y coordinate
3234
* This gets the origin of a #GdkWindow relative to
3235
* an Enlightenment-window-manager desktop. As long as you don't
3236
* assume that the user's desktop/workspace covers the entire
3237
* root window (i.e. you don't assume that the desktop begins
3238
* at root window coordinate 0,0) this function is not necessary.
3239
* It's deprecated for that reason.
3241
* Return value: not meaningful
3244
gdk_window_get_deskrelative_origin (GdkWindow *window,
3248
gboolean return_val = FALSE;
3249
gint num_children, format_return;
3250
Window win, *child, parent, root;
3255
gulong number_return, bytes_after_return;
3256
guchar *data_return;
3258
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
3260
if (!GDK_WINDOW_DESTROYED (window))
3262
atom = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
3263
"ENLIGHTENMENT_DESKTOP");
3264
win = GDK_WINDOW_XID (window);
3266
while (XQueryTree (GDK_WINDOW_XDISPLAY (window), win, &root, &parent,
3267
&child, (unsigned int *)&num_children))
3269
if ((child) && (num_children > 0))
3281
XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), win, atom, 0, 0,
3282
False, XA_CARDINAL, &type_return, &format_return,
3283
&number_return, &bytes_after_return, &data_return);
3285
if (type_return == XA_CARDINAL)
3287
XFree (data_return);
3292
return_val = XTranslateCoordinates (GDK_WINDOW_XDISPLAY (window),
3293
GDK_WINDOW_XID (window),
3308
* gdk_window_get_root_origin:
3309
* @window: a toplevel #GdkWindow
3310
* @x: return location for X position of window frame
3311
* @y: return location for Y position of window frame
3313
* Obtains the top-left corner of the window manager frame in root
3314
* window coordinates.
3318
gdk_window_get_root_origin (GdkWindow *window,
3324
g_return_if_fail (GDK_IS_WINDOW (window));
3326
gdk_window_get_frame_extents (window, &rect);
3336
* gdk_window_get_frame_extents:
3337
* @window: a toplevel #GdkWindow
3338
* @rect: rectangle to fill with bounding box of the window frame
3340
* Obtains the bounding box of the window, including window manager
3341
* titlebar/borders if any. The frame position is given in root window
3342
* coordinates. To get the position of the window itself (rather than
3343
* the frame) in root window coordinates, use gdk_window_get_origin().
3347
gdk_window_get_frame_extents (GdkWindow *window,
3350
GdkDisplay *display;
3351
GdkWindowObject *private;
3361
gulong nitems_return;
3362
gulong bytes_after_return;
3365
guint ww, wh, wb, wd;
3368
g_return_if_fail (GDK_IS_WINDOW (window));
3369
g_return_if_fail (rect != NULL);
3371
private = (GdkWindowObject*) window;
3378
if (GDK_WINDOW_DESTROYED (window))
3381
while (private->parent && ((GdkWindowObject*) private->parent)->parent)
3382
private = (GdkWindowObject*) private->parent;
3384
/* Refine our fallback answer a bit using local information */
3385
rect->x = private->x;
3386
rect->y = private->y;
3387
gdk_drawable_get_size ((GdkDrawable *)private, &rect->width, &rect->height);
3389
if (GDK_WINDOW_DESTROYED (private))
3392
gdk_error_trap_push();
3394
/* use NETWM_VIRTUAL_ROOTS if available */
3395
display = gdk_drawable_get_display (window);
3396
root = GDK_WINDOW_XROOTWIN (window);
3401
if (XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), root,
3402
gdk_x11_get_xatom_by_name_for_display (display,
3403
"_NET_VIRTUAL_ROOTS"),
3404
0, G_MAXLONG, False, XA_WINDOW, &type_return,
3405
&format_return, &nitems_return, &bytes_after_return,
3409
if ((type_return == XA_WINDOW) && (format_return == 32) && (data))
3411
nvroots = nitems_return;
3412
vroots = (Window *)data;
3416
xparent = GDK_WINDOW_XID (window);
3422
if (!XQueryTree (GDK_DISPLAY_XDISPLAY (display), xwindow,
3424
&children, &nchildren))
3430
/* check virtual roots */
3431
for (i = 0; i < nvroots; i++)
3433
if (xparent == vroots[i])
3440
while (xparent != root);
3442
if (XGetGeometry (GDK_DISPLAY_XDISPLAY (display), xwindow,
3443
&root, &wx, &wy, &ww, &wh, &wb, &wd))
3455
gdk_error_trap_pop ();
3459
_gdk_windowing_get_pointer (GdkDisplay *display,
3463
GdkModifierType *mask)
3465
GdkScreen *default_screen;
3475
if (display->closed)
3478
default_screen = gdk_display_get_default_screen (display);
3480
xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
3481
xwindow = GDK_SCREEN_XROOTWIN (default_screen);
3483
if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
3485
XQueryPointer (xdisplay, xwindow,
3486
&root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3490
XSetWindowAttributes attributes;
3493
w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
3494
CopyFromParent, InputOnly, CopyFromParent,
3496
XQueryPointer (xdisplay, w,
3497
&root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3498
XDestroyWindow (xdisplay, w);
3503
GdkWindow *gdk_root = gdk_window_lookup_for_display (display, root);
3504
*screen = gdk_drawable_get_screen (gdk_root);
3513
_gdk_windowing_window_get_pointer (GdkDisplay *display,
3517
GdkModifierType *mask)
3519
GdkWindow *return_val;
3525
unsigned int xmask = 0;
3526
gint xoffset, yoffset;
3528
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
3530
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3533
if (!GDK_WINDOW_DESTROYED (window))
3535
if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
3537
if (XQueryPointer (GDK_WINDOW_XDISPLAY (window),
3538
GDK_WINDOW_XID (window),
3539
&root, &child, &rootx, &rooty, &winx, &winy, &xmask))
3542
return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child);
3548
int originx, originy;
3549
_gdk_windowing_get_pointer (gdk_drawable_get_display (window), &screen,
3550
&rootx, &rooty, &xmask);
3551
gdk_window_get_origin (window, &originx, &originy);
3552
winx = rootx - originx;
3553
winy = rooty - originy;
3557
*x = winx + xoffset;
3558
*y = winy + yoffset;
3565
* gdk_display_warp_pointer:
3566
* @display: a #GdkDisplay
3567
* @screen: the screen of @display to warp the pointer to
3568
* @x: the x coordinate of the destination
3569
* @y: the y coordinate of the destination
3571
* Warps the pointer of @display to the point @x,@y on
3572
* the screen @screen, unless the pointer is confined
3573
* to a window by a grab, in which case it will be moved
3574
* as far as allowed by the grab. Warping the pointer
3575
* creates events as if the user had moved the mouse
3576
* instantaneously to the destination.
3578
* Note that the pointer should normally be under the
3579
* control of the user. This function was added to cover
3580
* some rare use cases like keyboard navigation support
3581
* for the color picker in the #GtkColorSelectionDialog.
3586
gdk_display_warp_pointer (GdkDisplay *display,
3594
xdisplay = GDK_DISPLAY_XDISPLAY (display);
3595
dest = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (screen));
3597
XWarpPointer (xdisplay, None, dest, 0, 0, 0, 0, x, y);
3601
_gdk_windowing_window_at_pointer (GdkDisplay *display,
3610
Window xwindow_last = 0;
3612
int rootx = -1, rooty = -1;
3616
screen = gdk_display_get_default_screen (display);
3618
xwindow = GDK_SCREEN_XROOTWIN (screen);
3619
xdisplay = GDK_SCREEN_XDISPLAY (screen);
3621
/* This function really only works if the mouse pointer is held still
3622
* during its operation. If it moves from one leaf window to another
3623
* than we'll end up with inaccurate values for win_x, win_y
3626
gdk_x11_display_grab (display);
3627
if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
3629
XQueryPointer (xdisplay, xwindow,
3630
&root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3631
if (root == xwindow)
3638
xwindow_last = xwindow;
3639
XQueryPointer (xdisplay, xwindow,
3640
&root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
3645
gint i, screens, width, height;
3646
GList *toplevels, *list;
3647
Window pointer_window;
3649
pointer_window = None;
3650
screens = gdk_display_get_n_screens (display);
3651
for (i = 0; i < screens; ++i) {
3652
screen = gdk_display_get_screen (display, i);
3653
toplevels = gdk_screen_get_toplevel_windows (screen);
3654
for (list = toplevels; list != NULL; list = g_list_next (list)) {
3655
window = GDK_WINDOW (list->data);
3656
xwindow = GDK_WINDOW_XWINDOW (window);
3657
gdk_error_trap_push ();
3658
XQueryPointer (xdisplay, xwindow,
3659
&root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3661
if (gdk_error_trap_pop ())
3665
pointer_window = child;
3668
gdk_window_get_geometry (window, NULL, NULL, &width, &height, NULL);
3669
if (winx >= 0 && winy >= 0 && winx < width && winy < height)
3671
/* A childless toplevel, or below another window? */
3672
XSetWindowAttributes attributes;
3675
w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
3676
CopyFromParent, InputOnly, CopyFromParent,
3678
XMapWindow (xdisplay, w);
3679
XQueryPointer (xdisplay, xwindow,
3680
&root, &child, &rootx, &rooty, &winx, &winy, &xmask);
3681
XDestroyWindow (xdisplay, w);
3684
pointer_window = xwindow;
3689
g_list_free (toplevels);
3690
if (pointer_window != None)
3693
xwindow = pointer_window;
3697
xwindow_last = xwindow;
3698
gdk_error_trap_push ();
3699
XQueryPointer (xdisplay, xwindow,
3700
&root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
3702
if (gdk_error_trap_pop ())
3707
gdk_x11_display_ungrab (display);
3709
window = gdk_window_lookup_for_display (display, xwindow_last);
3710
*win_x = window ? winx : -1;
3711
*win_y = window ? winy : -1;
3717
* gdk_window_get_events:
3718
* @window: a #GdkWindow
3720
* Gets the event mask for @window. See gdk_window_set_events().
3722
* Return value: event mask for @window
3725
gdk_window_get_events (GdkWindow *window)
3727
XWindowAttributes attrs;
3728
GdkEventMask event_mask;
3730
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
3732
if (GDK_WINDOW_DESTROYED (window))
3736
XGetWindowAttributes (GDK_WINDOW_XDISPLAY (window),
3737
GDK_WINDOW_XID (window),
3740
event_mask = x_event_mask_to_gdk_event_mask (attrs.your_event_mask);
3741
GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
3748
* gdk_window_set_events:
3749
* @window: a #GdkWindow
3750
* @event_mask: event mask for @window
3752
* The event mask for a window determines which events will be reported
3753
* for that window. For example, an event mask including #GDK_BUTTON_PRESS_MASK
3754
* means the window should report button press events. The event mask
3755
* is the bitwise OR of values from the #GdkEventMask enumeration.
3759
gdk_window_set_events (GdkWindow *window,
3760
GdkEventMask event_mask)
3765
g_return_if_fail (GDK_IS_WINDOW (window));
3767
if (!GDK_WINDOW_DESTROYED (window))
3769
GDK_WINDOW_OBJECT (window)->event_mask = event_mask;
3770
xevent_mask = StructureNotifyMask | PropertyChangeMask;
3771
for (i = 0; i < _gdk_nenvent_masks; i++)
3773
if (event_mask & (1 << (i + 1)))
3774
xevent_mask |= _gdk_event_mask_table[i];
3777
XSelectInput (GDK_WINDOW_XDISPLAY (window),
3778
GDK_WINDOW_XID (window),
3784
gdk_window_add_colormap_windows (GdkWindow *window)
3786
GdkWindow *toplevel;
3787
Window *old_windows;
3788
Window *new_windows;
3791
g_return_if_fail (GDK_IS_WINDOW (window));
3793
if (GDK_WINDOW_DESTROYED (window))
3796
toplevel = gdk_window_get_toplevel (window);
3799
if (!XGetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3800
GDK_WINDOW_XID (toplevel),
3801
&old_windows, &count))
3806
for (i = 0; i < count; i++)
3807
if (old_windows[i] == GDK_WINDOW_XID (window))
3809
XFree (old_windows);
3813
new_windows = g_new (Window, count + 1);
3815
for (i = 0; i < count; i++)
3816
new_windows[i] = old_windows[i];
3817
new_windows[count] = GDK_WINDOW_XID (window);
3819
XSetWMColormapWindows (GDK_WINDOW_XDISPLAY (toplevel),
3820
GDK_WINDOW_XID (toplevel),
3821
new_windows, count + 1);
3823
g_free (new_windows);
3825
XFree (old_windows);
3828
#define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
3831
* This needs the X11 shape extension.
3832
* If not available, shaped windows will look
3833
* ugly, but programs still work. Stefan Wille
3836
do_shape_combine_mask (GdkWindow *window,
3842
GdkWindowObject *private = (GdkWindowObject *)window;
3844
gint xoffset, yoffset;
3846
g_return_if_fail (GDK_IS_WINDOW (window));
3848
#ifdef HAVE_SHAPE_EXT
3849
if (GDK_WINDOW_DESTROYED (window))
3852
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3854
if (xoffset != 0 || yoffset != 0)
3856
WARN_SHAPE_TOO_BIG ();
3860
if (shape == ShapeBounding
3861
? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
3862
: gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
3866
pixmap = GDK_PIXMAP_XID (mask);
3868
private->shaped = (shape == ShapeBounding);
3876
private->shaped = FALSE;
3879
XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
3880
GDK_WINDOW_XID (window),
3886
#endif /* HAVE_SHAPE_EXT */
3890
* gdk_window_shape_combine_mask:
3891
* @window: a #GdkWindow
3893
* @x: X position of shape mask with respect to @window
3894
* @y: Y position of shape mask with respect to @window
3896
* Applies a shape mask to @window. Pixels in @window corresponding to
3897
* set bits in the @mask will be visible; pixels in @window
3898
* corresponding to unset bits in the @mask will be transparent. This
3899
* gives a non-rectangular window.
3901
* If @mask is %NULL, the shape mask will be unset, and the @x/@y
3902
* parameters are not used.
3904
* On the X11 platform, this uses an X server extension which is
3905
* widely available on most common platforms, but not available on
3906
* very old X servers, and occasionally the implementation will be
3907
* buggy. On servers without the shape extension, this function
3910
* On the Win32 platform the functionality is always present.
3912
* This function works on both toplevel and child windows.
3916
gdk_window_shape_combine_mask (GdkWindow *window,
3921
do_shape_combine_mask (window, mask, x, y, ShapeBounding);
3925
* gdk_window_input_shape_combine_mask:
3926
* @window: a #GdkWindow
3928
* @x: X position of shape mask with respect to @window
3929
* @y: Y position of shape mask with respect to @window
3931
* Like gdk_window_shape_combine_mask(), but the shape applies
3932
* only to event handling. Mouse events which happen while
3933
* the pointer position corresponds to an unset bit in the
3934
* mask will be passed on the window below @window.
3936
* An input shape is typically used with RGBA windows.
3937
* The alpha channel of the window defines which pixels are
3938
* invisible and allows for nicely antialiased borders,
3939
* and the input shape controls where the window is
3942
* On the X11 platform, this requires version 1.1 of the
3945
* On the Win32 platform, this functionality is not present and the
3946
* function does nothing.
3951
gdk_window_input_shape_combine_mask (GdkWindow *window,
3957
do_shape_combine_mask (window, mask, x, y, ShapeInput);
3963
do_shape_combine_region (GdkWindow *window,
3964
GdkRegion *shape_region,
3969
GdkWindowObject *private = (GdkWindowObject *)window;
3970
gint xoffset, yoffset;
3972
g_return_if_fail (GDK_IS_WINDOW (window));
3974
#ifdef HAVE_SHAPE_EXT
3975
if (GDK_WINDOW_DESTROYED (window))
3978
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
3980
if (xoffset != 0 || yoffset != 0)
3982
WARN_SHAPE_TOO_BIG ();
3986
if (shape_region == NULL)
3988
/* Use NULL mask to unset the shape */
3989
gdk_window_shape_combine_mask (window, NULL, 0, 0);
3993
if (shape == ShapeBounding
3994
? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
3995
: gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
3998
XRectangle *xrects = NULL;
4000
private->shaped = shape == ShapeBounding;
4002
_gdk_region_get_xrectangles (shape_region,
4006
XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
4007
GDK_WINDOW_XID (window),
4016
#endif /* HAVE_SHAPE_EXT */
4020
* gdk_window_shape_combine_region:
4021
* @window: a #GdkWindow
4022
* @shape_region: region of window to be non-transparent
4023
* @offset_x: X position of @shape_region in @window coordinates
4024
* @offset_y: Y position of @shape_region in @window coordinates
4026
* Makes pixels in @window outside @shape_region be transparent,
4027
* so that the window may be nonrectangular. See also
4028
* gdk_window_shape_combine_mask() to use a bitmap as the mask.
4030
* If @shape_region is %NULL, the shape will be unset, so the whole
4031
* window will be opaque again. @offset_x and @offset_y are ignored
4032
* if @shape_region is %NULL.
4034
* On the X11 platform, this uses an X server extension which is
4035
* widely available on most common platforms, but not available on
4036
* very old X servers, and occasionally the implementation will be
4037
* buggy. On servers without the shape extension, this function
4040
* On the Win32 platform, this functionality is always present.
4042
* This function works on both toplevel and child windows.
4046
gdk_window_shape_combine_region (GdkWindow *window,
4047
GdkRegion *shape_region,
4051
do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeBounding);
4055
* gdk_window_input_shape_combine_region:
4056
* @window: a #GdkWindow
4057
* @shape_region: region of window to be non-transparent
4058
* @offset_x: X position of @shape_region in @window coordinates
4059
* @offset_y: Y position of @shape_region in @window coordinates
4061
* Like gdk_window_shape_combine_region(), but the shape applies
4062
* only to event handling. Mouse events which happen while
4063
* the pointer position corresponds to an unset bit in the
4064
* mask will be passed on the window below @window.
4066
* An input shape is typically used with RGBA windows.
4067
* The alpha channel of the window defines which pixels are
4068
* invisible and allows for nicely antialiased borders,
4069
* and the input shape controls where the window is
4072
* On the X11 platform, this requires version 1.1 of the
4075
* On the Win32 platform, this functionality is not present and the
4076
* function does nothing.
4081
gdk_window_input_shape_combine_region (GdkWindow *window,
4082
GdkRegion *shape_region,
4087
do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeInput);
4093
* gdk_window_set_override_redirect:
4094
* @window: a toplevel #GdkWindow
4095
* @override_redirect: %TRUE if window should be override redirect
4097
* An override redirect window is not under the control of the window manager.
4098
* This means it won't have a titlebar, won't be minimizable, etc. - it will
4099
* be entirely under the control of the application. The window manager
4100
* can't see the override redirect window at all.
4102
* Override redirect should only be used for short-lived temporary
4103
* windows, such as popup menus. #GtkMenu uses an override redirect
4104
* window in its implementation, for example.
4108
gdk_window_set_override_redirect (GdkWindow *window,
4109
gboolean override_redirect)
4111
XSetWindowAttributes attr;
4113
g_return_if_fail (GDK_IS_WINDOW (window));
4115
if (!GDK_WINDOW_DESTROYED (window))
4117
GdkWindowObject *private = (GdkWindowObject *)window;
4118
GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl);
4120
attr.override_redirect = (override_redirect? True : False);
4121
XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
4122
GDK_WINDOW_XID (window),
4126
impl->override_redirect = attr.override_redirect;
4131
* gdk_window_set_accept_focus:
4132
* @window: a toplevel #GdkWindow
4133
* @accept_focus: %TRUE if the window should receive input focus
4135
* Setting @accept_focus to %FALSE hints the desktop environment that the
4136
* window doesn't want to receive input focus.
4138
* On X, it is the responsibility of the window manager to interpret this
4139
* hint. ICCCM-compliant window manager usually respect it.
4144
gdk_window_set_accept_focus (GdkWindow *window,
4145
gboolean accept_focus)
4147
GdkWindowObject *private;
4149
g_return_if_fail (GDK_IS_WINDOW (window));
4151
private = (GdkWindowObject *)window;
4153
accept_focus = accept_focus != FALSE;
4155
if (private->accept_focus != accept_focus)
4157
private->accept_focus = accept_focus;
4159
if (!GDK_WINDOW_DESTROYED (window))
4160
update_wm_hints (window, FALSE);
4165
* gdk_window_set_focus_on_map:
4166
* @window: a toplevel #GdkWindow
4167
* @focus_on_map: %TRUE if the window should receive input focus when mapped
4169
* Setting @focus_on_map to %FALSE hints the desktop environment that the
4170
* window doesn't want to receive input focus when it is mapped.
4171
* focus_on_map should be turned off for windows that aren't triggered
4172
* interactively (such as popups from network activity).
4174
* On X, it is the responsibility of the window manager to interpret
4175
* this hint. Window managers following the freedesktop.org window
4176
* manager extension specification should respect it.
4181
gdk_window_set_focus_on_map (GdkWindow *window,
4182
gboolean focus_on_map)
4184
GdkWindowObject *private;
4186
g_return_if_fail (GDK_IS_WINDOW (window));
4188
private = (GdkWindowObject *)window;
4190
focus_on_map = focus_on_map != FALSE;
4192
if (private->focus_on_map != focus_on_map)
4194
private->focus_on_map = focus_on_map;
4196
if ((!GDK_WINDOW_DESTROYED (window)) && (!private->focus_on_map))
4197
gdk_x11_window_set_user_time (window, 0);
4202
* gdk_x11_window_set_user_time:
4203
* @window: A toplevel #GdkWindow
4204
* @timestamp: An XServer timestamp to which the property should be set
4206
* The application can use this call to update the _NET_WM_USER_TIME
4207
* property on a toplevel window. This property stores an Xserver
4208
* time which represents the time of the last user input event
4209
* received for this window. This property may be used by the window
4210
* manager to alter the focus, stacking, and/or placement behavior of
4211
* windows when they are mapped depending on whether the new window
4212
* was created by a user action or is a "pop-up" window activated by a
4213
* timer or some other event.
4215
* Note that this property is automatically updated by GDK, so this
4216
* function should only be used by applications which handle input
4217
* events bypassing GDK.
4222
gdk_x11_window_set_user_time (GdkWindow *window,
4225
GdkDisplay *display;
4226
GdkDisplayX11 *display_x11;
4227
GdkToplevelX11 *toplevel;
4228
glong timestamp_long = (glong)timestamp;
4230
g_return_if_fail (GDK_IS_WINDOW (window));
4232
if (GDK_WINDOW_DESTROYED (window))
4235
display = gdk_drawable_get_display (window);
4236
display_x11 = GDK_DISPLAY_X11 (display);
4237
toplevel = _gdk_x11_window_get_toplevel (window);
4239
XChangeProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
4240
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_USER_TIME"),
4241
XA_CARDINAL, 32, PropModeReplace,
4242
(guchar *)×tamp_long, 1);
4244
if (timestamp_long != GDK_CURRENT_TIME)
4245
display_x11->user_time = timestamp_long;
4248
toplevel->user_time = timestamp_long;
4251
#define GDK_SELECTION_MAX_SIZE(display) \
4253
XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0 \
4254
? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100 \
4255
: XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
4258
* gdk_window_set_icon_list:
4259
* @window: The #GdkWindow toplevel window to set the icon of.
4260
* @pixbufs: A list of pixbufs, of different sizes.
4262
* Sets a list of icons for the window. One of these will be used
4263
* to represent the window when it has been iconified. The icon is
4264
* usually shown in an icon box or some sort of task bar. Which icon
4265
* size is shown depends on the window manager. The window manager
4266
* can scale the icon but setting several size icons can give better
4267
* image quality since the window manager may only need to scale the
4268
* icon by a small amount or not at all.
4272
gdk_window_set_icon_list (GdkWindow *window,
4281
gint width, height, stride;
4284
GdkDisplay *display;
4287
g_return_if_fail (GDK_IS_WINDOW (window));
4289
if (GDK_WINDOW_DESTROYED (window))
4292
display = gdk_drawable_get_display (window);
4300
g_return_if_fail (GDK_IS_PIXBUF (pixbuf));
4302
width = gdk_pixbuf_get_width (pixbuf);
4303
height = gdk_pixbuf_get_height (pixbuf);
4305
/* silently ignore overlarge icons */
4306
if (size + 2 + width * height > GDK_SELECTION_MAX_SIZE(display))
4308
g_warning ("gdk_window_set_icon_list: icons too large");
4313
size += 2 + width * height;
4315
l = g_list_next (l);
4318
data = g_malloc (size * sizeof (gulong));
4326
width = gdk_pixbuf_get_width (pixbuf);
4327
height = gdk_pixbuf_get_height (pixbuf);
4328
stride = gdk_pixbuf_get_rowstride (pixbuf);
4329
n_channels = gdk_pixbuf_get_n_channels (pixbuf);
4334
pixels = gdk_pixbuf_get_pixels (pixbuf);
4336
for (y = 0; y < height; y++)
4338
for (x = 0; x < width; x++)
4342
r = pixels[y*stride + x*n_channels + 0];
4343
g = pixels[y*stride + x*n_channels + 1];
4344
b = pixels[y*stride + x*n_channels + 2];
4345
if (n_channels >= 4)
4346
a = pixels[y*stride + x*n_channels + 3];
4350
*p++ = a << 24 | r << 16 | g << 8 | b ;
4354
l = g_list_next (l);
4360
XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
4361
GDK_WINDOW_XID (window),
4362
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"),
4365
(guchar*) data, size);
4369
XDeleteProperty (GDK_DISPLAY_XDISPLAY (display),
4370
GDK_WINDOW_XID (window),
4371
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON"));
4378
* gdk_window_set_icon:
4379
* @window: a toplevel #GdkWindow
4380
* @icon_window: a #GdkWindow to use for the icon, or %NULL to unset
4381
* @pixmap: a #GdkPixmap to use as the icon, or %NULL to unset
4382
* @mask: a 1-bit pixmap (#GdkBitmap) to use as mask for @pixmap, or %NULL to have none
4384
* Sets the icon of @window as a pixmap or window. If using GTK+, investigate
4385
* gtk_window_set_default_icon_list() first, and then gtk_window_set_icon_list()
4386
* and gtk_window_set_icon(). If those don't meet your needs, look at
4387
* gdk_window_set_icon_list(). Only if all those are too high-level do you
4388
* want to fall back to gdk_window_set_icon().
4392
gdk_window_set_icon (GdkWindow *window,
4393
GdkWindow *icon_window,
4397
GdkToplevelX11 *toplevel;
4399
g_return_if_fail (GDK_IS_WINDOW (window));
4400
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
4402
if (GDK_WINDOW_DESTROYED (window))
4405
toplevel = _gdk_x11_window_get_toplevel (window);
4407
if (toplevel->icon_window != icon_window)
4409
if (toplevel->icon_window)
4410
g_object_unref (toplevel->icon_window);
4411
toplevel->icon_window = g_object_ref (icon_window);
4414
if (toplevel->icon_pixmap != pixmap)
4417
g_object_ref (pixmap);
4418
if (toplevel->icon_pixmap)
4419
g_object_unref (toplevel->icon_pixmap);
4420
toplevel->icon_pixmap = pixmap;
4423
if (toplevel->icon_mask != mask)
4426
g_object_ref (mask);
4427
if (toplevel->icon_mask)
4428
g_object_unref (toplevel->icon_mask);
4429
toplevel->icon_mask = mask;
4432
update_wm_hints (window, FALSE);
4436
gdk_window_icon_name_set (GdkWindow *window)
4438
return GPOINTER_TO_UINT (g_object_get_qdata (G_OBJECT (window),
4439
g_quark_from_static_string ("gdk-icon-name-set")));
4443
* gdk_window_set_icon_name:
4444
* @window: a toplevel #GdkWindow
4445
* @name: name of window while iconified (minimized)
4447
* Windows may have a name used while minimized, distinct from the
4448
* name they display in their titlebar. Most of the time this is a bad
4449
* idea from a user interface standpoint. But you can set such a name
4450
* with this function, if you like.
4454
gdk_window_set_icon_name (GdkWindow *window,
4457
GdkDisplay *display;
4459
g_return_if_fail (GDK_IS_WINDOW (window));
4461
if (GDK_WINDOW_DESTROYED (window))
4464
display = gdk_drawable_get_display (window);
4466
g_object_set_qdata (G_OBJECT (window), g_quark_from_static_string ("gdk-icon-name-set"),
4467
GUINT_TO_POINTER (TRUE));
4469
XChangeProperty (GDK_DISPLAY_XDISPLAY (display),
4470
GDK_WINDOW_XID (window),
4471
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_ICON_NAME"),
4472
gdk_x11_get_xatom_by_name_for_display (display, "UTF8_STRING"), 8,
4473
PropModeReplace, (guchar *)name, strlen (name));
4475
set_text_property (display, GDK_WINDOW_XID (window),
4476
gdk_x11_get_xatom_by_name_for_display (display, "WM_ICON_NAME"),
4481
* gdk_window_iconify:
4482
* @window: a toplevel #GdkWindow
4484
* Asks to iconify (minimize) @window. The window manager may choose
4485
* to ignore the request, but normally will honor it. Using
4486
* gtk_window_iconify() is preferred, if you have a #GtkWindow widget.
4488
* This function only makes sense when @window is a toplevel window.
4492
gdk_window_iconify (GdkWindow *window)
4494
g_return_if_fail (GDK_IS_WINDOW (window));
4496
if (GDK_WINDOW_DESTROYED (window))
4499
if (GDK_WINDOW_IS_MAPPED (window))
4501
XIconifyWindow (GDK_WINDOW_XDISPLAY (window),
4502
GDK_WINDOW_XWINDOW (window),
4503
gdk_screen_get_number (GDK_WINDOW_SCREEN (window)));
4507
/* Flip our client side flag, the real work happens on map. */
4508
gdk_synthesize_window_state (window,
4510
GDK_WINDOW_STATE_ICONIFIED);
4515
* gdk_window_deiconify:
4516
* @window: a toplevel #GdkWindow
4518
* Attempt to deiconify (unminimize) @window. On X11 the window manager may
4519
* choose to ignore the request to deiconify. When using GTK+,
4520
* use gtk_window_deiconify() instead of the #GdkWindow variant. Or better yet,
4521
* you probably want to use gtk_window_present(), which raises the window, focuses it,
4522
* unminimizes it, and puts it on the current desktop.
4526
gdk_window_deiconify (GdkWindow *window)
4528
g_return_if_fail (GDK_IS_WINDOW (window));
4530
if (GDK_WINDOW_DESTROYED (window))
4533
if (GDK_WINDOW_IS_MAPPED (window))
4535
gdk_window_show (window);
4539
/* Flip our client side flag, the real work happens on map. */
4540
gdk_synthesize_window_state (window,
4541
GDK_WINDOW_STATE_ICONIFIED,
4548
* @window: a toplevel #GdkWindow
4550
* "Pins" a window such that it's on all workspaces and does not scroll
4551
* with viewports, for window managers that have scrollable viewports.
4552
* (When using #GtkWindow, gtk_window_stick() may be more useful.)
4554
* On the X11 platform, this function depends on window manager
4555
* support, so may have no effect with many window managers. However,
4556
* GDK will do the best it can to convince the window manager to stick
4557
* the window. For window managers that don't support this operation,
4558
* there's nothing you can do to force it to happen.
4562
gdk_window_stick (GdkWindow *window)
4564
g_return_if_fail (GDK_IS_WINDOW (window));
4566
if (GDK_WINDOW_DESTROYED (window))
4569
if (GDK_WINDOW_IS_MAPPED (window))
4571
/* "stick" means stick to all desktops _and_ do not scroll with the
4572
* viewport. i.e. glue to the monitor glass in all cases.
4575
XClientMessageEvent xclient;
4577
/* Request stick during viewport scroll */
4578
gdk_wmspec_change_state (TRUE, window,
4579
gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
4582
/* Request desktop 0xFFFFFFFF */
4583
memset (&xclient, 0, sizeof (xclient));
4584
xclient.type = ClientMessage;
4585
xclient.window = GDK_WINDOW_XWINDOW (window);
4586
xclient.display = GDK_WINDOW_XDISPLAY (window);
4587
xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window),
4589
xclient.format = 32;
4591
xclient.data.l[0] = 0xFFFFFFFF;
4592
xclient.data.l[1] = 0;
4593
xclient.data.l[2] = 0;
4594
xclient.data.l[3] = 0;
4595
xclient.data.l[4] = 0;
4597
XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False,
4598
SubstructureRedirectMask | SubstructureNotifyMask,
4599
(XEvent *)&xclient);
4603
/* Flip our client side flag, the real work happens on map. */
4604
gdk_synthesize_window_state (window,
4606
GDK_WINDOW_STATE_STICKY);
4611
* gdk_window_unstick:
4612
* @window: a toplevel #GdkWindow
4614
* Reverse operation for gdk_window_stick(); see gdk_window_stick(),
4615
* and gtk_window_unstick().
4619
gdk_window_unstick (GdkWindow *window)
4621
g_return_if_fail (GDK_IS_WINDOW (window));
4623
if (GDK_WINDOW_DESTROYED (window))
4626
if (GDK_WINDOW_IS_MAPPED (window))
4628
/* Request unstick from viewport */
4629
gdk_wmspec_change_state (FALSE, window,
4630
gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
4633
move_to_current_desktop (window);
4637
/* Flip our client side flag, the real work happens on map. */
4638
gdk_synthesize_window_state (window,
4639
GDK_WINDOW_STATE_STICKY,
4646
* gdk_window_maximize:
4647
* @window: a toplevel #GdkWindow
4649
* Maximizes the window. If the window was already maximized, then
4650
* this function does nothing.
4652
* On X11, asks the window manager to maximize @window, if the window
4653
* manager supports this operation. Not all window managers support
4654
* this, and some deliberately ignore it or don't have a concept of
4655
* "maximized"; so you can't rely on the maximization actually
4656
* happening. But it will happen with most standard window managers,
4657
* and GDK makes a best effort to get it to happen.
4659
* On Windows, reliably maximizes the window.
4663
gdk_window_maximize (GdkWindow *window)
4665
g_return_if_fail (GDK_IS_WINDOW (window));
4667
if (GDK_WINDOW_DESTROYED (window))
4670
if (GDK_WINDOW_IS_MAPPED (window))
4671
gdk_wmspec_change_state (TRUE, window,
4672
gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
4673
gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
4675
gdk_synthesize_window_state (window,
4677
GDK_WINDOW_STATE_MAXIMIZED);
4681
* gdk_window_unmaximize:
4682
* @window: a toplevel #GdkWindow
4684
* Unmaximizes the window. If the window wasn't maximized, then this
4685
* function does nothing.
4687
* On X11, asks the window manager to unmaximize @window, if the
4688
* window manager supports this operation. Not all window managers
4689
* support this, and some deliberately ignore it or don't have a
4690
* concept of "maximized"; so you can't rely on the unmaximization
4691
* actually happening. But it will happen with most standard window
4692
* managers, and GDK makes a best effort to get it to happen.
4694
* On Windows, reliably unmaximizes the window.
4698
gdk_window_unmaximize (GdkWindow *window)
4700
g_return_if_fail (GDK_IS_WINDOW (window));
4702
if (GDK_WINDOW_DESTROYED (window))
4705
if (GDK_WINDOW_IS_MAPPED (window))
4706
gdk_wmspec_change_state (FALSE, window,
4707
gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_VERT"),
4708
gdk_atom_intern_static_string ("_NET_WM_STATE_MAXIMIZED_HORZ"));
4710
gdk_synthesize_window_state (window,
4711
GDK_WINDOW_STATE_MAXIMIZED,
4716
* gdk_window_fullscreen:
4717
* @window: a toplevel #GdkWindow
4719
* Moves the window into fullscreen mode. This means the
4720
* window covers the entire screen and is above any panels
4723
* If the window was already fullscreen, then this function does nothing.
4725
* On X11, asks the window manager to put @window in a fullscreen
4726
* state, if the window manager supports this operation. Not all
4727
* window managers support this, and some deliberately ignore it or
4728
* don't have a concept of "fullscreen"; so you can't rely on the
4729
* fullscreenification actually happening. But it will happen with
4730
* most standard window managers, and GDK makes a best effort to get
4736
gdk_window_fullscreen (GdkWindow *window)
4738
g_return_if_fail (GDK_IS_WINDOW (window));
4740
if (GDK_WINDOW_DESTROYED (window))
4743
if (GDK_WINDOW_IS_MAPPED (window))
4744
gdk_wmspec_change_state (TRUE, window,
4745
gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
4749
gdk_synthesize_window_state (window,
4751
GDK_WINDOW_STATE_FULLSCREEN);
4755
* gdk_window_unfullscreen:
4756
* @window: a toplevel #GdkWindow
4758
* Moves the window out of fullscreen mode. If the window was not
4759
* fullscreen, does nothing.
4761
* On X11, asks the window manager to move @window out of the fullscreen
4762
* state, if the window manager supports this operation. Not all
4763
* window managers support this, and some deliberately ignore it or
4764
* don't have a concept of "fullscreen"; so you can't rely on the
4765
* unfullscreenification actually happening. But it will happen with
4766
* most standard window managers, and GDK makes a best effort to get
4772
gdk_window_unfullscreen (GdkWindow *window)
4774
g_return_if_fail (GDK_IS_WINDOW (window));
4776
if (GDK_WINDOW_DESTROYED (window))
4779
if (GDK_WINDOW_IS_MAPPED (window))
4780
gdk_wmspec_change_state (FALSE, window,
4781
gdk_atom_intern_static_string ("_NET_WM_STATE_FULLSCREEN"),
4785
gdk_synthesize_window_state (window,
4786
GDK_WINDOW_STATE_FULLSCREEN,
4791
* gdk_window_set_keep_above:
4792
* @window: a toplevel #GdkWindow
4793
* @setting: whether to keep @window above other windows
4795
* Set if @window must be kept above other windows. If the
4796
* window was already above, then this function does nothing.
4798
* On X11, asks the window manager to keep @window above, if the window
4799
* manager supports this operation. Not all window managers support
4800
* this, and some deliberately ignore it or don't have a concept of
4801
* "keep above"; so you can't rely on the window being kept above.
4802
* But it will happen with most standard window managers,
4803
* and GDK makes a best effort to get it to happen.
4808
gdk_window_set_keep_above (GdkWindow *window, gboolean setting)
4810
g_return_if_fail (GDK_IS_WINDOW (window));
4812
if (GDK_WINDOW_DESTROYED (window))
4815
if (GDK_WINDOW_IS_MAPPED (window))
4818
gdk_wmspec_change_state (FALSE, window,
4819
gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
4821
gdk_wmspec_change_state (setting, window,
4822
gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
4826
gdk_synthesize_window_state (window,
4827
setting ? GDK_WINDOW_STATE_BELOW : GDK_WINDOW_STATE_ABOVE,
4828
setting ? GDK_WINDOW_STATE_ABOVE : 0);
4832
* gdk_window_set_keep_below:
4833
* @window: a toplevel #GdkWindow
4834
* @setting: whether to keep @window below other windows
4836
* Set if @window must be kept below other windows. If the
4837
* window was already below, then this function does nothing.
4839
* On X11, asks the window manager to keep @window below, if the window
4840
* manager supports this operation. Not all window managers support
4841
* this, and some deliberately ignore it or don't have a concept of
4842
* "keep below"; so you can't rely on the window being kept below.
4843
* But it will happen with most standard window managers,
4844
* and GDK makes a best effort to get it to happen.
4849
gdk_window_set_keep_below (GdkWindow *window, gboolean setting)
4851
g_return_if_fail (GDK_IS_WINDOW (window));
4853
if (GDK_WINDOW_DESTROYED (window))
4856
if (GDK_WINDOW_IS_MAPPED (window))
4859
gdk_wmspec_change_state (FALSE, window,
4860
gdk_atom_intern_static_string ("_NET_WM_STATE_ABOVE"),
4862
gdk_wmspec_change_state (setting, window,
4863
gdk_atom_intern_static_string ("_NET_WM_STATE_BELOW"),
4867
gdk_synthesize_window_state (window,
4868
setting ? GDK_WINDOW_STATE_ABOVE : GDK_WINDOW_STATE_BELOW,
4869
setting ? GDK_WINDOW_STATE_BELOW : 0);
4873
* gdk_window_get_group:
4874
* @window: a toplevel #GdkWindow
4876
* Returns the group leader window for @window. See gdk_window_set_group().
4878
* Return value: the group leader window for @window
4883
gdk_window_get_group (GdkWindow *window)
4885
GdkToplevelX11 *toplevel;
4887
g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
4888
g_return_val_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD, NULL);
4890
if (GDK_WINDOW_DESTROYED (window))
4893
toplevel = _gdk_x11_window_get_toplevel (window);
4895
return toplevel->group_leader;
4899
* gdk_window_set_group:
4900
* @window: a toplevel #GdkWindow
4901
* @leader: group leader window, or %NULL to restore the default group leader window
4903
* Sets the group leader window for @window. By default,
4904
* GDK sets the group leader for all toplevel windows
4905
* to a global window implicitly created by GDK. With this function
4906
* you can override this default.
4908
* The group leader window allows the window manager to distinguish
4909
* all windows that belong to a single application. It may for example
4910
* allow users to minimize/unminimize all windows belonging to an
4911
* application at once. You should only set a non-default group window
4912
* if your application pretends to be multiple applications.
4915
gdk_window_set_group (GdkWindow *window,
4918
GdkToplevelX11 *toplevel;
4920
g_return_if_fail (GDK_IS_WINDOW (window));
4921
g_return_if_fail (GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD);
4922
g_return_if_fail (leader == NULL || GDK_IS_WINDOW (leader));
4924
if (GDK_WINDOW_DESTROYED (window) || (leader != NULL && GDK_WINDOW_DESTROYED (leader)))
4927
toplevel = _gdk_x11_window_get_toplevel (window);
4930
leader = gdk_display_get_default_group (gdk_drawable_get_display (window));
4932
if (toplevel->group_leader != leader)
4934
if (toplevel->group_leader)
4935
g_object_unref (toplevel->group_leader);
4936
toplevel->group_leader = g_object_ref (leader);
4937
(_gdk_x11_window_get_toplevel (leader))->is_leader = TRUE;
4940
update_wm_hints (window, FALSE);
4943
static MotifWmHints *
4944
gdk_window_get_mwm_hints (GdkWindow *window)
4946
GdkDisplay *display;
4947
Atom hints_atom = None;
4954
if (GDK_WINDOW_DESTROYED (window))
4957
display = gdk_drawable_get_display (window);
4959
hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4961
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XID (window),
4962
hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4963
False, AnyPropertyType, &type, &format, &nitems,
4964
&bytes_after, &data);
4969
return (MotifWmHints *)data;
4973
gdk_window_set_mwm_hints (GdkWindow *window,
4974
MotifWmHints *new_hints)
4976
GdkDisplay *display;
4977
Atom hints_atom = None;
4979
MotifWmHints *hints;
4985
if (GDK_WINDOW_DESTROYED (window))
4988
display = gdk_drawable_get_display (window);
4990
hints_atom = gdk_x11_get_xatom_by_name_for_display (display, _XA_MOTIF_WM_HINTS);
4992
XGetWindowProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
4993
hints_atom, 0, sizeof (MotifWmHints)/sizeof (long),
4994
False, AnyPropertyType, &type, &format, &nitems,
4995
&bytes_after, &data);
5001
hints = (MotifWmHints *)data;
5003
if (new_hints->flags & MWM_HINTS_FUNCTIONS)
5005
hints->flags |= MWM_HINTS_FUNCTIONS;
5006
hints->functions = new_hints->functions;
5008
if (new_hints->flags & MWM_HINTS_DECORATIONS)
5010
hints->flags |= MWM_HINTS_DECORATIONS;
5011
hints->decorations = new_hints->decorations;
5015
XChangeProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window),
5016
hints_atom, hints_atom, 32, PropModeReplace,
5017
(guchar *)hints, sizeof (MotifWmHints)/sizeof (long));
5019
if (hints != new_hints)
5024
* gdk_window_set_decorations:
5025
* @window: a toplevel #GdkWindow
5026
* @decorations: decoration hint mask
5028
* "Decorations" are the features the window manager adds to a toplevel #GdkWindow.
5029
* This function sets the traditional Motif window manager hints that tell the
5030
* window manager which decorations you would like your window to have.
5031
* Usually you should use gtk_window_set_decorated() on a #GtkWindow instead of
5032
* using the GDK function directly.
5034
* The @decorations argument is the logical OR of the fields in
5035
* the #GdkWMDecoration enumeration. If #GDK_DECOR_ALL is included in the
5036
* mask, the other bits indicate which decorations should be turned off.
5037
* If #GDK_DECOR_ALL is not included, then the other bits indicate
5038
* which decorations should be turned on.
5040
* Most window managers honor a decorations hint of 0 to disable all decorations,
5041
* but very few honor all possible combinations of bits.
5045
gdk_window_set_decorations (GdkWindow *window,
5046
GdkWMDecoration decorations)
5050
g_return_if_fail (GDK_IS_WINDOW (window));
5052
/* initialize to zero to avoid writing uninitialized data to socket */
5053
memset(&hints, 0, sizeof(hints));
5054
hints.flags = MWM_HINTS_DECORATIONS;
5055
hints.decorations = decorations;
5057
gdk_window_set_mwm_hints (window, &hints);
5061
* gdk_window_get_decorations:
5062
* @window: The toplevel #GdkWindow to get the decorations from
5063
* @decorations: The window decorations will be written here
5065
* Returns the decorations set on the GdkWindow with #gdk_window_set_decorations
5066
* Returns: TRUE if the window has decorations set, FALSE otherwise.
5069
gdk_window_get_decorations(GdkWindow *window,
5070
GdkWMDecoration *decorations)
5072
MotifWmHints *hints;
5073
gboolean result = FALSE;
5075
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
5077
hints = gdk_window_get_mwm_hints (window);
5081
if (hints->flags & MWM_HINTS_DECORATIONS)
5084
*decorations = hints->decorations;
5095
* gdk_window_set_functions:
5096
* @window: a toplevel #GdkWindow
5097
* @functions: bitmask of operations to allow on @window
5099
* Sets hints about the window management functions to make available
5100
* via buttons on the window frame.
5102
* On the X backend, this function sets the traditional Motif window
5103
* manager hint for this purpose. However, few window managers do
5104
* anything reliable or interesting with this hint. Many ignore it
5107
* The @functions argument is the logical OR of values from the
5108
* #GdkWMFunction enumeration. If the bitmask includes #GDK_FUNC_ALL,
5109
* then the other bits indicate which functions to disable; if
5110
* it doesn't include #GDK_FUNC_ALL, it indicates which functions to
5115
gdk_window_set_functions (GdkWindow *window,
5116
GdkWMFunction functions)
5120
g_return_if_fail (GDK_IS_WINDOW (window));
5122
/* initialize to zero to avoid writing uninitialized data to socket */
5123
memset(&hints, 0, sizeof(hints));
5124
hints.flags = MWM_HINTS_FUNCTIONS;
5125
hints.functions = functions;
5127
gdk_window_set_mwm_hints (window, &hints);
5130
#ifdef HAVE_SHAPE_EXT
5133
* propagate the shapes from all child windows of a GDK window to the parent
5134
* window. Shamelessly ripped from Enlightenment's code
5142
struct _gdk_span *next;
5146
gdk_add_to_span (struct _gdk_span **s,
5150
struct _gdk_span *ptr1, *ptr2, *noo, *ss;
5157
/* scan the spans for this line */
5160
/* -- -> new span */
5161
/* == -> existing span */
5162
/* ## -> spans intersect */
5163
/* if we are in the middle of spanning the span into the line */
5166
/* case: ---- ==== */
5167
if (xx < ptr1->start - 1)
5169
/* ends before next span - extend to here */
5173
/* case: ----##=== */
5174
else if (xx <= ptr1->end)
5176
/* crosses into next span - delete next span and append */
5177
ss->end = ptr1->end;
5178
ss->next = ptr1->next;
5182
/* case: ---###--- */
5185
/* overlaps next span - delete and keep checking */
5186
ss->next = ptr1->next;
5191
/* otherwise havent started spanning it in yet */
5194
/* case: ---- ==== */
5195
if (xx < ptr1->start - 1)
5197
/* insert span here in list */
5198
noo = g_malloc (sizeof (struct _gdk_span));
5212
/* case: ----##=== */
5213
else if ((x < ptr1->start) && (xx <= ptr1->end))
5215
/* expand this span to the left point of the new one */
5219
/* case: ===###=== */
5220
else if ((x >= ptr1->start) && (xx <= ptr1->end))
5222
/* throw the span away */
5225
/* case: ---###--- */
5226
else if ((x < ptr1->start) && (xx > ptr1->end))
5233
/* case: ===##---- */
5234
else if ((x >= ptr1->start) && (x <= ptr1->end + 1) && (xx > ptr1->end))
5240
/* case: ==== ---- */
5241
/* case handled by next loop iteration - first case */
5246
/* it started in the middle but spans beyond your current list */
5252
/* it does not start inside a span or in the middle, so add it to the end */
5253
noo = g_malloc (sizeof (struct _gdk_span));
5261
noo->next = ptr2->next;
5274
gdk_add_rectangles (Display *disp,
5276
struct _gdk_span **spans,
5283
gint x1, y1, x2, y2;
5287
rl = XShapeGetRectangles (disp, win, ShapeBounding, &rn, &ord);
5290
/* go through all clip rects in this window's shape */
5291
for (k = 0; k < rn; k++)
5293
/* for each clip rect, add it to each line's spans */
5295
x2 = x + rl[k].x + (rl[k].width - 1);
5297
y2 = y + rl[k].y + (rl[k].height - 1);
5306
for (a = y1; a <= y2; a++)
5309
gdk_add_to_span (&spans[a], x1, x2);
5317
gdk_propagate_shapes (Display *disp,
5322
Window rt, par, *list = NULL;
5323
gint i, j, num = 0, num_rects = 0;
5327
XRectangle *rects = NULL;
5328
struct _gdk_span **spans = NULL, *ptr1, *ptr2, *ptr3;
5329
XWindowAttributes xatt;
5331
XGetGeometry (disp, win, &rt, &x, &y, &w, &h, &d, &d);
5336
spans = g_malloc (sizeof (struct _gdk_span *) * h);
5338
for (i = 0; i < h; i++)
5340
XQueryTree (disp, win, &rt, &par, &list, (unsigned int *)&num);
5343
/* go through all child windows and create/insert spans */
5344
for (i = 0; i < num; i++)
5346
if (XGetWindowAttributes (disp, list[i], &xatt) && (xatt.map_state != IsUnmapped))
5347
if (XGetGeometry (disp, list[i], &rt, &x, &y, &w, &h, &d, &d))
5348
gdk_add_rectangles (disp, list[i], spans, basew, baseh, x, y);
5351
gdk_add_rectangles (disp, win, spans, basew, baseh, x, y);
5353
/* go through the spans list and build a list of rects */
5354
rects = g_malloc (sizeof (XRectangle) * 256);
5356
for (i = 0; i < baseh; i++)
5359
/* go through the line for all spans */
5362
rects[num_rects].x = ptr1->start;
5363
rects[num_rects].y = i;
5364
rects[num_rects].width = ptr1->end - ptr1->start + 1;
5365
rects[num_rects].height = 1;
5367
/* if there are more lines */
5369
/* while contigous rects (same start/end coords) exist */
5370
while ((contig) && (j < baseh))
5372
/* search next line for spans matching this one */
5378
/* if we have an exact span match set contig */
5379
if ((ptr2->start == ptr1->start) &&
5380
(ptr2->end == ptr1->end))
5383
/* remove the span - not needed */
5386
ptr3->next = ptr2->next;
5392
spans[j] = ptr2->next;
5398
/* gone past the span point no point looking */
5399
else if (ptr2->start < ptr1->start)
5407
/* if a contiguous span was found increase the rect h */
5410
rects[num_rects].height++;
5414
/* up the rect count */
5416
/* every 256 new rects increase the rect array */
5417
if ((num_rects % 256) == 0)
5418
rects = g_realloc (rects, sizeof (XRectangle) * (num_rects + 256));
5422
/* set the rects as the shape mask */
5425
XShapeCombineRectangles (disp, win, shape, 0, 0, rects, num_rects,
5426
ShapeSet, YXSorted);
5431
/* free up all the spans we made */
5432
for (i = 0; i < baseh; i++)
5445
#endif /* HAVE_SHAPE_EXT */
5448
* gdk_window_set_child_shapes:
5449
* @window: a #GdkWindow
5451
* Sets the shape mask of @window to the union of shape masks
5452
* for all children of @window, ignoring the shape mask of @window
5453
* itself. Contrast with gdk_window_merge_child_shapes() which includes
5454
* the shape mask of @window in the masks to be merged.
5457
gdk_window_set_child_shapes (GdkWindow *window)
5459
g_return_if_fail (GDK_IS_WINDOW (window));
5462
#ifdef HAVE_SHAPE_EXT
5463
if (!GDK_WINDOW_DESTROYED (window) &&
5464
gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
5465
gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
5466
GDK_WINDOW_XID (window), FALSE, ShapeBounding);
5471
* gdk_window_merge_child_shapes:
5472
* @window: a #GdkWindow
5474
* Merges the shape masks for any child windows into the
5475
* shape mask for @window. i.e. the union of all masks
5476
* for @window and its children will become the new mask
5477
* for @window. See gdk_window_shape_combine_mask().
5479
* This function is distinct from gdk_window_set_child_shapes()
5480
* because it includes @window's shape mask in the set of shapes to
5484
gdk_window_merge_child_shapes (GdkWindow *window)
5486
g_return_if_fail (GDK_IS_WINDOW (window));
5488
#ifdef HAVE_SHAPE_EXT
5489
if (!GDK_WINDOW_DESTROYED (window) &&
5490
gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
5491
gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
5492
GDK_WINDOW_XID (window), TRUE, ShapeBounding);
5497
* gdk_window_set_child_input_shapes:
5498
* @window: a #GdkWindow
5500
* Sets the input shape mask of @window to the union of input shape masks
5501
* for all children of @window, ignoring the input shape mask of @window
5502
* itself. Contrast with gdk_window_merge_child_input_shapes() which includes
5503
* the input shape mask of @window in the masks to be merged.
5508
gdk_window_set_child_input_shapes (GdkWindow *window)
5510
g_return_if_fail (GDK_IS_WINDOW (window));
5512
#ifdef HAVE_SHAPE_EXT
5514
if (!GDK_WINDOW_DESTROYED (window) &&
5515
gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
5516
gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
5517
GDK_WINDOW_XID (window), FALSE, ShapeInput);
5523
* gdk_window_merge_child_input_shapes:
5524
* @window: a #GdkWindow
5526
* Merges the input shape masks for any child windows into the
5527
* input shape mask for @window. i.e. the union of all input masks
5528
* for @window and its children will become the new input mask
5529
* for @window. See gdk_window_input_shape_combine_mask().
5531
* This function is distinct from gdk_window_set_child_input_shapes()
5532
* because it includes @window's input shape mask in the set of
5533
* shapes to be merged.
5538
gdk_window_merge_child_input_shapes (GdkWindow *window)
5540
g_return_if_fail (GDK_IS_WINDOW (window));
5542
#ifdef HAVE_SHAPE_EXT
5544
if (!GDK_WINDOW_DESTROYED (window) &&
5545
gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
5546
gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
5547
GDK_WINDOW_XID (window), TRUE, ShapeInput);
5554
gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
5556
XSetWindowAttributes xattributes;
5557
GdkWindowObject *private;
5558
guint xattributes_mask = 0;
5560
g_return_if_fail (GDK_IS_WINDOW (window));
5562
private = GDK_WINDOW_OBJECT (window);
5563
if (private->input_only)
5566
xattributes.bit_gravity = StaticGravity;
5567
xattributes_mask |= CWBitGravity;
5568
xattributes.bit_gravity = on ? StaticGravity : ForgetGravity;
5569
XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
5570
GDK_WINDOW_XID (window),
5571
CWBitGravity, &xattributes);
5575
gdk_window_set_static_win_gravity (GdkWindow *window, gboolean on)
5577
XSetWindowAttributes xattributes;
5579
g_return_if_fail (GDK_IS_WINDOW (window));
5581
xattributes.win_gravity = on ? StaticGravity : NorthWestGravity;
5583
XChangeWindowAttributes (GDK_WINDOW_XDISPLAY (window),
5584
GDK_WINDOW_XID (window),
5585
CWWinGravity, &xattributes);
5589
* gdk_window_set_static_gravities:
5590
* @window: a #GdkWindow
5591
* @use_static: %TRUE to turn on static gravity
5593
* Set the bit gravity of the given window to static, and flag it so
5594
* all children get static subwindow gravity. This is used if you are
5595
* implementing scary features that involve deep knowledge of the
5596
* windowing system. Don't worry about it unless you have to.
5598
* Return value: %TRUE if the server supports static gravity
5601
gdk_window_set_static_gravities (GdkWindow *window,
5602
gboolean use_static)
5604
GdkWindowObject *private = (GdkWindowObject *)window;
5607
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
5609
if (!use_static == !private->guffaw_gravity)
5612
private->guffaw_gravity = use_static;
5614
if (!GDK_WINDOW_DESTROYED (window))
5616
gdk_window_set_static_bit_gravity (window, use_static);
5618
tmp_list = private->children;
5621
gdk_window_set_static_win_gravity (tmp_list->data, use_static);
5623
tmp_list = tmp_list->next;
5631
wmspec_moveresize (GdkWindow *window,
5637
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
5639
XClientMessageEvent xclient;
5641
/* Release passive grab */
5642
gdk_display_pointer_ungrab (display, timestamp);
5644
memset (&xclient, 0, sizeof (xclient));
5645
xclient.type = ClientMessage;
5646
xclient.window = GDK_WINDOW_XID (window);
5647
xclient.message_type =
5648
gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_MOVERESIZE");
5649
xclient.format = 32;
5650
xclient.data.l[0] = root_x;
5651
xclient.data.l[1] = root_y;
5652
xclient.data.l[2] = direction;
5653
xclient.data.l[3] = 0;
5654
xclient.data.l[4] = 0;
5656
XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
5657
SubstructureRedirectMask | SubstructureNotifyMask,
5658
(XEvent *)&xclient);
5661
typedef struct _MoveResizeData MoveResizeData;
5663
struct _MoveResizeData
5665
GdkDisplay *display;
5667
GdkWindow *moveresize_window;
5668
GdkWindow *moveresize_emulation_window;
5670
GdkWindowEdge resize_edge;
5671
gint moveresize_button;
5674
gint moveresize_orig_x;
5675
gint moveresize_orig_y;
5676
gint moveresize_orig_width;
5677
gint moveresize_orig_height;
5678
GdkWindowHints moveresize_geom_mask;
5679
GdkGeometry moveresize_geometry;
5680
Time moveresize_process_time;
5681
XEvent *moveresize_pending_event;
5684
/* From the WM spec */
5685
#define _NET_WM_MOVERESIZE_SIZE_TOPLEFT 0
5686
#define _NET_WM_MOVERESIZE_SIZE_TOP 1
5687
#define _NET_WM_MOVERESIZE_SIZE_TOPRIGHT 2
5688
#define _NET_WM_MOVERESIZE_SIZE_RIGHT 3
5689
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT 4
5690
#define _NET_WM_MOVERESIZE_SIZE_BOTTOM 5
5691
#define _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6
5692
#define _NET_WM_MOVERESIZE_SIZE_LEFT 7
5693
#define _NET_WM_MOVERESIZE_MOVE 8
5696
wmspec_resize_drag (GdkWindow *window,
5705
/* Let the compiler turn a switch into a table, instead
5706
* of doing the table manually, this way is easier to verify.
5710
case GDK_WINDOW_EDGE_NORTH_WEST:
5711
direction = _NET_WM_MOVERESIZE_SIZE_TOPLEFT;
5714
case GDK_WINDOW_EDGE_NORTH:
5715
direction = _NET_WM_MOVERESIZE_SIZE_TOP;
5718
case GDK_WINDOW_EDGE_NORTH_EAST:
5719
direction = _NET_WM_MOVERESIZE_SIZE_TOPRIGHT;
5722
case GDK_WINDOW_EDGE_WEST:
5723
direction = _NET_WM_MOVERESIZE_SIZE_LEFT;
5726
case GDK_WINDOW_EDGE_EAST:
5727
direction = _NET_WM_MOVERESIZE_SIZE_RIGHT;
5730
case GDK_WINDOW_EDGE_SOUTH_WEST:
5731
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT;
5734
case GDK_WINDOW_EDGE_SOUTH:
5735
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOM;
5738
case GDK_WINDOW_EDGE_SOUTH_EAST:
5739
direction = _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT;
5743
g_warning ("gdk_window_begin_resize_drag: bad resize edge %d!",
5749
wmspec_moveresize (window, direction, root_x, root_y, timestamp);
5752
static MoveResizeData *
5753
get_move_resize_data (GdkDisplay *display,
5756
MoveResizeData *mv_resize;
5757
static GQuark move_resize_quark = 0;
5759
if (!move_resize_quark)
5760
move_resize_quark = g_quark_from_static_string ("gdk-window-moveresize");
5762
mv_resize = g_object_get_qdata (G_OBJECT (display), move_resize_quark);
5764
if (!mv_resize && create)
5766
mv_resize = g_new0 (MoveResizeData, 1);
5767
mv_resize->display = display;
5769
g_object_set_qdata (G_OBJECT (display), move_resize_quark, mv_resize);
5776
update_pos (MoveResizeData *mv_resize,
5782
dx = new_root_x - mv_resize->moveresize_x;
5783
dy = new_root_y - mv_resize->moveresize_y;
5785
if (mv_resize->is_resize)
5789
x = mv_resize->moveresize_orig_x;
5790
y = mv_resize->moveresize_orig_y;
5792
w = mv_resize->moveresize_orig_width;
5793
h = mv_resize->moveresize_orig_height;
5795
switch (mv_resize->resize_edge)
5797
case GDK_WINDOW_EDGE_NORTH_WEST:
5803
case GDK_WINDOW_EDGE_NORTH:
5807
case GDK_WINDOW_EDGE_NORTH_EAST:
5812
case GDK_WINDOW_EDGE_SOUTH_WEST:
5817
case GDK_WINDOW_EDGE_SOUTH_EAST:
5821
case GDK_WINDOW_EDGE_SOUTH:
5824
case GDK_WINDOW_EDGE_EAST:
5827
case GDK_WINDOW_EDGE_WEST:
5838
if (mv_resize->moveresize_geom_mask)
5840
gdk_window_constrain_size (&mv_resize->moveresize_geometry,
5841
mv_resize->moveresize_geom_mask,
5845
gdk_window_move_resize (mv_resize->moveresize_window, x, y, w, h);
5851
x = mv_resize->moveresize_orig_x + dx;
5852
y = mv_resize->moveresize_orig_y + dy;
5854
gdk_window_move (mv_resize->moveresize_window, x, y);
5859
finish_drag (MoveResizeData *mv_resize)
5861
gdk_window_destroy (mv_resize->moveresize_emulation_window);
5862
mv_resize->moveresize_emulation_window = NULL;
5863
g_object_unref (mv_resize->moveresize_window);
5864
mv_resize->moveresize_window = NULL;
5866
if (mv_resize->moveresize_pending_event)
5868
g_free (mv_resize->moveresize_pending_event);
5869
mv_resize->moveresize_pending_event = NULL;
5874
lookahead_motion_predicate (Display *xdisplay,
5878
gboolean *seen_release = (gboolean *)arg;
5879
GdkDisplay *display = gdk_x11_lookup_xdisplay (xdisplay);
5880
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5885
switch (event->xany.type)
5888
*seen_release = TRUE;
5891
mv_resize->moveresize_process_time = event->xmotion.time;
5901
moveresize_lookahead (MoveResizeData *mv_resize,
5905
gboolean seen_release = FALSE;
5907
if (mv_resize->moveresize_process_time)
5909
if (event->xmotion.time == mv_resize->moveresize_process_time)
5911
mv_resize->moveresize_process_time = 0;
5918
XCheckIfEvent (event->xany.display, &tmp_event,
5919
lookahead_motion_predicate, (XPointer) & seen_release);
5921
return mv_resize->moveresize_process_time == 0;
5925
_gdk_moveresize_handle_event (XEvent *event)
5927
guint button_mask = 0;
5928
GdkWindowObject *window_private;
5929
GdkDisplay *display = gdk_x11_lookup_xdisplay (event->xany.display);
5930
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5932
if (!mv_resize || !mv_resize->moveresize_window)
5935
window_private = (GdkWindowObject *) mv_resize->moveresize_window;
5937
button_mask = GDK_BUTTON1_MASK << (mv_resize->moveresize_button - 1);
5939
switch (event->xany.type)
5942
if (window_private->resize_count > 0)
5944
if (mv_resize->moveresize_pending_event)
5945
*mv_resize->moveresize_pending_event = *event;
5947
mv_resize->moveresize_pending_event =
5948
g_memdup (event, sizeof (XEvent));
5952
if (!moveresize_lookahead (mv_resize, event))
5955
update_pos (mv_resize,
5956
event->xmotion.x_root,
5957
event->xmotion.y_root);
5959
/* This should never be triggered in normal cases, but in the
5960
* case where the drag started without an implicit grab being
5961
* in effect, we could miss the release if it occurs before
5962
* we grab the pointer; this ensures that we will never
5963
* get a permanently stuck grab.
5965
if ((event->xmotion.state & button_mask) == 0)
5966
finish_drag (mv_resize);
5970
update_pos (mv_resize,
5971
event->xbutton.x_root,
5972
event->xbutton.y_root);
5974
if (event->xbutton.button == mv_resize->moveresize_button)
5975
finish_drag (mv_resize);
5982
_gdk_moveresize_configure_done (GdkDisplay *display,
5986
MoveResizeData *mv_resize = get_move_resize_data (display, FALSE);
5988
if (!mv_resize || window != mv_resize->moveresize_window)
5991
if (mv_resize->moveresize_pending_event)
5993
tmp_event = mv_resize->moveresize_pending_event;
5994
mv_resize->moveresize_pending_event = NULL;
5995
_gdk_moveresize_handle_event (tmp_event);
6003
create_moveresize_window (MoveResizeData *mv_resize,
6006
GdkWindowAttr attributes;
6007
gint attributes_mask;
6008
GdkGrabStatus status;
6010
g_assert (mv_resize->moveresize_emulation_window == NULL);
6012
attributes.x = -100;
6013
attributes.y = -100;
6014
attributes.width = 10;
6015
attributes.height = 10;
6016
attributes.window_type = GDK_WINDOW_TEMP;
6017
attributes.wclass = GDK_INPUT_ONLY;
6018
attributes.override_redirect = TRUE;
6019
attributes.event_mask = 0;
6021
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_NOREDIR;
6023
mv_resize->moveresize_emulation_window =
6024
gdk_window_new (gdk_screen_get_root_window (gdk_display_get_default_screen (mv_resize->display)),
6028
gdk_window_show (mv_resize->moveresize_emulation_window);
6030
status = gdk_pointer_grab (mv_resize->moveresize_emulation_window,
6032
GDK_BUTTON_RELEASE_MASK |
6033
GDK_POINTER_MOTION_MASK,
6038
if (status != GDK_GRAB_SUCCESS)
6040
/* If this fails, some other client has grabbed the window
6043
finish_drag (mv_resize);
6046
mv_resize->moveresize_process_time = 0;
6050
Calculate mv_resize->moveresize_orig_x and mv_resize->moveresize_orig_y
6051
so that calling XMoveWindow with these coordinates will not move the
6053
Note that this depends on the WM to implement ICCCM-compliant reference
6057
calculate_unmoving_origin (MoveResizeData *mv_resize)
6062
if (mv_resize->moveresize_geom_mask & GDK_HINT_WIN_GRAVITY &&
6063
mv_resize->moveresize_geometry.win_gravity == GDK_GRAVITY_STATIC)
6065
gdk_window_get_origin (mv_resize->moveresize_window,
6066
&mv_resize->moveresize_orig_x,
6067
&mv_resize->moveresize_orig_y);
6071
gdk_window_get_frame_extents (mv_resize->moveresize_window, &rect);
6072
gdk_window_get_geometry (mv_resize->moveresize_window,
6073
NULL, NULL, &width, &height, NULL);
6075
switch (mv_resize->moveresize_geometry.win_gravity)
6077
case GDK_GRAVITY_NORTH_WEST:
6078
mv_resize->moveresize_orig_x = rect.x;
6079
mv_resize->moveresize_orig_y = rect.y;
6081
case GDK_GRAVITY_NORTH:
6082
mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
6083
mv_resize->moveresize_orig_y = rect.y;
6085
case GDK_GRAVITY_NORTH_EAST:
6086
mv_resize->moveresize_orig_x = rect.x + rect.width - width;
6087
mv_resize->moveresize_orig_y = rect.y;
6089
case GDK_GRAVITY_WEST:
6090
mv_resize->moveresize_orig_x = rect.x;
6091
mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
6093
case GDK_GRAVITY_CENTER:
6094
mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
6095
mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
6097
case GDK_GRAVITY_EAST:
6098
mv_resize->moveresize_orig_x = rect.x + rect.width - width;
6099
mv_resize->moveresize_orig_y = rect.y + rect.height / 2 - height / 2;
6101
case GDK_GRAVITY_SOUTH_WEST:
6102
mv_resize->moveresize_orig_x = rect.x;
6103
mv_resize->moveresize_orig_y = rect.y + rect.height - height;
6105
case GDK_GRAVITY_SOUTH:
6106
mv_resize->moveresize_orig_x = rect.x + rect.width / 2 - width / 2;
6107
mv_resize->moveresize_orig_y = rect.y + rect.height - height;
6109
case GDK_GRAVITY_SOUTH_EAST:
6110
mv_resize->moveresize_orig_x = rect.x + rect.width - width;
6111
mv_resize->moveresize_orig_y = rect.y + rect.height - height;
6114
mv_resize->moveresize_orig_x = rect.x;
6115
mv_resize->moveresize_orig_y = rect.y;
6122
emulate_resize_drag (GdkWindow *window,
6129
MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
6131
mv_resize->is_resize = TRUE;
6132
mv_resize->moveresize_button = button;
6133
mv_resize->resize_edge = edge;
6134
mv_resize->moveresize_x = root_x;
6135
mv_resize->moveresize_y = root_y;
6136
mv_resize->moveresize_window = g_object_ref (window);
6138
gdk_drawable_get_size (window,
6139
&mv_resize->moveresize_orig_width,
6140
&mv_resize->moveresize_orig_height);
6142
mv_resize->moveresize_geom_mask = 0;
6143
gdk_window_get_geometry_hints (window,
6144
&mv_resize->moveresize_geometry,
6145
&mv_resize->moveresize_geom_mask);
6147
calculate_unmoving_origin (mv_resize);
6149
create_moveresize_window (mv_resize, timestamp);
6153
emulate_move_drag (GdkWindow *window,
6159
MoveResizeData *mv_resize = get_move_resize_data (GDK_WINDOW_DISPLAY (window), TRUE);
6161
mv_resize->is_resize = FALSE;
6162
mv_resize->moveresize_button = button;
6163
mv_resize->moveresize_x = root_x;
6164
mv_resize->moveresize_y = root_y;
6166
mv_resize->moveresize_window = g_object_ref (window);
6168
calculate_unmoving_origin (mv_resize);
6170
create_moveresize_window (mv_resize, timestamp);
6174
* gdk_window_begin_resize_drag:
6175
* @window: a toplevel #GdkWindow
6176
* @edge: the edge or corner from which the drag is started
6177
* @button: the button being used to drag
6178
* @root_x: root window X coordinate of mouse click that began the drag
6179
* @root_y: root window Y coordinate of mouse click that began the drag
6180
* @timestamp: timestamp of mouse click that began the drag (use gdk_event_get_time())
6182
* Begins a window resize operation (for a toplevel window).
6183
* You might use this function to implement a "window resize grip," for
6184
* example; in fact #GtkStatusbar uses it. The function works best
6185
* with window managers that support the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended Window Manager Hints</ulink>, but has a
6186
* fallback implementation for other window managers.
6190
gdk_window_begin_resize_drag (GdkWindow *window,
6197
g_return_if_fail (GDK_IS_WINDOW (window));
6199
if (GDK_WINDOW_DESTROYED (window))
6202
if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
6203
gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
6204
wmspec_resize_drag (window, edge, button, root_x, root_y, timestamp);
6206
emulate_resize_drag (window, edge, button, root_x, root_y, timestamp);
6210
* gdk_window_begin_move_drag:
6211
* @window: a toplevel #GdkWindow
6212
* @button: the button being used to drag
6213
* @root_x: root window X coordinate of mouse click that began the drag
6214
* @root_y: root window Y coordinate of mouse click that began the drag
6215
* @timestamp: timestamp of mouse click that began the drag
6217
* Begins a window move operation (for a toplevel window). You might
6218
* use this function to implement a "window move grip," for
6219
* example. The function works best with window managers that support
6220
* the <ulink url="http://www.freedesktop.org/Standards/wm-spec">Extended
6221
* Window Manager Hints</ulink>, but has a fallback implementation for
6222
* other window managers.
6226
gdk_window_begin_move_drag (GdkWindow *window,
6232
g_return_if_fail (GDK_IS_WINDOW (window));
6234
if (GDK_WINDOW_DESTROYED (window))
6237
if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
6238
gdk_atom_intern_static_string ("_NET_WM_MOVERESIZE")))
6239
wmspec_moveresize (window, _NET_WM_MOVERESIZE_MOVE, root_x, root_y,
6242
emulate_move_drag (window, button, root_x, root_y, timestamp);
6246
* gdk_window_enable_synchronized_configure:
6247
* @window: a toplevel #GdkWindow
6249
* Indicates that the application will cooperate with the window
6250
* system in synchronizing the window repaint with the window
6251
* manager during resizing operations. After an application calls
6252
* this function, it must call gdk_window_configure_finished() every
6253
* time it has finished all processing associated with a set of
6254
* Configure events. Toplevel GTK+ windows automatically use this
6257
* On X, calling this function makes @window participate in the
6258
* _NET_WM_SYNC_REQUEST window manager protocol.
6263
gdk_window_enable_synchronized_configure (GdkWindow *window)
6265
GdkWindowObject *private = (GdkWindowObject *)window;
6266
GdkWindowImplX11 *impl;
6268
g_return_if_fail (GDK_IS_WINDOW (window));
6270
impl = GDK_WINDOW_IMPL_X11 (private->impl);
6272
if (!impl->use_synchronized_configure)
6274
impl->use_synchronized_configure = TRUE;
6275
ensure_sync_counter (window);
6280
* gdk_window_configure_finished:
6281
* @window: a toplevel #GdkWindow
6283
* Signal to the window system that the application has finished
6284
* handling Configure events it has received. Window Managers can
6285
* use this to better synchronize the frame repaint with the
6286
* application. GTK+ applications will automatically call this
6287
* function when appropriate.
6289
* This function can only be called if gdk_window_enable_synchronized_configure()
6290
* was called previously.
6295
gdk_window_configure_finished (GdkWindow *window)
6297
GdkWindowImplX11 *impl;
6299
g_return_if_fail (GDK_IS_WINDOW (window));
6301
impl = GDK_WINDOW_IMPL_X11 (((GdkWindowObject *)window)->impl);
6302
if (!impl->use_synchronized_configure)
6306
if (!GDK_WINDOW_DESTROYED (window))
6308
GdkDisplay *display = GDK_WINDOW_DISPLAY (window);
6309
GdkToplevelX11 *toplevel = _gdk_x11_window_get_toplevel (window);
6311
if (toplevel && toplevel->update_counter != None &&
6312
GDK_DISPLAY_X11 (display)->use_sync &&
6313
!XSyncValueIsZero (toplevel->current_counter_value))
6315
XSyncSetCounter (GDK_WINDOW_XDISPLAY (window),
6316
toplevel->update_counter,
6317
toplevel->current_counter_value);
6319
XSyncIntToValue (&toplevel->current_counter_value, 0);
6325
#define __GDK_WINDOW_X11_C__
6326
#include "gdkaliasdef.c"