/* Forward declarations */
static void gdk_window_set_static_win_gravity (GdkWindow *window,
gboolean on);
-static gboolean gdk_window_have_shape_ext (GdkDisplay *display);
static gboolean gdk_window_icon_name_set (GdkWindow *window);
static void gdk_window_add_colormap_windows (GdkWindow *window);
static void set_wm_name (GdkDisplay *display,
Window xwindow,
const gchar *name);
+static void move_to_current_desktop (GdkWindow *window);
static GdkColormap* gdk_window_impl_x11_get_colormap (GdkDrawable *drawable);
static void gdk_window_impl_x11_set_colormap (GdkDrawable *drawable,
gint *width,
gint *height);
static GdkRegion* gdk_window_impl_x11_get_visible_region (GdkDrawable *drawable);
-static void gdk_window_impl_x11_init (GdkWindowImplX11 *window);
-static void gdk_window_impl_x11_class_init (GdkWindowImplX11Class *klass);
static void gdk_window_impl_x11_finalize (GObject *object);
-static gpointer parent_class = NULL;
-
#define WINDOW_IS_TOPLEVEL(window) \
(GDK_WINDOW_TYPE (window) != GDK_WINDOW_CHILD && \
GDK_WINDOW_TYPE (window) != GDK_WINDOW_FOREIGN)
(( time1 < time2 ) && ( time2 - time1 > ((guint32)-1)/2 )) \
)
-GType
-gdk_window_impl_x11_get_type (void)
-{
- static GType object_type = 0;
-
- if (!object_type)
- {
- static const GTypeInfo object_info =
- {
- sizeof (GdkWindowImplX11Class),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) gdk_window_impl_x11_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GdkWindowImplX11),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gdk_window_impl_x11_init,
- };
-
- object_type = g_type_register_static (GDK_TYPE_DRAWABLE_IMPL_X11,
- g_intern_static_string ("GdkWindowImplX11"),
- &object_info, 0);
- }
-
- return object_type;
-}
+G_DEFINE_TYPE (GdkWindowImplX11, gdk_window_impl_x11, GDK_TYPE_DRAWABLE_IMPL_X11)
GType
_gdk_window_impl_get_type (void)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkDrawableClass *drawable_class = GDK_DRAWABLE_CLASS (klass);
- parent_class = g_type_class_peek_parent (klass);
-
object_class->finalize = gdk_window_impl_x11_finalize;
drawable_class->set_colormap = gdk_window_impl_x11_set_colormap;
if (window_impl->cursor)
gdk_cursor_unref (window_impl->cursor);
- G_OBJECT_CLASS (parent_class)->finalize (object);
+ G_OBJECT_CLASS (gdk_window_impl_x11_parent_class)->finalize (object);
}
static void
}
}
+/* Unsetting and resetting window backgrounds.
+ *
+ * In many cases it is possible to avoid flicker by unsetting the
+ * background of windows. For example if the background of the
+ * parent window is unset when a window is unmapped, a brief flicker
+ * of background painting is avoided.
+ */
void
_gdk_x11_window_tmp_unset_bg (GdkWindow *window,
gboolean recurse)
return;
/* chain up */
- GDK_DRAWABLE_CLASS (parent_class)->set_colormap (drawable, cmap);
+ GDK_DRAWABLE_CLASS (gdk_window_impl_x11_parent_class)->set_colormap (drawable, cmap);
if (cmap)
{
else
private->window_type = attributes->window_type;
+ /* Work around a bug where Xorg refuses to map toplevel InputOnly windows
+ * from an untrusted client: http://bugs.freedesktop.org/show_bug.cgi?id=6988
+ */
+ if (attributes->wclass == GDK_INPUT_ONLY &&
+ GDK_WINDOW_TYPE (parent) == GDK_WINDOW_ROOT &&
+ !G_LIKELY (GDK_DISPLAY_X11 (GDK_WINDOW_DISPLAY (parent))->trusted_client))
+ {
+ g_warning ("Coercing GDK_INPUT_ONLY toplevel window to GDK_INPUT_OUTPUT to work around bug in Xorg server");
+ attributes->wclass = GDK_INPUT_OUTPUT;
+ }
+
_gdk_window_init_position (GDK_WINDOW (private));
if (impl->position_info.big)
private->guffaw_gravity = TRUE;
Window xwindow = GDK_WINDOW_XID (window);
GdkWindowObject *private;
GdkToplevelX11 *toplevel;
- Atom atoms[7];
+ Atom atoms[9];
gint i;
private = (GdkWindowObject*) window;
if (toplevel->on_all_desktops)
return;
+
+ move_to_current_desktop (window);
+}
+static void
+move_to_current_desktop (GdkWindow *window)
+{
if (gdk_x11_screen_supports_net_wm_hint (GDK_WINDOW_SCREEN (window),
gdk_atom_intern_static_string ("_NET_WM_DESKTOP")))
{
case GDK_WINDOW_TYPE_HINT_DESKTOP:
atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP");
break;
+ case GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU");
+ break;
+ case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU");
+ break;
+ case GDK_WINDOW_TYPE_HINT_TOOLTIP:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP");
+ break;
+ case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION");
+ break;
+ case GDK_WINDOW_TYPE_HINT_COMBO:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO");
+ break;
+ case GDK_WINDOW_TYPE_HINT_DND:
+ atom = gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND");
+ break;
default:
g_warning ("Unknown hint %d passed to gdk_window_set_type_hint", hint);
/* Fall thru */
if ((type_return == XA_ATOM) && (format_return == 32) &&
(data) && (nitems_return == 1))
{
- Atom atom = (Atom) *data;
+ Atom atom = *(Atom*)data;
if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DIALOG"))
type = GDK_WINDOW_TYPE_HINT_DIALOG;
type = GDK_WINDOW_TYPE_HINT_DOCK;
else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DESKTOP"))
type = GDK_WINDOW_TYPE_HINT_DESKTOP;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU"))
+ type = GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_POPUP_MENU"))
+ type = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_TOOLTIP"))
+ type = GDK_WINDOW_TYPE_HINT_TOOLTIP;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_NOTIFICATION"))
+ type = GDK_WINDOW_TYPE_HINT_NOTIFICATION;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_COMBO"))
+ type = GDK_WINDOW_TYPE_HINT_COMBO;
+ else if (atom == gdk_x11_get_xatom_by_name_for_display (display, "_NET_WM_WINDOW_TYPE_DND"))
+ type = GDK_WINDOW_TYPE_HINT_DND;
}
if (type_return != None && data != NULL)
GdkModifierType *mask)
{
GdkScreen *default_screen;
+ Display *xdisplay;
+ Window xwindow;
Window root = None;
Window child;
int rootx, rooty;
return;
default_screen = gdk_display_get_default_screen (display);
+
+ xdisplay = GDK_SCREEN_XDISPLAY (default_screen);
+ xwindow = GDK_SCREEN_XROOTWIN (default_screen);
- XQueryPointer (GDK_SCREEN_XDISPLAY (default_screen),
- GDK_SCREEN_XROOTWIN (default_screen),
- &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
+ if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
+ {
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
+ }
+ else
+ {
+ XSetWindowAttributes attributes;
+ Window w;
+
+ w = XCreateWindow (xdisplay, xwindow, 0, 0, 1, 1, 0,
+ CopyFromParent, InputOnly, CopyFromParent,
+ 0, &attributes);
+ XQueryPointer (xdisplay, w,
+ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
+ XDestroyWindow (xdisplay, w);
+ }
if (root != None)
{
_gdk_windowing_window_get_offsets (window, &xoffset, &yoffset);
return_val = NULL;
- if (!GDK_WINDOW_DESTROYED (window) &&
- XQueryPointer (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window),
- &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
+ if (!GDK_WINDOW_DESTROYED (window))
{
- if (child)
- return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child);
+ if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
+ {
+ if (XQueryPointer (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window),
+ &root, &child, &rootx, &rooty, &winx, &winy, &xmask))
+ {
+ if (child)
+ return_val = gdk_window_lookup_for_display (GDK_WINDOW_DISPLAY (window), child);
+ }
+ }
+ else
+ {
+ GdkScreen *screen;
+ int originx, originy;
+ _gdk_windowing_get_pointer (gdk_drawable_get_display (window), &screen,
+ &rootx, &rooty, &xmask);
+ gdk_window_get_origin (window, &originx, &originy);
+ winx = rootx - originx;
+ winy = rooty - originy;
+ }
}
*x = winx + xoffset;
* and the result.
*/
gdk_x11_display_grab (display);
- XQueryPointer (xdisplay, xwindow,
- &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
-
- if (root == xwindow)
- xwindow = child;
- else
- xwindow = root;
-
- while (xwindow)
+ if (G_LIKELY (GDK_DISPLAY_X11 (display)->trusted_client))
{
- xwindow_last = xwindow;
XQueryPointer (xdisplay, xwindow,
- &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
+ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
+ if (root == xwindow)
+ xwindow = child;
+ else
+ xwindow = root;
+
+ while (xwindow)
+ {
+ xwindow_last = xwindow;
+ XQueryPointer (xdisplay, xwindow,
+ &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
+ }
+ }
+ else
+ {
+ gint i, screens, width, height;
+ GList *toplevels, *list;
+ Window pointer_window;
+
+ pointer_window = None;
+ screens = gdk_display_get_n_screens (display);
+ for (i = 0; i < screens; ++i) {
+ screen = gdk_display_get_screen (display, i);
+ toplevels = gdk_screen_get_toplevel_windows (screen);
+ for (list = toplevels; list != NULL; list = g_list_next (list)) {
+ window = GDK_WINDOW (list->data);
+ xwindow = GDK_WINDOW_XWINDOW (window);
+ gdk_error_trap_push ();
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
+ gdk_flush ();
+ if (gdk_error_trap_pop ())
+ continue;
+ if (child != None)
+ {
+ pointer_window = child;
+ break;
+ }
+ gdk_window_get_geometry (window, NULL, NULL, &width, &height, NULL);
+ if (winx >= 0 && winy >= 0 && winx < width && winy < height)
+ {
+ /* A childless toplevel, or below another window? */
+ XSetWindowAttributes attributes;
+ Window w;
+
+ w = XCreateWindow (xdisplay, xwindow, winx, winy, 1, 1, 0,
+ CopyFromParent, InputOnly, CopyFromParent,
+ 0, &attributes);
+ XMapWindow (xdisplay, w);
+ XQueryPointer (xdisplay, xwindow,
+ &root, &child, &rootx, &rooty, &winx, &winy, &xmask);
+ XDestroyWindow (xdisplay, w);
+ if (child == w)
+ {
+ pointer_window = xwindow;
+ break;
+ }
+ }
+ }
+ g_list_free (toplevels);
+ if (pointer_window != None)
+ break;
+ }
+ xwindow = pointer_window;
+
+ while (xwindow)
+ {
+ xwindow_last = xwindow;
+ gdk_error_trap_push ();
+ XQueryPointer (xdisplay, xwindow,
+ &root, &xwindow, &rootx, &rooty, &winx, &winy, &xmask);
+ gdk_flush ();
+ if (gdk_error_trap_pop ())
+ break;
+ }
}
+
gdk_x11_display_ungrab (display);
- window = gdk_window_lookup_for_display (GDK_SCREEN_DISPLAY(screen),
- xwindow_last);
+ window = gdk_window_lookup_for_display (display, xwindow_last);
*win_x = window ? winx : -1;
*win_y = window ? winy : -1;
XFree (old_windows);
}
-static gboolean
-gdk_window_have_shape_ext (GdkDisplay *display)
-{
-#ifdef HAVE_SHAPE_EXT
- int ignore;
-
- return XShapeQueryExtension (GDK_DISPLAY_XDISPLAY (display),
- &ignore, &ignore);
-#else
- return 0;
-#endif
-}
-
#define WARN_SHAPE_TOO_BIG() g_warning ("GdkWindow is too large to allow the use of shape masks or shape regions.")
/*
* If not available, shaped windows will look
* ugly, but programs still work. Stefan Wille
*/
-/**
- * gdk_window_shape_combine_mask:
- * @window: a #GdkWindow
- * @mask: shape mask
- * @x: X position of shape mask with respect to @window
- * @y: Y position of shape mask with respect to @window
- *
- * Applies a shape mask to @window. Pixels in @window corresponding to
- * set bits in the @mask will be visible; pixels in @window
- * corresponding to unset bits in the @mask will be transparent. This
- * gives a non-rectangular window.
- *
- * If @mask is %NULL, the shape mask will be unset, and the @x/@y
- * parameters are not used.
- *
- * On the X11 platform, this uses an X server extension which is
- * widely available on most common platforms, but not available on
- * very old X servers, and occasionally the implementation will be
- * buggy. On servers without the shape extension, this function
- * will do nothing.
- *
- * This function works on both toplevel and child windows.
- *
- **/
-void
-gdk_window_shape_combine_mask (GdkWindow *window,
- GdkBitmap *mask,
- gint x, gint y)
+static void
+do_shape_combine_mask (GdkWindow *window,
+ GdkBitmap *mask,
+ gint x,
+ gint y,
+ gint shape)
{
GdkWindowObject *private = (GdkWindowObject *)window;
Pixmap pixmap;
return;
}
- if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ if (shape == ShapeBounding
+ ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
+ : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
{
if (mask)
{
pixmap = GDK_PIXMAP_XID (mask);
- private->shaped = TRUE;
+ private->shaped = (shape == ShapeBounding);
}
else
{
XShapeCombineMask (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
- ShapeBounding,
+ shape,
x, y,
pixmap,
ShapeSet);
}
/**
- * gdk_window_shape_combine_region:
+ * gdk_window_shape_combine_mask:
* @window: a #GdkWindow
- * @shape_region: region of window to be non-transparent
- * @offset_x: X position of @shape_region in @window coordinates
- * @offset_y: Y position of @shape_region in @window coordinates
+ * @mask: shape mask
+ * @x: X position of shape mask with respect to @window
+ * @y: Y position of shape mask with respect to @window
*
- * Makes pixels in @window outside @shape_region be transparent,
- * so that the window may be nonrectangular. See also
- * gdk_window_shape_combine_mask() to use a bitmap as the mask.
+ * Applies a shape mask to @window. Pixels in @window corresponding to
+ * set bits in the @mask will be visible; pixels in @window
+ * corresponding to unset bits in the @mask will be transparent. This
+ * gives a non-rectangular window.
+ *
+ * If @mask is %NULL, the shape mask will be unset, and the @x/@y
+ * parameters are not used.
*
- * If @shape_region is %NULL, the shape will be unset, so the whole
- * window will be opaque again. @offset_x and @offset_y are ignored
- * if @shape_region is %NULL.
- *
* On the X11 platform, this uses an X server extension which is
* widely available on most common platforms, but not available on
* very old X servers, and occasionally the implementation will be
*
**/
void
-gdk_window_shape_combine_region (GdkWindow *window,
- GdkRegion *shape_region,
- gint offset_x,
- gint offset_y)
-{
+gdk_window_shape_combine_mask (GdkWindow *window,
+ GdkBitmap *mask,
+ gint x,
+ gint y)
+{
+ do_shape_combine_mask (window, mask, x, y, ShapeBounding);
+}
+
+/**
+ * gdk_window_input_shape_combine_mask:
+ * @window: a #GdkWindow
+ * @mask: shape mask
+ * @x: X position of shape mask with respect to @window
+ * @y: Y position of shape mask with respect to @window
+ *
+ * Like gdk_window_shape_combine_mask(), but the shape applies
+ * only to event handling. Mouse events which happen while
+ * the pointer position corresponds to an unset bit in the
+ * mask will be passed on the window below @window.
+ *
+ * An input shape is typically used with RGBA windows.
+ * The alpha channel of the window defines which pixels are
+ * invisible and allows for nicely antialiased borders,
+ * and the input shape controls where the window is
+ * "clickable".
+ *
+ * On the X11 platform, this requires version 1.1 of the
+ * shape extension.
+ *
+ * Since: 2.10
+ */
+void
+gdk_window_input_shape_combine_mask (GdkWindow *window,
+ GdkBitmap *mask,
+ gint x,
+ gint y)
+{
+#ifdef ShapeInput
+ do_shape_combine_mask (window, mask, x, y, ShapeInput);
+#endif
+}
+
+
+static void
+do_shape_combine_region (GdkWindow *window,
+ GdkRegion *shape_region,
+ gint offset_x,
+ gint offset_y,
+ gint shape)
+{
GdkWindowObject *private = (GdkWindowObject *)window;
gint xoffset, yoffset;
return;
}
- if (gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ if (shape == ShapeBounding
+ ? gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window))
+ : gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
{
gint n_rects = 0;
XRectangle *xrects = NULL;
- private->shaped = TRUE;
+ private->shaped = shape == ShapeBounding;
_gdk_region_get_xrectangles (shape_region,
0, 0,
XShapeCombineRectangles (GDK_WINDOW_XDISPLAY (window),
GDK_WINDOW_XID (window),
- ShapeBounding,
+ shape,
offset_x, offset_y,
xrects, n_rects,
ShapeSet,
#endif /* HAVE_SHAPE_EXT */
}
+/**
+ * gdk_window_shape_combine_region:
+ * @window: a #GdkWindow
+ * @shape_region: region of window to be non-transparent
+ * @offset_x: X position of @shape_region in @window coordinates
+ * @offset_y: Y position of @shape_region in @window coordinates
+ *
+ * Makes pixels in @window outside @shape_region be transparent,
+ * so that the window may be nonrectangular. See also
+ * gdk_window_shape_combine_mask() to use a bitmap as the mask.
+ *
+ * If @shape_region is %NULL, the shape will be unset, so the whole
+ * window will be opaque again. @offset_x and @offset_y are ignored
+ * if @shape_region is %NULL.
+ *
+ * On the X11 platform, this uses an X server extension which is
+ * widely available on most common platforms, but not available on
+ * very old X servers, and occasionally the implementation will be
+ * buggy. On servers without the shape extension, this function
+ * will do nothing.
+ *
+ * This function works on both toplevel and child windows.
+ *
+ **/
+void
+gdk_window_shape_combine_region (GdkWindow *window,
+ GdkRegion *shape_region,
+ gint offset_x,
+ gint offset_y)
+{
+ do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeBounding);
+}
+
+/**
+ * gdk_window_input_shape_combine_region:
+ * @window: a #GdkWindow
+ * @shape_region: region of window to be non-transparent
+ * @offset_x: X position of @shape_region in @window coordinates
+ * @offset_y: Y position of @shape_region in @window coordinates
+ *
+ * Like gdk_window_shape_combine_region(), but the shape applies
+ * only to event handling. Mouse events which happen while
+ * the pointer position corresponds to an unset bit in the
+ * mask will be passed on the window below @window.
+ *
+ * An input shape is typically used with RGBA windows.
+ * The alpha channel of the window defines which pixels are
+ * invisible and allows for nicely antialiased borders,
+ * and the input shape controls where the window is
+ * "clickable".
+ *
+ * On the X11 platform, this requires version 1.1 of the
+ * shape extension.
+ *
+ * Since: 2.10
+ */
+void
+gdk_window_input_shape_combine_region (GdkWindow *window,
+ GdkRegion *shape_region,
+ gint offset_x,
+ gint offset_y)
+{
+#ifdef ShapeInput
+ do_shape_combine_region (window, shape_region, offset_x, offset_y, ShapeInput);
+#endif
+}
+
/**
* gdk_window_set_override_redirect:
toplevel->user_time = timestamp_long;
}
+#define GDK_SELECTION_MAX_SIZE(display) \
+ MIN(262144, \
+ XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) == 0 \
+ ? XMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100 \
+ : XExtendedMaxRequestSize (GDK_DISPLAY_XDISPLAY (display)) - 100)
+
/**
* gdk_window_set_icon_list:
* @window: The #GdkWindow toplevel window to set the icon of.
gint x, y;
gint n_channels;
GdkDisplay *display;
+ gint n;
g_return_if_fail (GDK_IS_WINDOW (window));
l = pixbufs;
size = 0;
-
+ n = 0;
while (l)
{
pixbuf = l->data;
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
+ /* silently ignore overlarge icons */
+ if (size + 2 + width * height > GDK_SELECTION_MAX_SIZE(display))
+ {
+ g_warning ("gdk_window_set_icon_list: icons too large");
+ break;
+ }
+
+ n++;
size += 2 + width * height;
-
+
l = g_list_next (l);
}
l = pixbufs;
p = data;
- while (l)
+ while (l && n > 0)
{
pixbuf = l->data;
}
l = g_list_next (l);
+ n--;
}
if (size > 0)
if (GDK_WINDOW_IS_MAPPED (window))
{
- XEvent xev;
- Atom type;
- gint format;
- gulong nitems;
- gulong bytes_after;
- guchar *data;
- gulong *current_desktop;
- GdkDisplay *display = gdk_drawable_get_display (window);
-
/* Request unstick from viewport */
gdk_wmspec_change_state (FALSE, window,
gdk_atom_intern_static_string ("_NET_WM_STATE_STICKY"),
NULL);
- /* Get current desktop, then set it; this is a race, but not
- * one that matters much in practice.
- */
- XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window),
- gdk_x11_get_xatom_by_name_for_display (display, "_NET_CURRENT_DESKTOP"),
- 0, G_MAXLONG,
- False, XA_CARDINAL, &type, &format, &nitems,
- &bytes_after, &data);
-
- if (type == XA_CARDINAL)
- {
- current_desktop = (gulong *)data;
-
- xev.xclient.type = ClientMessage;
- 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 (display, "_NET_WM_DESKTOP");
- xev.xclient.format = 32;
-
- xev.xclient.data.l[0] = *current_desktop;
- xev.xclient.data.l[1] = 0;
- xev.xclient.data.l[2] = 0;
- xev.xclient.data.l[3] = 0;
- xev.xclient.data.l[4] = 0;
-
- XSendEvent (GDK_DISPLAY_XDISPLAY (display), GDK_WINDOW_XROOTWIN (window), False,
- SubstructureRedirectMask | SubstructureNotifyMask,
- &xev);
-
- XFree (current_desktop);
- }
+ move_to_current_desktop (window);
}
else
{
g_return_if_fail (GDK_IS_WINDOW (window));
+ /* initialize to zero to avoid writing uninitialized data to socket */
+ memset(&hints, 0, sizeof(hints));
hints.flags = MWM_HINTS_DECORATIONS;
hints.decorations = decorations;
* @window: a toplevel #GdkWindow
* @functions: bitmask of operations to allow on @window
*
- * This function isn't really good for much. It sets the traditional
- * Motif window manager hint for which operations the window manager
- * should allow on a toplevel window. However, few window managers do
+ * Sets hints about the window management functions to make available
+ * via buttons on the window frame.
+ *
+ * On the X backend, this function sets the traditional Motif window
+ * manager hint for this purpose. However, few window managers do
* anything reliable or interesting with this hint. Many ignore it
* entirely.
*
g_return_if_fail (GDK_IS_WINDOW (window));
+ /* initialize to zero to avoid writing uninitialized data to socket */
+ memset(&hints, 0, sizeof(hints));
hints.flags = MWM_HINTS_FUNCTIONS;
hints.functions = functions;
static void
gdk_propagate_shapes (Display *disp,
Window win,
- gboolean merge)
+ gboolean merge,
+ int shape)
{
Window rt, par, *list = NULL;
gint i, j, num = 0, num_rects = 0;
/* set the rects as the shape mask */
if (rects)
{
- XShapeCombineRectangles (disp, win, ShapeBounding, 0, 0, rects, num_rects,
+ XShapeCombineRectangles (disp, win, shape, 0, 0, rects, num_rects,
ShapeSet, YXSorted);
g_free (rects);
}
{
g_return_if_fail (GDK_IS_WINDOW (window));
+
#ifdef HAVE_SHAPE_EXT
if (!GDK_WINDOW_DESTROYED (window) &&
- gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window), FALSE);
+ GDK_WINDOW_XID (window), FALSE, ShapeBounding);
#endif
}
* This function is distinct from gdk_window_set_child_shapes()
* because it includes @window's shape mask in the set of shapes to
* be merged.
- *
**/
void
gdk_window_merge_child_shapes (GdkWindow *window)
#ifdef HAVE_SHAPE_EXT
if (!GDK_WINDOW_DESTROYED (window) &&
- gdk_window_have_shape_ext (GDK_WINDOW_DISPLAY (window)))
+ gdk_display_supports_shapes (GDK_WINDOW_DISPLAY (window)))
gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
- GDK_WINDOW_XID (window), TRUE);
+ GDK_WINDOW_XID (window), TRUE, ShapeBounding);
#endif
}
+/**
+ * gdk_window_set_child_input_shapes:
+ * @window: a #GdkWindow
+ *
+ * Sets the input shape mask of @window to the union of input shape masks
+ * for all children of @window, ignoring the input shape mask of @window
+ * itself. Contrast with gdk_window_merge_child_input_shapes() which includes
+ * the input shape mask of @window in the masks to be merged.
+ *
+ * Since: 2.10
+ **/
+void
+gdk_window_set_child_input_shapes (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_SHAPE_EXT
+#ifdef ShapeInput
+ if (!GDK_WINDOW_DESTROYED (window) &&
+ gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
+ gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window), FALSE, ShapeInput);
+#endif
+#endif
+}
+
+/**
+ * gdk_window_merge_child_input_shapes:
+ * @window: a #GdkWindow
+ *
+ * Merges the input shape masks for any child windows into the
+ * input shape mask for @window. i.e. the union of all input masks
+ * for @window and its children will become the new input mask
+ * for @window. See gdk_window_input_shape_combine_mask().
+ *
+ * This function is distinct from gdk_window_set_child_input_shapes()
+ * because it includes @window's input shape mask in the set of
+ * shapes to be merged.
+ *
+ * Since: 2.10
+ **/
+void
+gdk_window_merge_child_input_shapes (GdkWindow *window)
+{
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+#ifdef HAVE_SHAPE_EXT
+#ifdef ShapeInput
+ if (!GDK_WINDOW_DESTROYED (window) &&
+ gdk_display_supports_input_shapes (GDK_WINDOW_DISPLAY (window)))
+ gdk_propagate_shapes (GDK_WINDOW_XDISPLAY (window),
+ GDK_WINDOW_XID (window), TRUE, ShapeInput);
+#endif
+#endif
+}
+
+
static void
gdk_window_set_static_bit_gravity (GdkWindow *window, gboolean on)
{
{
gdk_window_destroy (mv_resize->moveresize_emulation_window);
mv_resize->moveresize_emulation_window = NULL;
+ g_object_unref (mv_resize->moveresize_window);
mv_resize->moveresize_window = NULL;
if (mv_resize->moveresize_pending_event)
/* If this fails, some other client has grabbed the window
* already.
*/
- gdk_window_destroy (mv_resize->moveresize_emulation_window);
- mv_resize->moveresize_emulation_window = NULL;
+ finish_drag (mv_resize);
}
mv_resize->moveresize_process_time = 0;