diff options
Diffstat (limited to 'gdk/x11/gdkwindow-x11.c')
-rw-r--r-- | gdk/x11/gdkwindow-x11.c | 225 |
1 files changed, 138 insertions, 87 deletions
diff --git a/gdk/x11/gdkwindow-x11.c b/gdk/x11/gdkwindow-x11.c index 13799250a..ffd8d583e 100644 --- a/gdk/x11/gdkwindow-x11.c +++ b/gdk/x11/gdkwindow-x11.c @@ -33,6 +33,7 @@ #include "config.h" #include "gdkwindow.h" +#include "gdkasync.h" #include "gdkinputprivate.h" #include "gdkdisplay-x11.h" #include "gdkprivate-x11.h" @@ -283,12 +284,6 @@ _gdk_windowing_window_init (GdkScreen * screen) GdkWindowImplX11 *impl; GdkDrawableImplX11 *draw_impl; GdkScreenX11 *screen_x11; - XWindowAttributes xattributes; - unsigned int width; - unsigned int height; - unsigned int border_width; - unsigned int depth; - int x, y; screen_x11 = GDK_SCREEN_X11 (screen); @@ -297,10 +292,6 @@ _gdk_windowing_window_init (GdkScreen * screen) gdk_screen_set_default_colormap (screen, gdk_screen_get_system_colormap (screen)); - XGetGeometry (screen_x11->xdisplay, screen_x11->xroot_window, - &screen_x11->xroot_window, &x, &y, &width, &height, &border_width, &depth); - XGetWindowAttributes (screen_x11->xdisplay, screen_x11->xroot_window, &xattributes); - screen_x11->root_window = g_object_new (GDK_TYPE_WINDOW, NULL); private = (GdkWindowObject *)screen_x11->root_window; impl = GDK_WINDOW_IMPL_X11 (private->impl); @@ -313,10 +304,10 @@ _gdk_windowing_window_init (GdkScreen * screen) g_object_ref (draw_impl->colormap); private->window_type = GDK_WINDOW_ROOT; - private->depth = depth; + private->depth = DefaultDepthOfScreen (screen_x11->xscreen); - impl->width = width; - impl->height = height; + impl->width = WidthOfScreen (screen_x11->xscreen); + impl->height = HeightOfScreen (screen_x11->xscreen); _gdk_window_init_position (GDK_WINDOW (private)); @@ -400,7 +391,6 @@ gdk_window_new (GdkWindow *parent, XSetWindowAttributes xattributes; long xattributes_mask; XSizeHints size_hints; - XWMHints wm_hints; XClassHint *class_hint; int x, y, depth; @@ -659,19 +649,12 @@ gdk_window_new (GdkWindow *parent, check_leader_window_title (screen_x11->display); - wm_hints.flags = StateHint | WindowGroupHint; - wm_hints.window_group = GDK_DISPLAY_X11 (screen_x11->display)->leader_window; - wm_hints.input = True; - wm_hints.initial_state = NormalState; - /* FIXME: Is there any point in doing this? Do any WM's pay * attention to PSize, and even if they do, is this the * correct value??? */ XSetWMNormalHints (xdisplay, xid, &size_hints); - XSetWMHints (xdisplay, xid, &wm_hints); - /* This will set WM_CLIENT_MACHINE and WM_LOCALE_NAME */ XSetWMProperties (xdisplay, xid, NULL, NULL, NULL, 0, NULL, NULL, NULL); @@ -855,14 +838,38 @@ _gdk_windowing_window_destroy (GdkWindow *window, gboolean foreign_destroy) { GdkWindowObject *private = (GdkWindowObject *)window; - + GdkWindowImplX11 *window_impl; + g_return_if_fail (GDK_IS_WINDOW (window)); + window_impl = GDK_WINDOW_IMPL_X11 (private->impl); + _gdk_selection_window_destroyed (window); if (private->extension_events != 0) _gdk_input_window_destroy (window); + if (window_impl->icon_window) + { + g_object_unref (window_impl->icon_window); + window_impl->icon_window = NULL; + } + if (window_impl->icon_pixmap) + { + g_object_unref (window_impl->icon_pixmap); + window_impl->icon_pixmap = NULL; + } + if (window_impl->icon_mask) + { + g_object_unref (window_impl->icon_mask); + window_impl->icon_mask = NULL; + } + if (window_impl->group_leader) + { + g_object_unref (window_impl->group_leader); + window_impl->group_leader = NULL; + } + #ifdef HAVE_XFT { GdkDrawableImplX11 *draw_impl = GDK_DRAWABLE_IMPL_X11 (private->impl); @@ -945,6 +952,61 @@ gdk_window_destroy_notify (GdkWindow *window) } static void +update_wm_hints (GdkWindow *window, + gboolean force) +{ + GdkWindowObject *private = (GdkWindowObject *)window; + GdkWindowImplX11 *impl = GDK_WINDOW_IMPL_X11 (private->impl); + GdkDisplay *display = GDK_WINDOW_DISPLAY (window); + XWMHints wm_hints; + + if (!force && + private->state & GDK_WINDOW_STATE_WITHDRAWN) + return; + + wm_hints.flags = StateHint; + wm_hints.input = True; + wm_hints.initial_state = NormalState; + + if (private->state & GDK_WINDOW_STATE_ICONIFIED) + { + wm_hints.flags |= StateHint; + wm_hints.initial_state = IconicState; + } + + if (impl->icon_window && !GDK_WINDOW_DESTROYED (impl->icon_window)) + { + wm_hints.flags |= IconWindowHint; + wm_hints.icon_window = GDK_WINDOW_XID (impl->icon_window); + } + + if (impl->icon_pixmap) + { + wm_hints.flags |= IconPixmapHint; + wm_hints.icon_pixmap = GDK_PIXMAP_XID (impl->icon_pixmap); + } + + if (impl->icon_mask) + { + wm_hints.flags |= IconMaskHint; + wm_hints.icon_mask = GDK_PIXMAP_XID (impl->icon_mask); + } + + wm_hints.flags |= WindowGroupHint; + if (impl->group_leader && !GDK_WINDOW_DESTROYED (impl->group_leader)) + { + wm_hints.flags |= WindowGroupHint; + wm_hints.window_group = GDK_WINDOW_XID (impl->group_leader); + } + else + wm_hints.window_group = GDK_DISPLAY_X11 (display)->leader_window; + + XSetWMHints (GDK_WINDOW_XDISPLAY (window), + GDK_WINDOW_XID (window), + &wm_hints); +} + +static void set_initial_hints (GdkWindow *window) { GdkDisplay *display = GDK_WINDOW_DISPLAY (window); @@ -957,22 +1019,9 @@ set_initial_hints (GdkWindow *window) private = (GdkWindowObject*) window; impl = GDK_WINDOW_IMPL_X11 (private->impl); - - if (private->state & GDK_WINDOW_STATE_ICONIFIED) - { - XWMHints *wm_hints; - - wm_hints = XGetWMHints (xdisplay, xwindow); - if (!wm_hints) - wm_hints = XAllocWMHints (); - - wm_hints->flags |= StateHint; - wm_hints->initial_state = IconicState; - - XSetWMHints (xdisplay, xwindow, wm_hints); - XFree (wm_hints); - } + update_wm_hints (window, TRUE); + /* We set the spec hints regardless of whether the spec is supported, * since it can't hurt and it's kind of expensive to check whether * it's supported. @@ -1068,9 +1117,12 @@ show_window_internal (GdkWindow *window, private = (GdkWindowObject*) window; if (!private->destroyed) { + GdkWindowImplX11 *impl =GDK_WINDOW_IMPL_X11 (private->impl); + Display *xdisplay = GDK_WINDOW_XDISPLAY (window); + Window xwindow = GDK_WINDOW_XID (window); + if (raise) - XRaiseWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); + XRaiseWindow (xdisplay, xwindow); if (!GDK_WINDOW_IS_MAPPED (window)) { @@ -1079,13 +1131,14 @@ show_window_internal (GdkWindow *window, gdk_synthesize_window_state (window, GDK_WINDOW_STATE_WITHDRAWN, 0); + + impl->map_serial = NextRequest (xdisplay); } g_assert (GDK_WINDOW_IS_MAPPED (window)); - - if (GDK_WINDOW_IMPL_X11 (private->impl)->position_info.mapped) - XMapWindow (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); + + if (impl->position_info.mapped) + XMapWindow (xdisplay, xwindow); } } @@ -1550,11 +1603,15 @@ void gdk_window_focus (GdkWindow *window, guint32 timestamp) { + GdkDisplay *display; + g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; + display = GDK_WINDOW_DISPLAY (window); + if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window), gdk_atom_intern ("_NET_ACTIVE_WINDOW", FALSE))) { @@ -1564,7 +1621,7 @@ gdk_window_focus (GdkWindow *window, xev.xclient.serial = 0; xev.xclient.send_event = True; xev.xclient.window = GDK_WINDOW_XWINDOW (window); - xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (GDK_WINDOW_DISPLAY (window), + xev.xclient.message_type = gdk_x11_get_xatom_by_name_for_display (display, "_NET_ACTIVE_WINDOW"); xev.xclient.format = 32; xev.xclient.data.l[0] = 0; @@ -1573,24 +1630,20 @@ gdk_window_focus (GdkWindow *window, xev.xclient.data.l[3] = 0; xev.xclient.data.l[4] = 0; - XSendEvent (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XROOTWIN (window), False, + XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } else { - XRaiseWindow (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XID (window)); + XRaiseWindow (GDK_DISPLAY_XDISPLAY (window), GDK_WINDOW_XID (window)); - /* There is no way of knowing reliably whether we are viewable so we need - * to trap errors so we don't cause a BadMatch. + /* There is no way of knowing reliably whether we are viewable; + * _gdk_x11_set_input_focus_safe() traps errors asynchronously. */ - gdk_error_trap_push (); - XSetInputFocus (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XWINDOW (window), - RevertToParent, - timestamp); - XSync (GDK_WINDOW_XDISPLAY (window), False); - gdk_error_trap_pop (); + _gdk_x11_set_input_focus_safe (display, GDK_WINDOW_XID (window), + RevertToParent, + timestamp); } } @@ -3277,40 +3330,40 @@ gdk_window_set_icon (GdkWindow *window, GdkPixmap *pixmap, GdkBitmap *mask) { - XWMHints *wm_hints; - + GdkWindowObject *private; + GdkWindowImplX11 *impl; + g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); if (GDK_WINDOW_DESTROYED (window)) return; - wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); - if (!wm_hints) - wm_hints = XAllocWMHints (); + private = (GdkWindowObject *)window; + impl = GDK_WINDOW_IMPL_X11 (private->impl); - if (icon_window != NULL) + if (impl->icon_window != icon_window) { - wm_hints->flags |= IconWindowHint; - wm_hints->icon_window = GDK_WINDOW_XID (icon_window); + if (impl->icon_window) + g_object_unref (impl->icon_window); + impl->icon_window = g_object_ref (icon_window); } - if (pixmap != NULL) + if (impl->icon_pixmap != pixmap) { - wm_hints->flags |= IconPixmapHint; - wm_hints->icon_pixmap = GDK_PIXMAP_XID (pixmap); + if (impl->icon_pixmap) + g_object_unref (impl->icon_pixmap); + impl->icon_pixmap = g_object_ref (pixmap); } - if (mask != NULL) + if (impl->icon_mask != mask) { - wm_hints->flags |= IconMaskHint; - wm_hints->icon_mask = GDK_PIXMAP_XID (mask); + if (impl->icon_mask) + g_object_unref (impl->icon_mask); + impl->icon_mask = g_object_ref (mask); } - - XSetWMHints (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), wm_hints); - XFree (wm_hints); + + update_wm_hints (window, FALSE); } static gboolean @@ -3733,15 +3786,13 @@ gdk_window_unfullscreen (GdkWindow *window) * allow users to minimize/unminimize all windows belonging to an * application at once. You should only set a non-default group window * if your application pretends to be multiple applications. - * The group leader window may not be changed after a window has been - * mapped (with gdk_window_show() for example). - * **/ void gdk_window_set_group (GdkWindow *window, GdkWindow *leader) { - XWMHints *wm_hints; + GdkWindowObject *private; + GdkWindowImplX11 *impl; g_return_if_fail (window != NULL); g_return_if_fail (GDK_IS_WINDOW (window)); @@ -3751,17 +3802,17 @@ gdk_window_set_group (GdkWindow *window, if (GDK_WINDOW_DESTROYED (window) || GDK_WINDOW_DESTROYED (leader)) return; - wm_hints = XGetWMHints (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window)); - if (!wm_hints) - wm_hints = XAllocWMHints (); + private = (GdkWindowObject *)window; + impl = GDK_WINDOW_IMPL_X11 (private->impl); - wm_hints->flags |= WindowGroupHint; - wm_hints->window_group = GDK_WINDOW_XID (leader); + if (impl->group_leader != leader) + { + if (impl->group_leader) + g_object_unref (impl->group_leader); + impl->group_leader = g_object_ref (impl->group_leader); + } - XSetWMHints (GDK_WINDOW_XDISPLAY (window), - GDK_WINDOW_XID (window), wm_hints); - XFree (wm_hints); + update_wm_hints (window, FALSE); } static MotifWmHints * |