From 2ad1a89db0c9e3704c79294620c5ed4925b143eb Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Fri, 7 Aug 2015 12:41:15 +0800 Subject: [PATCH] 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 --- exwm-input.el | 30 +++++++++++++++--------------- exwm-workspace.el | 20 ++++++++++---------- exwm.el | 6 ++++-- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/exwm-input.el b/exwm-input.el index 6d72cc2..f94cf50 100644 --- a/exwm-input.el +++ b/exwm-input.el @@ -161,7 +161,9 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.") (let ((obj (make-instance 'xcb:KeyPress))) (xcb:unmarshal obj data) (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-prefix-keys nil @@ -211,7 +213,7 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.") ;; ;; in this case. ;; ;; P.S.; to use this implementation, comment out the KeyRelease listener ;; ;; 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." ;; (with-slots (detail state) obj ;; (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 ;; (e.g. xterm) ignore the synthetic key events, making it only viable for EXWM ;; 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." (with-slots (detail state) obj (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))) (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." (with-slots (detail state) obj (let ((keysym (xcb:keysyms:keycode->keysym exwm--connection detail state)) event) (when (and keysym (setq event (xcb:keysyms:keysym->event keysym state))) - (setq exwm-input--temp-line-mode t - exwm-input--during-key-sequence t) - (push event unread-command-events) - (exwm-input--grab-keyboard))))) ;grab keyboard temporarily - -(defalias 'exwm-input--handle-KeyPress 'exwm-input--handle-KeyPress-line-mode - "Generic function for handling KeyPress event.") + (when (eq major-mode 'exwm-mode) + (setq exwm-input--temp-line-mode t + exwm-input--during-key-sequence t) + (exwm-input--grab-keyboard)) ;grab keyboard temporarily + (push event unread-command-events))))) (defun exwm-input--grab-keyboard (&optional id) "Grab all key events on window ID." (unless id (setq id (exwm--buffer->id (window-buffer)))) + (cl-assert id) (when (xcb:+request-checked+request-check exwm--connection (make-instance 'xcb:GrabKey :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 :keyboard-mode xcb:GrabMode:Async)) (exwm--log "Failed to grab keyboard for #x%x" id)) - (defalias 'exwm-input--handle-KeyPress - 'exwm-input--handle-KeyPress-line-mode)) + (setq exwm--on-KeyPress 'exwm-input--on-KeyPress-line-mode)) (defun exwm-input--release-keyboard (&optional id) "Ungrab all key events on window ID." (unless id (setq id (exwm--buffer->id (window-buffer)))) + (cl-assert id) (when (xcb:+request-checked+request-check exwm--connection (make-instance 'xcb:UngrabKey :key xcb:Grab:Any :grab-window id :modifiers xcb:ModMask:Any)) (exwm--log "Failed to release keyboard for #x%x" id)) - (defalias 'exwm-input--handle-KeyPress - 'exwm-input--handle-KeyPress-char-mode)) + (setq exwm--on-KeyPress 'exwm-input--on-KeyPress-char-mode)) (defun exwm-input-grab-keyboard (&optional id) "Switch to line-mode." diff --git a/exwm-workspace.el b/exwm-workspace.el index d700f41..b175543 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -98,20 +98,20 @@ The optional FORCE option is for internal use only." (interactive (list - (let* ((history-add-new-input nil) ;prevent modifying history - (idx (read-from-minibuffer - "Workspace: " (elt exwm-workspace--switch-history - exwm-workspace-current-index) - exwm-workspace--switch-map nil - `(exwm-workspace--switch-history - . ,(1+ exwm-workspace-current-index))))) - (cl-position idx exwm-workspace--switch-history :test 'equal)))) - (unless exwm-workspace--switch-lock + (unless (and (eq major-mode 'exwm-mode) exwm--fullscreen) ;it's invisible + (let* ((history-add-new-input nil) ;prevent modifying history + (idx (read-from-minibuffer + "Workspace: " (elt exwm-workspace--switch-history + exwm-workspace-current-index) + exwm-workspace--switch-map nil + `(exwm-workspace--switch-history + . ,(1+ exwm-workspace-current-index))))) + (cl-position idx exwm-workspace--switch-history :test 'equal))))) + (unless (or exwm-workspace--switch-lock (not index)) (setq exwm-workspace--switch-lock t) (unless (and (<= 0 index) (< index exwm-workspace-number)) (user-error "[EXWM] Workspace index out of range: %d" index)) (when (or force (/= exwm-workspace-current-index index)) - (exwm-reset) ;exit full screen (let ((frame (elt exwm-workspace--list index))) (setq exwm-workspace--current frame exwm-workspace-current-index index) diff --git a/exwm.el b/exwm.el index 18d8dda..88d7674 100644 --- a/exwm.el +++ b/exwm.el @@ -196,8 +196,8 @@ "Reset window to standard state: non-fullscreen, line-mode." (interactive) (with-current-buffer (window-buffer) - (when (and (eq major-mode 'exwm-mode) exwm--fullscreen) - (exwm-layout-unset-fullscreen) + (when (eq major-mode 'exwm-mode) + (when exwm--fullscreen (exwm-layout-unset-fullscreen)) (exwm-input-grab-keyboard)))) (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--floating-frame-geometry) nil) ;in fullscreen (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 (set (make-local-variable 'exwm-window-type) nil) (set (make-local-variable 'exwm--geometry) nil)