about summary refs log tree commit diff
path: root/exwm-input.el
diff options
context:
space:
mode:
authorChris Feng <chris.w.feng@gmail.com>2016-07-29T09·05+0800
committerChris Feng <chris.w.feng@gmail.com>2016-07-29T09·05+0800
commit719b825bc4e5471ca2a51f1f9f3b1149a1532c24 (patch)
treee724150b6ddd1ecddd638b6e1c22ddbb294be58f /exwm-input.el
parent2220c8cea21093afb17da24e8c8ecb32c357a09d (diff)
Sync with XELB
* exwm-input.el (exwm-input--update-global-prefix-keys)
(exwm-input--on-KeyPress-line-mode, exwm-input--on-KeyPress-char-mode)
(exwm-input--fake-key, exwm-input--init): Sync with XELB.

* exwm-input.el (exwm-input--on-KeyPress)
(exwm-input--on-KeyPress-line-mode): Resend XKB events with SendEvent
since AllowEvents in ReplayKeyboard mode doesn't seem to work.
Diffstat (limited to 'exwm-input.el')
-rw-r--r--exwm-input.el54
1 files changed, 35 insertions, 19 deletions
diff --git a/exwm-input.el b/exwm-input.el
index 4a6d56e2fbfe..0b5ce98e6a55 100644
--- a/exwm-input.el
+++ b/exwm-input.el
@@ -265,7 +265,7 @@ This value should always be overwritten.")
     (xcb:unmarshal obj data)
     (setq exwm-input--timestamp (slot-value obj 'time))
     (if (eq major-mode 'exwm-mode)
-        (funcall exwm--on-KeyPress obj)
+        (funcall exwm--on-KeyPress obj data)
       (exwm-input--on-KeyPress-char-mode obj))))
 
 (defvar exwm-input--global-keys nil "Global key bindings.")
@@ -307,9 +307,9 @@ This value should always be overwritten.")
                     keycode (xcb:keysyms:keysym->keycode exwm--connection
                                                          (car keysym)))
               (setf (slot-value grab-key 'grab-window) workspace
-                    (slot-value grab-key 'modifiers) (cadr keysym)
+                    (slot-value grab-key 'modifiers) (cdr keysym)
                     (slot-value grab-key 'key) keycode)
-              (when (or (not keycode)
+              (when (or (= 0 keycode)
                         (xcb:+request-checked+request-check exwm--connection
                             grab-key))
                 (user-error "[EXWM] Failed to grab key: %s"
@@ -344,14 +344,15 @@ This value should always be overwritten.")
 (defvar exwm-input--during-command nil
   "Indicate whether between `pre-command-hook' and `post-command-hook'.")
 
-(defun exwm-input--on-KeyPress-line-mode (key-press)
+(defun exwm-input--on-KeyPress-line-mode (key-press raw-data)
   "Parse X KeyPress event to Emacs key event and then feed the command loop."
   (with-slots (detail state) key-press
     (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state))
           event minibuffer-window mode)
-      (when (and keysym
-                 (setq event (xcb:keysyms:keysym->event exwm--connection
-                                                        keysym state))
+      (when (and (/= 0 (car keysym))
+                 (setq event (xcb:keysyms:keysym->event
+                              exwm--connection (car keysym)
+                              (logand state (lognot (cdr keysym)))))
                  (or exwm-input--during-key-sequence
                      exwm-input--during-command
                      (setq minibuffer-window (active-minibuffer-window))
@@ -363,20 +364,35 @@ This value should always be overwritten.")
         ;; Feed this event to command loop.  Also force it to be added to
         ;; `this-command-keys'.
         (exwm-input--unread-event event))
+      (unless mode
+        (if (= 0 (logand #x6000 state)) ;Check the 13~14 bits.
+            ;; Not an XKB state; just replay it.
+            (setq mode xcb:Allow:ReplayKeyboard)
+          ;; An XKB state; sent it with SendEvent.
+          ;; FIXME: Can this also be replayed?
+          ;; FIXME: KeyRelease events are lost.
+          (setq mode xcb:Allow:AsyncKeyboard)
+          (xcb:+request exwm--connection
+              (make-instance 'xcb:SendEvent
+                             :propagate 0
+                             :destination (slot-value key-press 'event)
+                             :event-mask xcb:EventMask:NoEvent
+                             :event raw-data))))
       (xcb:+request exwm--connection
           (make-instance 'xcb:AllowEvents
-                         :mode (or mode xcb:Allow:ReplayKeyboard)
+                         :mode mode
                          :time xcb:Time:CurrentTime))
       (xcb:flush exwm--connection))))
 
-(defun exwm-input--on-KeyPress-char-mode (key-press)
+(defun exwm-input--on-KeyPress-char-mode (key-press &optional _raw-data)
   "Handle KeyPress event in char-mode."
   (with-slots (detail state) key-press
     (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state))
           event)
-      (when (and keysym
-                 (setq event (xcb:keysyms:keysym->event exwm--connection
-                                                        keysym state)))
+      (when (and (/= 0 (car keysym))
+                 (setq event (xcb:keysyms:keysym->event
+                              exwm--connection (car keysym)
+                              (logand state (lognot (cdr keysym))))))
         (when (eq major-mode 'exwm-mode)
           ;; FIXME: This functionality seems not working, e.g. when this
           ;;        command would activate the minibuffer, the temporary
@@ -476,11 +492,11 @@ This value should always be overwritten.")
   "Fake a key event equivalent to Emacs event EVENT."
   (let* ((keysym (xcb:keysyms:event->keysym exwm--connection event))
          keycode id)
-    (unless keysym
+    (when (= 0 (car keysym))
       (user-error "[EXWM] Invalid key: %s" (single-key-description event)))
     (setq keycode (xcb:keysyms:keysym->keycode exwm--connection
                                                (car keysym)))
-    (when keycode
+    (when (/= 0 keycode)
       (setq id (exwm--buffer->id (window-buffer (selected-window))))
       (dolist (class '(xcb:KeyPress xcb:KeyRelease))
         (xcb:+request exwm--connection
@@ -495,7 +511,7 @@ This value should always be overwritten.")
                                                   :child 0
                                                   :root-x 0 :root-y 0
                                                   :event-x 0 :event-y 0
-                                                  :state (cadr keysym)
+                                                  :state (cdr keysym)
                                                   :same-screen 1)
                                    exwm--connection)))))
     (xcb:flush exwm--connection)))
@@ -592,16 +608,16 @@ Its usage is the same with `exwm-input-set-simulation-keys'."
                                              exwm-input-move-event))
         (resize-key (xcb:keysyms:event->keysym exwm--connection
                                                exwm-input-resize-event)))
-    (unless move-key
+    (when (= 0 (car move-key))
       (user-error "[EXWM] Invalid key: %s"
                   (single-key-description exwm-input-move-event)))
-    (unless resize-key
+    (when (= 0 (car resize-key))
       (user-error "[EXWM] Invalid key: %s"
                   (single-key-description exwm-input-resize-event)))
     (setq exwm-input--move-keysym (car move-key)
-          exwm-input--move-mask (cadr move-key)
+          exwm-input--move-mask (cdr move-key)
           exwm-input--resize-keysym (car resize-key)
-          exwm-input--resize-mask (cadr resize-key)))
+          exwm-input--resize-mask (cdr resize-key)))
   ;; Attach event listeners
   (xcb:+event exwm--connection 'xcb:KeyPress #'exwm-input--on-KeyPress)
   (xcb:+event exwm--connection 'xcb:ButtonPress #'exwm-input--on-ButtonPress)