x11: Fix x-display-process-events to return #f when all events read.
authorMatt Birkholz <puck@birchwood-abbey.net>
Fri, 29 Jul 2016 06:16:06 +0000 (23:16 -0700)
committerMatt Birkholz <puck@birchwood-abbey.net>
Fri, 29 Jul 2016 07:08:32 +0000 (00:08 -0700)
The plugin's version of x_display_process_events will return any
keypress even though some do not translate into any input (e.g. when
it IsModifier).  X-display-process-events would return #f in that case
and preview-events think all events were read.  Now x-display-process-
events returns #t and preview-events disregards it, continuing to read
events.  Many callers must disregard these non-events.

Punt property-notify events in the previewer; do not queue them.

src/runtime/x11graph.scm
src/x11-screen/x11-screen.scm
src/x11/x11-shim.h
src/x11/x11.cdecl
src/x11/x11base.c
src/x11/x11base.scm
src/x11/x11device.scm

index cdf9985bf6699f4b4c2c668bc24e08505f2cd07e..2f92dc1884a5ac566c1c829be662f1eb9cf7efa8 100644 (file)
@@ -304,7 +304,8 @@ USA.
                             (x-display-process-events (x-display/xd display)
                                                       2)))
                        (if event
-                           (begin (process-event display event)
+                           (begin (if (not (eq? #t event))
+                                      (process-event display event))
                                   (loop))))))))))))
     (set-x-display/previewer-registration! display registration)))
 
@@ -328,7 +329,7 @@ USA.
                        #t
                        'READ))
                  (x-display-process-events (x-display/xd display) 1)))))
-    (if event
+    (if (and event (not (eq? #t event)))
        (process-event display event))))
 
 (define (discard-events display)
@@ -341,7 +342,8 @@ USA.
                      ((x-display-process-events (x-display/xd display) 2)
                       =>
                       (lambda (event)
-                        (process-event display event)
+                        (if (not (eq? #t event))
+                            (process-event display event))
                         (loop))))))))
     (with-thread-events-blocked loop)))
 \f
index f5b244b6022c8415615116e54762e8c2e83f14d8..f1cff4602f89a798678a29dbc8f92b70b769ecc9 100644 (file)
@@ -525,7 +525,8 @@ USA.
        (let loop ()
         (let ((event (x-display-process-events x-display-data 2)))
           (if event
-              (begin (preview-event event x-display-events)
+              (begin (if (not (eq? #t event))
+                         (preview-event event x-display-events))
                      (loop))))))
 
      (register!))))
@@ -545,7 +546,9 @@ USA.
        (if event
            (if (and (vector? event) (predicate event))
                (or (process-event event) (loop))
-               (begin (preview-event event x-display-events) (loop)))
+               (begin (if (not (eq? #t event))
+                          (preview-event event x-display-events))
+                      (loop)))
            ;; Busy loop!
            (and (< (real-time-clock) timeout)
                 (loop)))))))
@@ -565,6 +568,12 @@ USA.
        ((and (vector? event)
              (fix:= event-type:expose (vector-ref event 0)))
         (process-expose-event event))
