Various input fixes

* Fix `exwm-reset`
* Make input mode buffer local
* Allow window to stay in `char-mode` while setting input focus to other window
  or switching to other workspace
This commit is contained in:
Chris Feng 2015-08-07 12:41:15 +08:00
parent 1e36a22b3f
commit 2ad1a89db0
3 changed files with 29 additions and 27 deletions

View file

@ -161,7 +161,9 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
(let ((obj (make-instance 'xcb:KeyPress))) (let ((obj (make-instance 'xcb:KeyPress)))
(xcb:unmarshal obj data) (xcb:unmarshal obj data)
(setq exwm-input--timestamp (slot-value obj 'time)) (setq exwm-input--timestamp (slot-value obj 'time))
(funcall 'exwm-input--handle-KeyPress obj))) (if (eq major-mode 'exwm-mode)
(funcall exwm--on-KeyPress obj)
(exwm-input--on-KeyPress-char-mode obj))))
(defvar exwm-input--global-keys nil "Global key bindings.") (defvar exwm-input--global-keys nil "Global key bindings.")
(defvar exwm-input--global-prefix-keys nil (defvar exwm-input--global-prefix-keys nil
@ -211,7 +213,7 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
;; ;; in this case. ;; ;; in this case.
;; ;; P.S.; to use this implementation, comment out the KeyRelease listener ;; ;; P.S.; to use this implementation, comment out the KeyRelease listener
;; ;; together with this one and make GrabKey in Sync mode. ;; ;; together with this one and make GrabKey in Sync mode.
;; (cl-defmethod exwm-input--handle-KeyPress-line-mode ((obj xcb:KeyPress)) ;; (cl-defmethod exwm-input--on-KeyPress-line-mode ((obj xcb:KeyPress))
;; "Parse X KeyPress event to Emacs key event and then feed the command loop." ;; "Parse X KeyPress event to Emacs key event and then feed the command loop."
;; (with-slots (detail state) obj ;; (with-slots (detail state) obj
;; (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state)) ;; (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state))
@ -238,7 +240,7 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
;; This implementation has a drawback that some (legacy) applications ;; This implementation has a drawback that some (legacy) applications
;; (e.g. xterm) ignore the synthetic key events, making it only viable for EXWM ;; (e.g. xterm) ignore the synthetic key events, making it only viable for EXWM
;; to work in char-mode in such case. ;; to work in char-mode in such case.
(cl-defmethod exwm-input--handle-KeyPress-line-mode ((obj xcb:KeyPress)) (cl-defmethod exwm-input--on-KeyPress-line-mode ((obj xcb:KeyPress))
"Parse X KeyPress event to Emacs key event and then feed the command loop." "Parse X KeyPress event to Emacs key event and then feed the command loop."
(with-slots (detail state) obj (with-slots (detail state) obj
(let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state)) (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state))
@ -264,23 +266,22 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
:event (xcb:marshal obj exwm--connection))) :event (xcb:marshal obj exwm--connection)))
(xcb:flush exwm--connection))))) (xcb:flush exwm--connection)))))
(cl-defmethod exwm-input--handle-KeyPress-char-mode ((obj xcb:KeyPress)) (cl-defmethod exwm-input--on-KeyPress-char-mode ((obj xcb:KeyPress))
"Handle KeyPress event in char-mode." "Handle KeyPress event in char-mode."
(with-slots (detail state) obj (with-slots (detail state) obj
(let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state)) (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state))
event) event)
(when (and keysym (setq event (xcb:keysyms:keysym->event keysym state))) (when (and keysym (setq event (xcb:keysyms:keysym->event keysym state)))
(setq exwm-input--temp-line-mode t (when (eq major-mode 'exwm-mode)
exwm-input--during-key-sequence t) (setq exwm-input--temp-line-mode t
(push event unread-command-events) exwm-input--during-key-sequence t)
(exwm-input--grab-keyboard))))) ;grab keyboard temporarily (exwm-input--grab-keyboard)) ;grab keyboard temporarily
(push event unread-command-events)))))
(defalias 'exwm-input--handle-KeyPress 'exwm-input--handle-KeyPress-line-mode
"Generic function for handling KeyPress event.")
(defun exwm-input--grab-keyboard (&optional id) (defun exwm-input--grab-keyboard (&optional id)
"Grab all key events on window ID." "Grab all key events on window ID."
(unless id (setq id (exwm--buffer->id (window-buffer)))) (unless id (setq id (exwm--buffer->id (window-buffer))))
(cl-assert id)
(when (xcb:+request-checked+request-check exwm--connection (when (xcb:+request-checked+request-check exwm--connection
(make-instance 'xcb:GrabKey (make-instance 'xcb:GrabKey
:owner-events 0 :grab-window id :owner-events 0 :grab-window id
@ -289,19 +290,18 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
:pointer-mode xcb:GrabMode:Async :pointer-mode xcb:GrabMode:Async
:keyboard-mode xcb:GrabMode:Async)) :keyboard-mode xcb:GrabMode:Async))
(exwm--log "Failed to grab keyboard for #x%x" id)) (exwm--log "Failed to grab keyboard for #x%x" id))
(defalias 'exwm-input--handle-KeyPress (setq exwm--on-KeyPress 'exwm-input--on-KeyPress-line-mode))
'exwm-input--handle-KeyPress-line-mode))
(defun exwm-input--release-keyboard (&optional id) (defun exwm-input--release-keyboard (&optional id)
"Ungrab all key events on window ID." "Ungrab all key events on window ID."
(unless id (setq id (exwm--buffer->id (window-buffer)))) (unless id (setq id (exwm--buffer->id (window-buffer))))
(cl-assert id)
(when (xcb:+request-checked+request-check exwm--connection (when (xcb:+request-checked+request-check exwm--connection
(make-instance 'xcb:UngrabKey (make-instance 'xcb:UngrabKey
:key xcb:Grab:Any :grab-window id :key xcb:Grab:Any :grab-window id
:modifiers xcb:ModMask:Any)) :modifiers xcb:ModMask:Any))
(exwm--log "Failed to release keyboard for #x%x" id)) (exwm--log "Failed to release keyboard for #x%x" id))
(defalias 'exwm-input--handle-KeyPress (setq exwm--on-KeyPress 'exwm-input--on-KeyPress-char-mode))
'exwm-input--handle-KeyPress-char-mode))
(defun exwm-input-grab-keyboard (&optional id) (defun exwm-input-grab-keyboard (&optional id)
"Switch to line-mode." "Switch to line-mode."

View file

@ -98,20 +98,20 @@
The optional FORCE option is for internal use only." The optional FORCE option is for internal use only."
(interactive (interactive
(list (list
(let* ((history-add-new-input nil) ;prevent modifying history (unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible
(idx (read-from-minibuffer (let* ((history-add-new-input nil) ;prevent modifying history
"Workspace: " (elt exwm-workspace--switch-history (idx (read-from-minibuffer
exwm-workspace-current-index) "Workspace: " (elt exwm-workspace--switch-history
exwm-workspace--switch-map nil exwm-workspace-current-index)
`(exwm-workspace--switch-history exwm-workspace--switch-map nil
. ,(1+ exwm-workspace-current-index))))) `(exwm-workspace--switch-history
(cl-position idx exwm-workspace--switch-history :test 'equal)))) . ,(1+ exwm-workspace-current-index)))))
(unless exwm-workspace--switch-lock (cl-position idx exwm-workspace--switch-history :test 'equal)))))
(unless (or exwm-workspace--switch-lock (not index))
(setq exwm-workspace--switch-lock t) (setq exwm-workspace--switch-lock t)
(unless (and (<= 0 index) (< index exwm-workspace-number)) (unless (and (<= 0 index) (< index exwm-workspace-number))
(user-error "[EXWM] Workspace index out of range: %d" index)) (user-error "[EXWM] Workspace index out of range: %d" index))
(when (or force (/= exwm-workspace-current-index index)) (when (or force (/= exwm-workspace-current-index index))
(exwm-reset) ;exit full screen
(let ((frame (elt exwm-workspace--list index))) (let ((frame (elt exwm-workspace--list index)))
(setq exwm-workspace--current frame (setq exwm-workspace--current frame
exwm-workspace-current-index index) exwm-workspace-current-index index)

View file

@ -196,8 +196,8 @@
"Reset window to standard state: non-fullscreen, line-mode." "Reset window to standard state: non-fullscreen, line-mode."
(interactive) (interactive)
(with-current-buffer (window-buffer) (with-current-buffer (window-buffer)
(when (and (eq major-mode 'exwm-mode) exwm--fullscreen) (when (eq major-mode 'exwm-mode)
(exwm-layout-unset-fullscreen) (when exwm--fullscreen (exwm-layout-unset-fullscreen))
(exwm-input-grab-keyboard)))) (exwm-input-grab-keyboard))))
(defmacro exwm--with-current-id (id &rest body) (defmacro exwm--with-current-id (id &rest body)
@ -651,6 +651,8 @@
(set (make-local-variable 'exwm--fullscreen) nil) ;used in fullscreen (set (make-local-variable 'exwm--fullscreen) nil) ;used in fullscreen
(set (make-local-variable 'exwm--floating-frame-geometry) nil) ;in fullscreen (set (make-local-variable 'exwm--floating-frame-geometry) nil) ;in fullscreen
(set (make-local-variable 'exwm--fixed-size) nil) ;fixed size (set (make-local-variable 'exwm--fixed-size) nil) ;fixed size
(set (make-local-variable 'exwm--on-KeyPress) ;KeyPress event handler
'exwm-input--on-KeyPress-line-mode)
;; Properties ;; Properties
(set (make-local-variable 'exwm-window-type) nil) (set (make-local-variable 'exwm-window-type) nil)
(set (make-local-variable 'exwm--geometry) nil) (set (make-local-variable 'exwm--geometry) nil)