[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master f38bdb0327 1/2: Take window shapes into account when processing d
From: |
Po Lu |
Subject: |
master f38bdb0327 1/2: Take window shapes into account when processing drag and drop |
Date: |
Fri, 25 Mar 2022 04:23:02 -0400 (EDT) |
branch: master
commit f38bdb0327c5806286ab97687e2823d65d8e184a
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Take window shapes into account when processing drag and drop
* configure.ac: Test for the Nonrectangular Window Shape
extension.
* msdos/sed1v2.inp: Update.
* src/xterm.c (struct x_client_list_window): New fields for
shapes.
(x_dnd_free_toplevels): Free shapes.
(x_dnd_compute_toplevels): Populate window shapes.
(x_dnd_get_target_window_2): New function.
(x_dnd_get_target_window_1): Test WM state of window before
taking it into account.
(x_dnd_begin_drag_and_drop): Use outer window as the initial
last seen window.
(x_dnd_update_state): Small fixes to frame tracking.
(handle_one_xevent): Handle ShapeNotify events correctly.
(x_term_init): Test for the Nonrectangular Window Shape
extension.
* src/xterm.h (struct x_display_info): New atom `WM_STATE'.
---
configure.ac | 18 +++
msdos/sed1v2.inp | 2 +
src/xterm.c | 403 ++++++++++++++++++++++++++++++++++++++++++++++++++++---
src/xterm.h | 9 ++
4 files changed, 410 insertions(+), 22 deletions(-)
diff --git a/configure.ac b/configure.ac
index 6e63747733..4ac8c143e5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4538,6 +4538,24 @@ fi
AC_SUBST(XDBE_CFLAGS)
AC_SUBST(XDBE_LIBS)
+### Use the Nonrectangular Window Shape extension if available.
+HAVE_XSHAPE=no
+if test "${HAVE_X11}" = "yes"; then
+ AC_CHECK_HEADER(X11/extensions/shape.h,
+ [AC_CHECK_LIB(Xext, XShapeQueryVersion, HAVE_XSHAPE=yes)],
+ [],
+ [#include <X11/extensions/shape.h>
+ ])
+ if test $HAVE_XSHAPE = yes; then
+ XSHAPE_LIBS=-lXext
+ fi
+ if test $HAVE_XSHAPE = yes; then
+ AC_DEFINE(HAVE_XSHAPE, 1, [Define to 1 if you have the Nonrectangular
Window Shape extension.])
+ fi
+fi
+AC_SUBST(XSHAPE_CFLAGS)
+AC_SUBST(XSHAPE_LIBS)
+
### Use Xcomposite (-lXcomposite) if available
HAVE_XCOMPOSITE=no
if test "${HAVE_X11}" = "yes"; then
diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp
index 24ae079db1..4cc733ee79 100644
--- a/msdos/sed1v2.inp
+++ b/msdos/sed1v2.inp
@@ -119,6 +119,8 @@ s/ *@WEBP_LIBS@//
/^XDBE_CFLAGS *=/s/@XDBE_CFLAGS@//
/^XCOMPOSITE_LIBS *=/s/@XCOMPOSITE_LIBS@//
/^XCOMPOSITE_CFLAGS *=/s/@XCOMPOSITE_CFLAGS@//
+/^XSHAPE_LIBS *=/s/@XSHAPE_LIBS@//
+/^XSHAPE_CFLAGS *=/s/@XSHAPE_CFLAGS@//
/^XINPUT_LIBS *=/s/@XINPUT_LIBS@//
/^XINPUT_CFLAGS *=/s/@XINPUT_CFLAGS@//
/^XSYNC_LIBS *=/s/@XSYNC_LIBS@//
diff --git a/src/xterm.c b/src/xterm.c
index 0267ba7ec1..cd651f4667 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -546,6 +546,10 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include <X11/extensions/Xcomposite.h>
#endif
+#ifdef HAVE_XSHAPE
+#include <X11/extensions/shape.h>
+#endif
+
/* Load sys/types.h if not already loaded.
In some systems loading it twice is suicidal. */
#ifndef makedev
@@ -826,10 +830,21 @@ struct x_client_list_window
Display *dpy;
int x, y;
int width, height;
- bool visible_p;
+ bool mapped_p;
long previous_event_mask;
+ unsigned long wm_state;
struct x_client_list_window *next;
+
+#ifdef HAVE_XSHAPE
+ int border_width;
+
+ XRectangle *input_rects;
+ int n_input_rects;
+
+ XRectangle *bounding_rects;
+ int n_bounding_rects;
+#endif
};
static struct x_client_list_window *x_dnd_toplevels = NULL;
@@ -849,7 +864,18 @@ x_dnd_free_toplevels (void)
x_catch_errors (last->dpy);
XSelectInput (last->dpy, last->window,
last->previous_event_mask);
+#ifdef HAVE_XSHAPE
+ XShapeSelectInput (last->dpy, last->window, None);
+#endif
x_uncatch_errors ();
+
+#ifdef HAVE_XSHAPE
+ if (last->n_input_rects != -1)
+ xfree (last->input_rects);
+ if (last->n_bounding_rects != -1)
+ xfree (last->bounding_rects);
+#endif
+
xfree (last);
}
@@ -862,11 +888,15 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
Atom type;
Window *toplevels, child;
int format, rc, dest_x, dest_y;
- unsigned long nitems, bytes_after;
- unsigned char *data = NULL;
+ unsigned long nitems, wmstate_items, bytes_after, *wmstate;
+ unsigned char *data = NULL, *wmstate_data = NULL;
unsigned long i;
XWindowAttributes attrs;
struct x_client_list_window *tem;
+#ifdef HAVE_XSHAPE
+ int count, ordering;
+ XRectangle *rects;
+#endif
rc = XGetWindowProperty (dpyinfo->display, dpyinfo->root_window,
dpyinfo->Xatom_net_client_list_stacking,
@@ -899,10 +929,22 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
-attrs.border_width, &dest_x,
&dest_y, &child)
&& !x_had_errors_p (dpyinfo->display));
+ if (rc)
+ rc = ((XGetWindowProperty (dpyinfo->display,
+ toplevels[i],
+ dpyinfo->Xatom_wm_state,
+ 0, 2, False, AnyPropertyType,
+ &type, &format, &wmstate_items,
+ &bytes_after, &wmstate_data)
+ == Success)
+ && !x_had_errors_p (dpyinfo->display)
+ && wmstate_data && wmstate_items == 2 && format == 32);
x_uncatch_errors_after_check ();
if (rc)
{
+ wmstate = (unsigned long *) wmstate_data;
+
tem = xmalloc (sizeof *tem);
tem->window = toplevels[i];
tem->dpy = dpyinfo->display;
@@ -910,13 +952,93 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
tem->y = dest_y;
tem->width = attrs.width + attrs.border_width;
tem->height = attrs.height + attrs.border_width;
- tem->visible_p = (attrs.map_state == IsViewable);
+ tem->mapped_p = (attrs.map_state != IsUnmapped);
tem->next = x_dnd_toplevels;
tem->previous_event_mask = attrs.your_event_mask;
+ tem->wm_state = wmstate[0];
+
+ XFree (wmstate_data);
+
+#ifdef HAVE_XSHAPE
+ tem->border_width = attrs.border_width;
+ tem->n_bounding_rects = -1;
+ tem->n_input_rects = -1;
+
+ if (dpyinfo->xshape_supported_p)
+ {
+ x_catch_errors (dpyinfo->display);
+ XShapeSelectInput (dpyinfo->display,
+ toplevels[i],
+ ShapeNotifyMask);
+ x_uncatch_errors ();
+
+ x_catch_errors (dpyinfo->display);
+ rects = XShapeGetRectangles (dpyinfo->display,
+ toplevels[i],
+ ShapeBounding,
+ &count, &ordering);
+ rc = x_had_errors_p (dpyinfo->display);
+ x_uncatch_errors_after_check ();
+
+ /* Does XShapeGetRectangles allocate anything upon an
+ error? */
+ if (!rc)
+ {
+ tem->n_bounding_rects = count;
+ tem->bounding_rects
+ = xmalloc (sizeof *tem->bounding_rects * count);
+ memcpy (tem->bounding_rects, rects,
+ sizeof *tem->bounding_rects * count);
+
+ XFree (rects);
+ }
+
+#ifdef ShapeInput
+ if (dpyinfo->xshape_major > 1
+ || (dpyinfo->xshape_major == 1
+ && dpyinfo->xshape_minor >= 1))
+ {
+ x_catch_errors (dpyinfo->display);
+ rects = XShapeGetRectangles (dpyinfo->display,
+ toplevels[i], ShapeInput,
+ &count, &ordering);
+ rc = x_had_errors_p (dpyinfo->display);
+ x_uncatch_errors_after_check ();
+
+ /* Does XShapeGetRectangles allocate anything upon
+ an error? */
+ if (!rc)
+ {
+ tem->n_input_rects = count;
+ tem->input_rects
+ = xmalloc (sizeof *tem->input_rects * count);
+ memcpy (tem->input_rects, rects,
+ sizeof *tem->input_rects * count);
+
+ XFree (rects);
+ }
+ }
+#endif
+ }
+
+ /* Handle the common case where the input shape equals the
+ bounding shape. */
+
+ if (tem->n_input_rects != -1
+ && tem->n_bounding_rects == tem->n_input_rects
+ && !memcmp (tem->bounding_rects, tem->input_rects,
+ tem->n_input_rects * sizeof *tem->input_rects))
+ {
+ xfree (tem->input_rects);
+ tem->n_input_rects = -1;
+ }
+#endif
x_catch_errors (dpyinfo->display);
XSelectInput (dpyinfo->display, toplevels[i],
- attrs.your_event_mask | StructureNotifyMask);
+ (attrs.your_event_mask
+ | StructureNotifyMask
+ | PropertyChangeMask));
x_uncatch_errors ();
x_dnd_toplevels = tem;
@@ -931,6 +1053,28 @@ x_dnd_compute_toplevels (struct x_display_info *dpyinfo)
static int x_dnd_get_window_proto (struct x_display_info *, Window);
static Window x_dnd_get_window_proxy (struct x_display_info *, Window);
+#ifdef HAVE_XSHAPE
+static bool
+x_dnd_get_target_window_2 (XRectangle *rects, int nrects,
+ int x, int y)
+{
+ int i;
+ XRectangle *tem;
+
+ for (i = 0; i < nrects; ++i)
+ {
+ tem = &rects[i];
+
+ if (x >= tem->x && y >= tem->y
+ && x < tem->x + tem->width
+ && y < tem->y + tem->height)
+ return true;
+ }
+
+ return false;
+}
+#endif
+
static Window
x_dnd_get_target_window_1 (struct x_display_info *dpyinfo,
int root_x, int root_y)
@@ -942,13 +1086,33 @@ x_dnd_get_target_window_1 (struct x_display_info
*dpyinfo,
for (tem = x_dnd_toplevels; tem; tem = tem->next)
{
- if (!tem->visible_p)
+ if (!tem->mapped_p || tem->wm_state != NormalState)
continue;
if (root_x >= tem->x && root_y >= tem->y
&& root_x < tem->x + tem->width
&& root_y < tem->y + tem->height)
- return tem->window;
+ {
+#ifdef HAVE_XSHAPE
+ if (tem->n_bounding_rects == -1)
+#endif
+ return tem->window;
+
+#ifdef HAVE_XSHAPE
+ if (x_dnd_get_target_window_2 (tem->bounding_rects,
+ tem->n_bounding_rects,
+ tem->border_width + root_x - tem->x,
+ tem->border_width + root_y - tem->y))
+ {
+ if (tem->n_input_rects == -1
+ || x_dnd_get_target_window_2 (tem->input_rects,
+ tem->n_input_rects,
+ tem->border_width + root_x -
tem->x,
+ tem->border_width + root_y -
tem->y))
+ return tem->window;
+ }
+#endif
+ }
}
return None;
@@ -7230,7 +7394,7 @@ x_dnd_begin_drag_and_drop (struct frame *f, Time time,
Atom xaction,
x_dnd_in_progress = true;
x_dnd_frame = f;
- x_dnd_last_seen_window = FRAME_X_WINDOW (f);
+ x_dnd_last_seen_window = FRAME_OUTER_WINDOW (f);
x_dnd_last_protocol_version = -1;
x_dnd_mouse_rect_target = None;
x_dnd_action = None;
@@ -10983,10 +11147,10 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
{
if (x_dnd_last_seen_window != None
&& x_dnd_last_protocol_version != -1
- && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame))
+ && x_dnd_last_seen_window != FRAME_OUTER_WINDOW (x_dnd_frame))
x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
- if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
+ if (target != FRAME_OUTER_WINDOW (x_dnd_frame)
&& x_dnd_return_frame == 1)
x_dnd_return_frame = 2;
@@ -10999,6 +11163,8 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
x_dnd_return_frame_object
= x_any_window_to_frame (dpyinfo, target);
x_dnd_return_frame = 3;
+ x_dnd_waiting_for_finish = false;
+ target = None;
}
x_dnd_action = None;
@@ -11018,7 +11184,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
x_dnd_wanted_action);
}
/* The pointer moved out of the screen. */
- else if (x_dnd_last_protocol_version)
+ else if (x_dnd_last_protocol_version != -1)
{
if (x_dnd_last_seen_window != None
&& x_dnd_last_protocol_version != -1)
@@ -11028,6 +11194,7 @@ x_dnd_update_state (struct x_display_info *dpyinfo)
x_dnd_end_window = x_dnd_last_seen_window;
x_dnd_last_seen_window = None;
x_dnd_in_progress = false;
+ x_dnd_waiting_for_finish = false;
x_dnd_frame = NULL;
}
}
@@ -11464,6 +11631,65 @@ handle_one_xevent (struct x_display_info *dpyinfo,
break;
case PropertyNotify:
+ if (x_dnd_in_progress && x_dnd_use_toplevels
+ && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame)
+ && event->xproperty.atom == dpyinfo->Xatom_wm_state)
+ {
+ struct x_client_list_window *tem, *last;
+
+ for (last = NULL, tem = x_dnd_toplevels; tem;
+ last = tem, tem = tem->next)
+ {
+ if (tem->window == event->xproperty.window)
+ {
+ Atom actual_type;
+ int actual_format, rc;
+ unsigned long nitems, bytesafter;
+ unsigned char *data = NULL;
+
+
+ if (event->xproperty.state == PropertyDelete)
+ {
+ if (!last)
+ x_dnd_toplevels = tem->next;
+ else
+ last->next = tem->next;
+
+#ifdef HAVE_XSHAPE
+ if (tem->n_input_rects != -1)
+ xfree (tem->input_rects);
+ if (tem->n_bounding_rects != -1)
+ xfree (tem->bounding_rects);
+#endif
+ xfree (tem);
+ }
+ else
+ {
+ x_catch_errors (dpyinfo->display);
+ rc = XGetWindowProperty (dpyinfo->display,
+ event->xproperty.window,
+ dpyinfo->Xatom_wm_state,
+ 0, 2, False, AnyPropertyType,
+ &actual_type, &actual_format,
+ &nitems, &bytesafter, &data);
+
+ if (!x_had_errors_p (dpyinfo->display) && rc == Success
&& data
+ && nitems == 2 && actual_format == 32)
+ {
+ tem->wm_state = ((unsigned long *) data)[0];
+ XFree (data);
+ }
+ else
+ tem->wm_state = WithdrawnState;
+ x_uncatch_errors_after_check ();
+ }
+
+ x_dnd_update_state (dpyinfo);
+ break;
+ }
+ }
+ }
+
f = x_top_window_to_frame (dpyinfo, event->xproperty.window);
if (f && event->xproperty.atom == dpyinfo->Xatom_net_wm_state)
{
@@ -11697,14 +11923,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
break;
case UnmapNotify:
- if (x_dnd_in_progress && x_dnd_use_toplevels)
+ if (x_dnd_in_progress && x_dnd_use_toplevels
+ && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
{
for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
tem = tem->next)
{
- if (tem->window == event->xmap.window)
+ if (tem->window == event->xunmap.window)
{
- tem->visible_p = false;
+ tem->mapped_p = false;
break;
}
}
@@ -11758,14 +11985,15 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (x_dnd_in_progress)
x_dnd_update_state (dpyinfo);
- if (x_dnd_in_progress && x_dnd_use_toplevels)
+ if (x_dnd_in_progress && x_dnd_use_toplevels
+ && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
{
for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
tem = tem->next)
{
if (tem->window == event->xmap.window)
{
- tem->visible_p = true;
+ tem->mapped_p = true;
break;
}
}
@@ -12389,10 +12617,10 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
if (x_dnd_last_seen_window != None
&& x_dnd_last_protocol_version != -1
- && x_dnd_last_seen_window != FRAME_X_WINDOW (x_dnd_frame))
+ && x_dnd_last_seen_window != FRAME_OUTER_WINDOW
(x_dnd_frame))
x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
- if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
+ if (target != FRAME_OUTER_WINDOW (x_dnd_frame)
&& x_dnd_return_frame == 1)
x_dnd_return_frame = 2;
@@ -12405,6 +12633,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_dnd_return_frame_object
= x_any_window_to_frame (dpyinfo, target);
x_dnd_return_frame = 3;
+ x_dnd_waiting_for_finish = false;
+ target = None;
}
x_dnd_action = None;
@@ -12547,7 +12777,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
configureEvent = next_event;
}
- if (x_dnd_in_progress && x_dnd_use_toplevels)
+ if (x_dnd_in_progress && x_dnd_use_toplevels
+ && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
{
int rc, dest_x, dest_y;
Window child;
@@ -12589,6 +12820,12 @@ handle_one_xevent (struct x_display_info *dpyinfo,
else
last->next = tem->next;
+#ifdef HAVE_XSHAPE
+ if (tem->n_input_rects != -1)
+ xfree (tem->input_rects);
+ if (tem->n_bounding_rects != -1)
+ xfree (tem->bounding_rects);
+#endif
xfree (tem);
}
@@ -13699,20 +13936,24 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
if (x_dnd_last_seen_window != None
&& x_dnd_last_protocol_version != -1
- && x_dnd_last_seen_window != FRAME_X_WINDOW
(x_dnd_frame))
+ && x_dnd_last_seen_window != FRAME_OUTER_WINDOW
(x_dnd_frame))
x_dnd_send_leave (x_dnd_frame, x_dnd_last_seen_window);
- if (x_dnd_last_seen_window == FRAME_X_WINDOW (x_dnd_frame)
+ if (target != FRAME_OUTER_WINDOW (x_dnd_frame)
&& x_dnd_return_frame == 1)
x_dnd_return_frame = 2;
if (x_dnd_return_frame == 2
&& x_any_window_to_frame (dpyinfo, target))
{
+ x_dnd_end_window = x_dnd_last_seen_window;
+ x_dnd_last_seen_window = None;
x_dnd_in_progress = false;
x_dnd_return_frame_object
= x_any_window_to_frame (dpyinfo, target);
x_dnd_return_frame = 3;
+ x_dnd_waiting_for_finish = false;
+ target = None;
}
x_dnd_action = None;
@@ -15043,7 +15284,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
default:
#ifdef HAVE_XKB
- if (event->type == dpyinfo->xkb_event_type)
+ if (dpyinfo->supports_xkb
+ && event->type == dpyinfo->xkb_event_type)
{
XkbEvent *xkbevent = (XkbEvent *) event;
@@ -15088,6 +15330,109 @@ handle_one_xevent (struct x_display_info *dpyinfo,
x_find_modifier_meanings (dpyinfo);
}
}
+#endif
+#ifdef HAVE_XSHAPE
+ if (dpyinfo->xshape_supported_p
+ && event->type == dpyinfo->xshape_event_base + ShapeNotify
+ && x_dnd_in_progress && x_dnd_use_toplevels
+ && dpyinfo == FRAME_DISPLAY_INFO (x_dnd_frame))
+ {
+ XEvent xevent;
+ XShapeEvent *xse = (XShapeEvent *) event;
+ XRectangle *rects;
+ int rc, ordering;
+
+ while (XPending (dpyinfo->display))
+ {
+ XNextEvent (dpyinfo->display, &xevent);
+
+ if (xevent.type == dpyinfo->xshape_event_base + ShapeNotify
+ && ((XShapeEvent *) &xevent)->window == xse->window)
+ xse = (XShapeEvent *) &xevent;
+ else
+ {
+ XPutBackEvent (dpyinfo->display, &xevent);
+ break;
+ }
+ }
+
+ for (struct x_client_list_window *tem = x_dnd_toplevels; tem;
+ tem = tem->next)
+ {
+ if (tem->window == xse->window)
+ {
+ if (tem->n_input_rects != -1)
+ xfree (tem->input_rects);
+ if (tem->n_bounding_rects != -1)
+ xfree (tem->bounding_rects);
+
+ tem->n_input_rects = -1;
+ tem->n_bounding_rects = -1;
+
+ x_catch_errors (dpyinfo->display);
+ rects = XShapeGetRectangles (dpyinfo->display,
+ xse->window,
+ ShapeBounding,
+ &count, &ordering);
+ rc = x_had_errors_p (dpyinfo->display);
+ x_uncatch_errors_after_check ();
+
+ /* Does XShapeGetRectangles allocate anything upon an
+ error? */
+ if (!rc)
+ {
+ tem->n_bounding_rects = count;
+ tem->bounding_rects
+ = xmalloc (sizeof *tem->bounding_rects * count);
+ memcpy (tem->bounding_rects, rects,
+ sizeof *tem->bounding_rects * count);
+
+ XFree (rects);
+ }
+
+#ifdef ShapeInput
+ if (dpyinfo->xshape_major > 1
+ || (dpyinfo->xshape_major == 1
+ && dpyinfo->xshape_minor >= 1))
+ {
+ x_catch_errors (dpyinfo->display);
+ rects = XShapeGetRectangles (dpyinfo->display,
+ xse->window, ShapeInput,
+ &count, &ordering);
+ rc = x_had_errors_p (dpyinfo->display);
+ x_uncatch_errors_after_check ();
+
+ /* Does XShapeGetRectangles allocate anything upon
+ an error? */
+ if (!rc)
+ {
+ tem->n_input_rects = count;
+ tem->input_rects
+ = xmalloc (sizeof *tem->input_rects * count);
+ memcpy (tem->input_rects, rects,
+ sizeof *tem->input_rects * count);
+
+ XFree (rects);
+ }
+ }
+#endif
+
+ /* Handle the common case where the input shape equals the
+ bounding shape. */
+
+ if (tem->n_input_rects != -1
+ && tem->n_bounding_rects == tem->n_input_rects
+ && !memcmp (tem->bounding_rects, tem->input_rects,
+ tem->n_input_rects * sizeof
*tem->input_rects))
+ {
+ xfree (tem->input_rects);
+ tem->n_input_rects = -1;
+ }
+
+ break;
+ }
+ }
+ }
#endif
OTHER:
#ifdef USE_X_TOOLKIT
@@ -19011,6 +19356,19 @@ x_term_init (Lisp_Object display_name, char
*xrm_option, char *resource_name)
&dpyinfo->composite_minor);
#endif
+#ifdef HAVE_XSHAPE
+ dpyinfo->xshape_supported_p
+ = XShapeQueryExtension (dpyinfo->display,
+ &dpyinfo->xshape_event_base,
+ &dpyinfo->xshape_error_base);
+
+ if (dpyinfo->xshape_supported_p)
+ dpyinfo->xshape_supported_p
+ = XShapeQueryVersion (dpyinfo->display,
+ &dpyinfo->xshape_major,
+ &dpyinfo->xshape_minor);
+#endif
+
/* Put the rdb where we can find it in a way that works on
all versions. */
dpyinfo->rdb = xrdb;
@@ -19391,6 +19749,7 @@ x_term_init (Lisp_Object display_name, char
*xrm_option, char *resource_name)
ATOM_REFS_INIT ("WM_SAVE_YOURSELF", Xatom_wm_save_yourself)
ATOM_REFS_INIT ("WM_DELETE_WINDOW", Xatom_wm_delete_window)
ATOM_REFS_INIT ("WM_CHANGE_STATE", Xatom_wm_change_state)
+ ATOM_REFS_INIT ("WM_STATE", Xatom_wm_state)
ATOM_REFS_INIT ("WM_CONFIGURE_DENIED", Xatom_wm_configure_denied)
ATOM_REFS_INIT ("WM_MOVED", Xatom_wm_window_moved)
ATOM_REFS_INIT ("WM_CLIENT_LEADER", Xatom_wm_client_leader)
diff --git a/src/xterm.h b/src/xterm.h
index 4a71968b04..5a7b09925e 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -396,6 +396,7 @@ struct x_display_info
/* Atom for indicating window state to the window manager. */
Atom Xatom_wm_change_state;
+ Atom Xatom_wm_state;
/* Other WM communication */
Atom Xatom_wm_configure_denied; /* When our config request is denied */
@@ -644,6 +645,14 @@ struct x_display_info
int composite_major;
int composite_minor;
#endif
+
+#ifdef HAVE_XSHAPE
+ bool xshape_supported_p;
+ int xshape_major;
+ int xshape_minor;
+ int xshape_event_base;
+ int xshape_error_base;
+#endif
};
#ifdef HAVE_X_I18N