[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/exwm 04e4269 29/64: Improve input focus switch mechanis
From: |
Chris Feng |
Subject: |
[elpa] externals/exwm 04e4269 29/64: Improve input focus switch mechanism |
Date: |
Thu, 17 Sep 2015 23:18:00 +0000 |
branch: externals/exwm
commit 04e426961736c67046fa3809fc14f1ac027dae77
Author: Chris Feng <address@hidden>
Commit: Chris Feng <address@hidden>
Improve input focus switch mechanism
This commit should fix most input focus bugs (especially those related to
floating windows). The actual settings of input focus are delayed to exclude
redundant event. Dead code since this commit is removed.
This commit also fixes a bug for non-floating windows converted form
floating
state. The workaround for `ido-mode` is also improved to properly handle
`exwm-mode` buffers.
---
exwm-floating.el | 16 +++-----
exwm-input.el | 95 +++++++++++++++++++++++++++--------------------------
exwm-manage.el | 11 +-----
exwm-workspace.el | 3 --
exwm.el | 18 +++-------
5 files changed, 62 insertions(+), 81 deletions(-)
diff --git a/exwm-floating.el b/exwm-floating.el
index 7888fd2..e1d8738 100644
--- a/exwm-floating.el
+++ b/exwm-floating.el
@@ -179,12 +179,7 @@
exwm--floating-frame frame)
(set-window-buffer window (current-buffer)) ;this changes current buffer
(set-window-dedicated-p window t))
- (with-current-buffer (exwm--id->buffer id)
- ;; Some window should not get input focus on creation
- ;; FIXME: other conditions?
- (unless (memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY exwm-window-type)
- (x-focus-frame exwm--floating-frame)
- (exwm-input--set-focus id)))))
+ (select-window window)))
(defun exwm-floating--unset-floating (id)
"Make window ID non-floating."
@@ -212,11 +207,12 @@
(set-window-dedicated-p (frame-first-window exwm--floating-frame) nil)
(delete-frame exwm--floating-frame))) ;remove the floating frame
(with-current-buffer buffer
- (setq exwm--floating-frame nil
+ (setq window-size-fixed nil
+ exwm--floating-frame nil
exwm--frame exwm-workspace--current))
- (select-frame exwm-workspace--current t)
- (set-window-buffer nil buffer)
- (exwm-input--set-focus id)))
+ (let ((window (frame-selected-window exwm-workspace--current)))
+ (set-window-buffer window buffer)
+ (select-window window))))
(defun exwm-floating-toggle-floating ()
"Toggle the current window between floating and non-floating states."
diff --git a/exwm-input.el b/exwm-input.el
index 4acacdf..454521f 100644
--- a/exwm-input.el
+++ b/exwm-input.el
@@ -57,8 +57,6 @@ It's updated in several occasions, and only used by
`exwm-input--set-focus'.")
(defun exwm-input--set-focus (id)
"Set input focus to window ID in a proper way."
(with-current-buffer (exwm--id->buffer id)
- (exwm--log "Set focus ID to #x%x" id)
- (setq exwm-input--focus-id id)
(if (and (not exwm--hints-input)
(memq xcb:Atom:WM_TAKE_FOCUS exwm--protocols))
(progn
@@ -79,45 +77,53 @@ It's updated in several occasions, and only used by
`exwm-input--set-focus'.")
:time xcb:Time:CurrentTime)))
(xcb:flush exwm--connection)))
-(defvar exwm-input--focus-id xcb:Window:None
- "The window that is theoretically focused.")
+(defvar exwm-input--focus-buffer nil "The buffer to be focused.")
+(defvar exwm-input--redirected nil
+ "Indicate next update on buffer list is actually a result of redirection.")
+(defvar exwm-input--timer nil "Currently running timer.")
+
+(defun exwm-input--on-buffer-list-update ()
+ "Run in buffer-list-update-hook to track input focus."
+ (let ((frame (selected-frame))
+ (buffer (current-buffer)))
+ (when (and (not (minibufferp buffer))
+ (frame-parameter frame 'exwm-window-id) ;e.g. emacsclient frame
+ (eq buffer (window-buffer))) ;e.g. `with-temp-buffer'
+ (unless (and exwm-input--redirected
+ exwm-input--focus-buffer
+ (with-current-buffer exwm-input--focus-buffer
+ exwm--floating-frame))
+ (setq exwm-input--focus-buffer buffer)
+ (when exwm-input--timer (cancel-timer exwm-input--timer))
+ (setq exwm-input--timer
+ (run-with-timer 0.01 nil 'exwm-input--update-focus)))
+ (setq exwm-input--redirected nil))))
+
+(defun exwm-input--on-focus-in ()
+ "Run in focus-in-hook to remove redirected focus on frame."
+ (let ((frame (selected-frame)))
+ (when (and (frame-parameter frame 'exwm-window-id)
+ (not (memq frame exwm-workspace--list)))
+ (setq exwm-input--redirected t))))
(defun exwm-input--update-focus ()
"Update input focus."
- (when (and (frame-parameter nil 'exwm-window-id) ;e.g. emacsclient frame
- (eq (current-buffer) (window-buffer))) ;e.g. `with-temp-buffer'
- (if (eq major-mode 'exwm-mode)
- (progn (exwm--log "Set focus ID to #x%x" exwm--id)
- (setq exwm-input--focus-id exwm--id)
- (when exwm--floating-frame
- (if (eq (selected-frame) exwm--floating-frame)
- ;; Cancel the possible input focus redirection
- (progn
- (exwm--log "Cancel input focus redirection on %s"
- exwm--floating-frame)
- (redirect-frame-focus exwm--floating-frame nil))
- ;; Focus the floating frame
- (exwm--log "Focus on floating frame %s"
- exwm--floating-frame)
- (x-focus-frame exwm--floating-frame)))
- ;; Finally focus the window
- (when (exwm--id->buffer exwm-input--focus-id)
- (exwm-input--set-focus exwm-input--focus-id)))
- (let ((buffer (exwm--id->buffer exwm-input--focus-id)))
- (when (and buffer (eq (selected-frame) exwm-workspace--current))
- (with-current-buffer buffer
- (exwm--log "Set focus ID to #x%x" xcb:Window:None)
- (setq exwm-input--focus-id xcb:Window:None)
- (if exwm--floating-frame
- (unless (active-minibuffer-window)
- ;; Redirect input focus to the workspace frame
- (exwm--log "Redirect input focus (%s => %s)"
- exwm--floating-frame exwm-workspace--current)
- (redirect-frame-focus exwm--floating-frame
- exwm-workspace--current))
- ;; Focus the workspace frame
- (exwm--log "Focus on workspace %s" exwm-workspace--current)
- (x-focus-frame exwm-workspace--current))))))))
+ (when exwm-input--focus-buffer
+ (with-current-buffer exwm-input--focus-buffer
+ (exwm--log "Set focus on %s" exwm-input--focus-buffer)
+ (setq exwm-input--focus-buffer nil)
+ (if (eq major-mode 'exwm-mode)
+ (progn
+ (when exwm--floating-frame
+ (redirect-frame-focus exwm--floating-frame nil)
+ (select-frame-set-input-focus exwm--floating-frame t))
+ (exwm-input--set-focus exwm--id))
+ (select-frame-set-input-focus exwm-workspace--current t)
+ (dolist (pair exwm--id-buffer-alist)
+ (with-current-buffer (cdr pair)
+ (when (and exwm--floating-frame
+ (eq exwm--frame exwm-workspace--current))
+ (redirect-frame-focus exwm--floating-frame exwm--frame))))))))
(defun exwm-input--finish-key-sequence ()
"Mark the end of a key sequence (with the aid of `pre-command-hook')."
@@ -169,12 +175,8 @@ It's updated in several occasions, and only used by
`exwm-input--set-focus'.")
;; Resize
(exwm-floating--start-moveresize event))
(t
- ;; Click to focus
- (unless (and (boundp 'exwm--id) (= event exwm--id))
- (with-current-buffer (exwm--id->buffer event)
- (select-frame-set-input-focus (or exwm--floating-frame
- exwm--frame))
- (select-window (get-buffer-window nil 'visible))))
+ (select-window (get-buffer-window (exwm--id->buffer event)
+ 'visible))
;; The event should be replayed
(setq mode xcb:Allow:ReplayPointer))))
(xcb:+request exwm--connection
@@ -246,7 +248,6 @@ It's updated in several occasions, and only used by
`exwm-input--set-focus'.")
;; (when (and keysym
;; (setq event (xcb:keysyms:keysym->event keysym state))
;; (or exwm-input--during-key-sequence
-;; (= exwm-input--focus-id xcb:Window:None)
;; (setq window (active-minibuffer-window))
;; (eq event ?\C-c) ;mode-specific key
;; (memq event exwm-input--global-prefix-keys)
@@ -273,7 +274,6 @@ It's updated in several occasions, and only used by
`exwm-input--set-focus'.")
(if (and keysym
(setq event (xcb:keysyms:keysym->event keysym state))
(or exwm-input--during-key-sequence
- (= exwm-input--focus-id xcb:Window:None)
(setq minibuffer-window (active-minibuffer-window))
(eq event ?\C-c) ;mode-specific key
(memq event exwm-input--global-prefix-keys)
@@ -466,7 +466,8 @@ SIMULATION-KEYS is a list of alist (key-sequence1 .
key-sequence2)."
;; `pre-command-hook' marks the end of a key sequence (existing or not)
(add-hook 'pre-command-hook 'exwm-input--finish-key-sequence)
;; Update focus when buffer list updates
- (add-hook 'buffer-list-update-hook 'exwm-input--update-focus)
+ (add-hook 'buffer-list-update-hook 'exwm-input--on-buffer-list-update)
+ (add-hook 'focus-in-hook 'exwm-input--on-focus-in)
;; Update prefix keys for global keys
(exwm-input--update-global-prefix-keys))
diff --git a/exwm-manage.el b/exwm-manage.el
index fc61e50..d1736ff 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -183,15 +183,8 @@ corresponding buffer.")
(let ((floating exwm--floating-frame))
(kill-buffer)
(when floating
- (if (eq 'exwm-mode
- (with-current-buffer
- (window-buffer
- (frame-first-window exwm-workspace--current))
- major-mode))
- ;; Input focus is to be set on a window
- (x-focus-frame exwm-workspace--current)
- ;; Set input focus on a frame
- (select-frame-set-input-focus exwm-workspace--current))))))))
+ (select-window
+ (frame-selected-window exwm-workspace--current))))))))
(defun exwm-manage--scan ()
"Search for existing windows and try to manage them."
diff --git a/exwm-workspace.el b/exwm-workspace.el
index bcac917..09112d2 100644
--- a/exwm-workspace.el
+++ b/exwm-workspace.el
@@ -188,9 +188,6 @@ The optional FORCE option is for internal use only."
;; Move the window itself
(bury-buffer)
(exwm-layout--hide id)
- ;; Force update input focus
- (setq exwm-input--focus-id xcb:Window:None)
- (exwm-input--update-focus)
(xcb:+request exwm--connection
(make-instance 'xcb:ReparentWindow
:window id
diff --git a/exwm.el b/exwm.el
index 7e909cd..989bf88 100644
--- a/exwm.el
+++ b/exwm.el
@@ -195,15 +195,9 @@
(defun exwm-reset ()
"Reset window to standard state: non-fullscreen, line-mode."
(interactive)
- (unless (frame-parameter nil 'exwm-window-id)
- ;; Move focus away form a non-EXWM frame
- (x-focus-frame exwm-workspace--current))
(with-current-buffer (window-buffer)
(when (eq major-mode 'exwm-mode)
(when exwm--fullscreen (exwm-layout-unset-fullscreen))
- ;; Force update input focus
- (setq exwm-input--focus-id xcb:Window:None)
- (exwm-input--update-focus)
;; Force refresh
(exwm-layout--refresh)
(exwm-input-grab-keyboard))))
@@ -709,12 +703,12 @@
(defun exwm--ido-buffer-window-other-frame (orig-fun buffer)
"Wrapper for `ido-buffer-window-other-frame' to exclude invisible windows."
- (let* ((window (funcall orig-fun buffer))
- (frame (window-frame window)))
- ;; Exclude windows on other workspaces
- (unless (and (memq frame exwm-workspace--list)
- (not (eq frame exwm-workspace--current)))
- window)))
+ (with-current-buffer buffer
+ (if (eq major-mode 'exwm-mode)
+ ;; `ido-mode' works well with `exwm-mode' buffers
+ (funcall orig-fun buffer)
+ ;; Other buffers should be selected within the same workspace
+ (get-buffer-window buffer exwm-workspace--current))))
(defun exwm--fix-ido-buffer-window-other-frame ()
"Fix `ido-buffer-window-other-frame'."
- [elpa] externals/exwm 048994c 24/64: Remove redundant code caused by the concurrency of events (continued), (continued)
- [elpa] externals/exwm 048994c 24/64: Remove redundant code caused by the concurrency of events (continued), Chris Feng, 2015/09/17
- [elpa] externals/exwm 35560a4 30/64: Minor fixes for emacsclient, Chris Feng, 2015/09/17
- [elpa] externals/exwm b755296 26/64: Remove redundant code caused by the concurrency of events (contd, 2), Chris Feng, 2015/09/17
- [elpa] externals/exwm 7bfd429 33/64: Honor `value-mask` field in ConfigureRequest event, Chris Feng, 2015/09/17
- [elpa] externals/exwm dba43b0 32/64: Fix input focus stealing, Chris Feng, 2015/09/17
- [elpa] externals/exwm d998b42 34/64: Provide hooks run when the floating state of a window changes (close #28), Chris Feng, 2015/09/17
- [elpa] externals/exwm 15ad591 35/64: Fix bug when moving a window to the current workspace, Chris Feng, 2015/09/17
- [elpa] externals/exwm 43b00d2 36/64: fix buffer renaming, Chris Feng, 2015/09/17
- [elpa] externals/exwm 2d07429 39/64: Merge branch 'move-window-fix' of https://github.com/pipcet/exwm into pipcet-move-window-fix, Chris Feng, 2015/09/17
- [elpa] externals/exwm 5882015 40/64: Merge branch 'pipcet-move-window-fix', Chris Feng, 2015/09/17
- [elpa] externals/exwm 04e4269 29/64: Improve input focus switch mechanism,
Chris Feng <=
- [elpa] externals/exwm 7120291 38/64: Merge branch 'pipcet-robustness', Chris Feng, 2015/09/17
- [elpa] externals/exwm 5210e13 41/64: Only manage windows mapped as the direct children of root window (close #38), Chris Feng, 2015/09/17
- [elpa] externals/exwm 07e59e0 31/64: Fix multi-screen bugs, Chris Feng, 2015/09/17
- [elpa] externals/exwm d1806e9 37/64: Improve code robustness., Chris Feng, 2015/09/17
- [elpa] externals/exwm bb4ebde 46/64: Fix `exwm-workspace-rename-buffer`, Chris Feng, 2015/09/17
- [elpa] externals/exwm 94bdbfc 42/64: Avoid using the "no window manager" code in Emacs, Chris Feng, 2015/09/17
- [elpa] externals/exwm 874c383 43/64: Merge pull request #42 from pipcet/ewmh-fullscreen, Chris Feng, 2015/09/17
- [elpa] externals/exwm 5f9f673 47/64: Fix window size calculations, Chris Feng, 2015/09/17
- [elpa] externals/exwm 7032ee7 48/64: Re-enable complete refresh of keyboard mapping, Chris Feng, 2015/09/17
- [elpa] externals/exwm 981293f 44/64: Replay KeyPress events instead of fake them in line-mode, Chris Feng, 2015/09/17