+       ((and (vector? event)
+             (fix:= event-type:property-notify (vector-ref event 0)))
+        ;; These events are only used inside wait-for-event, in the
+        ;; previewer, with events blocked, though many more are sent
+        ;; and needn't be queued.
+        unspecific)
        ((and (vector? event)
              (or (fix:= event-type:map (vector-ref event 0))
                  (fix:= event-type:unmap (vector-ref event 0))
index b9095d46d2b2cfeca9be2c5e6184fef771d2a4bc..7b47aeee04c3abe6ea5d1e8024e228c321285dad 100644 (file)
@@ -51,8 +51,9 @@ extern void x_close_window (struct xwindow * xw);
 extern int x_set_default_font (struct xdisplay * xd, const char * name);
 extern int x_display_descriptor (struct xdisplay * xd);
 extern long x_max_request_size (struct xdisplay * xd);
-extern struct xwindow * x_display_process_events (struct xdisplay * xd,
-                                                 XEvent * event);
+extern int x_display_process_events (struct xdisplay * xd,
+                                    XEvent * event,
+                                    struct xwindow ** xw_ret);
 extern void x_select_input (struct xdisplay * xd, Window window, long mask);
 extern long x_window_event_mask (struct xwindow * xw);
 extern int x_window_set_event_mask (struct xwindow * xw, long mask);
index 639eab7b42f7b4d59060e959dc34e24b8f9d1d36..1209092c7ad965681e47c31e3765f34bf0e33438 100644 (file)
@@ -344,10 +344,11 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
        x_max_request_size
        (xd (* (struct xdisplay))))
 
-(extern (* (struct xwindow))
+(extern int
        x_display_process_events
        (xd (* (struct xdisplay)))
-       (event (* XEvent)))
+       (event (* XEvent))
+       (xw_ret (* (* (struct xwindow)))))
 
 (extern void
        x_select_input
index d36c4b545553ea723414762924c7c477aa428ea9..e187a414771e2d3ce545570359e19e024da10226 100644 (file)
@@ -1109,13 +1109,16 @@ ping_server (struct xdisplay * xd)
     }
 }
 
-static struct xwindow *
-xd_process_events (struct xdisplay * xd, XEvent * result)
+static int
+xd_process_events (struct xdisplay * xd, XEvent * result,
+                  struct xwindow ** xw_ret)
 {
   Display * display = (XD_DISPLAY (xd));
   unsigned int events_queued;
   XEvent event;
-  struct xwindow * retval = NULL;
+  struct xwindow * xw = NULL;
+  int done_p = 1;
+
   if (x_debug > 1)
     {
       fprintf (stderr, "Enter xd_process_events\n");
@@ -1125,7 +1128,6 @@ xd_process_events (struct xdisplay * xd, XEvent * result)
   events_queued = (XEventsQueued (display, QueuedAfterReading));
   while (0 < events_queued)
     {
-      struct xwindow * xw;
       events_queued -= 1;
       XNextEvent (display, (&event));
       if ((event.type) == KeymapNotify)
@@ -1140,16 +1142,17 @@ xd_process_events (struct xdisplay * xd, XEvent * result)
       if (xw_process_event (xw, (&event)))
        continue;
       memcpy (result, &event, sizeof (XEvent));
-      retval = xw;
+      *xw_ret = xw;
+      done_p = 0;
       break;
     }
   if (x_debug > 1)
     {
-      fprintf (stderr, "Return from xd_process_events: 0x%lx\n",
-              ((unsigned long) retval));
+      fprintf (stderr, "Return from xd_process_events: %d 0x%lx\n",
+              done_p, ((unsigned long) xw));
       fflush (stderr);
     }
-  return (retval);
+  return (done_p);
 }
 \f
 /* Open/Close Primitives */
@@ -1255,10 +1258,11 @@ x_max_request_size (struct xdisplay * xd)
   return (XMaxRequestSize (display));
 }
 
-struct xwindow *
-x_display_process_events (struct xdisplay * xd, XEvent * event)
+int
+x_display_process_events (struct xdisplay * xd, XEvent * event,
+                         struct xwindow **xw_ret)
 {
-  return (xd_process_events (xd, event));
+  return (xd_process_events (xd, event, xw_ret));
 }
 
 void
index 5a3596e84209730c488a480de0e6b221072edf91..52ce079e71a410bc5c5f7d19c628eb4c66cda8c5 100644 (file)
@@ -24,7 +24,7 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 |#
 
 ;;;; X11 interface
-;;; package: (x11)
+;;; package: (x11 base)
 ;;;
 ;;; These were once primitives created by x11base.c in umodule prx11.
 
@@ -101,13 +101,16 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 (define (x-display-process-events display how)
   (declare (ignore how))
   (guarantee-xdisplay display 'x-display-process-events)
-  (let* ((event (malloc (C-sizeof "XEvent") '|XEvent|))
-        (window (C-call "x_display_process_events"
-                        (make-alien '(struct |xwindow|))
-                        display event)))
-    (let ((obj (if (alien-null? window)
-                  #f
-                  (make-event-object window event))))
+  (let ((event (malloc (C-sizeof "XEvent") '|XEvent|))
+       (xw (malloc (C-sizeof "* struct xwindow") '(* (struct |xwindow|)))))
+    (let* ((done-p (C-call "x_display_process_events"
+                          display event xw))
+          (window (C-> xw "* xwindow" (make-alien '(struct |xwindow|))))
+          (obj (if (= done-p 1)
+                   #f
+                   (or (make-event-object window event)
+                       #t))))
+      (free xw)
       (free event)
       obj)))
 
index 3ffadbbb8620ae6fc5c233f6c2e8092e77d6d2c2..1c6a20cbd03641c26ec4858897bd3cc997d8be7f 100644 (file)
@@ -211,8 +211,10 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
                             (x-display-process-events (x-display/xd display)
                                                       2)))
                        (if event
-                           (begin (process-event display event)
-                                  (loop))))))))))))
+                           (begin
+                             (if (not (eq? #t event))
+                                 (process-event display event))
+                             (loop))))))))))))
     (set-x-display/previewer-registration! display registration)))
 
 (define (read-event display)
@@ -235,7 +237,7 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
                        #t
                        'READ))
                  (x-display-process-events (x-display/xd display) 1)))))
-    (if event
+    (if (and event (not (eq? #t event)))
        (process-event display event))))
 
 (define (discard-events display)
@@ -248,7 +250,8 @@ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
                      ((x-display-process-events (x-display/xd display) 2)
                       =>
                       (lambda (event)
-                        (process-event display event)
+                        (if (not (eq? #t event))
+                            (process-event display event))
                         (loop))))))))
     (with-thread-events-blocked loop)))
 \f