The standard specify that the pseudo-selection which is used to
cooperatively replace window managers should actually contain the version
of the ICCCM standard which is supported. As this could be handy for
compatibility checks in the future, let Window Maker comply.

Signed-off-by: Christophe CURIS <christophe.cu...@free.fr>
---
 src/event.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/src/event.c b/src/event.c
index 71450fc..a6a5402 100644
--- a/src/event.c
+++ b/src/event.c
@@ -37,6 +37,7 @@
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <X11/Xatom.h>
 #ifdef USE_XSHAPE
 # include <X11/extensions/shape.h>
 #endif
@@ -103,6 +104,7 @@ static void handleFocusIn(XEvent *event);
 static void handleMotionNotify(XEvent *event);
 static void handleVisibilityNotify(XEvent *event);
 static void handle_inotify_events(void);
+static void handle_selection_request(XSelectionRequestEvent *event);
 static void handle_selection_clear(XSelectionClearEvent *event);
 static void wdelete_death_handler(WMagicNumber id);
 
@@ -275,6 +277,10 @@ void DispatchEvent(XEvent * event)
 #endif
                break;
 
+       case SelectionRequest:
+               handle_selection_request(&event->xselectionrequest);
+               break;
+
        case SelectionClear:
                handle_selection_clear(&event->xselectionclear);
                break;
@@ -1892,6 +1898,79 @@ static void handleVisibilityNotify(XEvent * event)
        wwin->flags.obscured = (event->xvisibility.state == 
VisibilityFullyObscured);
 }
 
+static void handle_selection_request(XSelectionRequestEvent *event)
+{
+#ifdef USE_ICCCM_WMREPLACE
+       static Atom atom_version = None;
+       WScreen *scr;
+       XSelectionEvent notify;
+
+       /*
+        * This event must be sent to the slection requester to not block him
+        *
+        * We create it with the answer 'there is no selection' by default
+        */
+       notify.type = SelectionNotify;
+       notify.display = dpy;
+       notify.requestor = event->requestor;
+       notify.selection = event->selection;
+       notify.target = event->target;
+       notify.property = None; /* This says that there is no selection */
+       notify.time = event->time;
+
+       scr = wScreenForWindow(event->owner);
+       if (!scr)
+               goto not_our_selection;
+
+       if (event->owner != scr->info_window)
+               goto not_our_selection;
+
+       if (event->selection != scr->sn_atom)
+               goto not_our_selection;
+
+       if (atom_version == None)
+               atom_version = XInternAtom(dpy, "VERSION", False);
+
+       if (event->target == atom_version) {
+               static const long icccm_version[] = { 2, 0 };
+
+               /*
+                * This protocol is defined in ICCCM 2.0:
+                * 
http://www.x.org/releases/X11R7.7/doc/xorg-docs/icccm/icccm.html
+                *  "Communication with the Window Manager by Means of 
Selections"
+                */
+
+               /*
+                * Setting the property means the content of the selection is 
available
+                * According to the ICCCM spec, we need to support being asked 
for a property
+                * set to 'None' for compatibility with old clients
+                */
+               notify.property = (event->property == 
None)?(event->target):(event->property);
+
+               XChangeProperty(dpy, event->requestor, notify.property,
+                               XA_INTEGER, 32, PropModeReplace,
+                               (unsigned char *) icccm_version, 
wlengthof(icccm_version));
+       }
+
+ not_our_selection:
+       if (notify.property == None)
+               wwarning("received SelectionRequest(%s) for target=\"%s\" from 
requestor 0x%lX but we have no answer",
+                        XGetAtomName(dpy, event->selection), XGetAtomName(dpy, 
event->target), (long) event->requestor);
+
+       /* Send the answer to the requestor */
+       XSendEvent(dpy, event->requestor, False, 0L, (XEvent *) &notify);
+
+#else
+       /*
+        * If the support for ICCCM window manager replacement was not enabled, 
we should not receive
+        * this kind of event, so we just ignore it (Conceptually, we should 
reply with 'SelectionNotify'
+        * event with property set to 'None' to tell that we don't have this 
selection, but that is a bit
+        * costly for an event that shall never happen).
+        */
+       (void) event;
+#endif
+}
+
 static void handle_selection_clear(XSelectionClearEvent *event)
 {
 #ifdef USE_ICCCM_WMREPLACE
-- 
2.1.4


-- 
To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.

Reply via email to