From 5c1aa4dc310444c1a73c273b581f9e5868cb9a6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Medra=C3=B1o=20Calvo?= Date: Thu, 16 Aug 2018 12:00:00 +0000 Subject: [PATCH 1/5] Consider windows of the frame being refreshed, not the selected one at the time exwm-layout--refresh runs * exwm-layout.el (exwm-layout--refresh): Consider windows of the frame being refreshed instead of the selected frame. --- exwm-layout.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exwm-layout.el b/exwm-layout.el index 9427607..a03b6fb 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -293,7 +293,7 @@ selected by `other-buffer'." (or exwm-layout-show-all-buffers ;; Exclude X windows on other workspaces (eq frame exwm--frame))) - (setq windows (get-buffer-window-list (current-buffer) 0)) + (setq windows (get-buffer-window-list (current-buffer) 0 frame)) (if (not windows) (when (eq frame exwm--frame) (exwm-layout--hide exwm--id)) From 11fecb5186ceac31aa4a78261da3969ddb6856ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Medra=C3=B1o=20Calvo?= Date: Thu, 16 Aug 2018 12:00:00 +0000 Subject: [PATCH 2/5] Use more explicit argument for excluding minibuffers * exwm-layout.el (exwm-layout--refresh): Use a more intuitive value for specifying exclusion of minibuffers. --- exwm-layout.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/exwm-layout.el b/exwm-layout.el index a03b6fb..18c2c27 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -278,7 +278,7 @@ selected by `other-buffer'." (exwm-layout--hide exwm--id))))) ;; Other frames (e.g. terminal/graphical frame of emacsclient) ;; We shall bury all `exwm-mode' buffers in this case - (setq windows (window-list frame 0)) ;exclude minibuffer + (setq windows (window-list frame 'nomini)) (let ((exwm-layout--other-buffer-exclude-exwm-mode-buffers t)) (dolist (window windows) (with-current-buffer (window-buffer window) @@ -293,7 +293,7 @@ selected by `other-buffer'." (or exwm-layout-show-all-buffers ;; Exclude X windows on other workspaces (eq frame exwm--frame))) - (setq windows (get-buffer-window-list (current-buffer) 0 frame)) + (setq windows (get-buffer-window-list (current-buffer) 'nomini frame)) (if (not windows) (when (eq frame exwm--frame) (exwm-layout--hide exwm--id)) @@ -307,7 +307,7 @@ selected by `other-buffer'." ;; need to display with some other buffer there. (setq vacated-windows (append vacated-windows (cdr (get-buffer-window-list - (current-buffer) 0 t)))) + (current-buffer) 'nomini t)))) ;; Note down when an EXWM-buffer is being covered by this ;; buffer; we don't want it to reappear in some vacated window. (let ((prev-buffer (car-safe @@ -323,7 +323,7 @@ selected by `other-buffer'." (switch-to-prev-buffer window))) ;; Make sure windows floating / on other workspaces are excluded (let ((exwm-layout--other-buffer-exclude-exwm-mode-buffers t)) - (dolist (window (window-list frame 0)) + (dolist (window (window-list frame 'nomini)) (with-current-buffer (window-buffer window) (when (and (derived-mode-p 'exwm-mode) (or exwm--floating-frame (not (eq frame exwm--frame)))) From 633065ad55f84431db6aa380dc2467c38b5fbdcb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Medra=C3=B1o=20Calvo?= Date: Thu, 16 Aug 2018 12:00:00 +0000 Subject: [PATCH 3/5] Don't assume order of `get-buffer-window-list' results It only guarantees that the first result *if* the buffer appears on the selected window. --- exwm-layout.el | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/exwm-layout.el b/exwm-layout.el index 18c2c27..8f3c47f 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -306,8 +306,10 @@ selected by `other-buffer'." ;; windows displaying an EXWM-buffer now displayed elsewhere; we ;; need to display with some other buffer there. (setq vacated-windows - (append vacated-windows (cdr (get-buffer-window-list - (current-buffer) 'nomini t)))) + (append vacated-windows (remove + window + (get-buffer-window-list + (current-buffer) 'nomini t)))) ;; Note down when an EXWM-buffer is being covered by this ;; buffer; we don't want it to reappear in some vacated window. (let ((prev-buffer (car-safe From f820217d00623489a655c79506816397319eb762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Medra=C3=B1o=20Calvo?= Date: Thu, 16 Aug 2018 12:00:00 +0000 Subject: [PATCH 4/5] Split exwm-layout--refresh into three functions * exwm-layout.el (exwm-layout--refresh): Split in three functions for clarity. (exwm-layout--refresh-workspace, exwm-layout--refresh-other) (exwm-layout--refresh-floating): New functions. --- exwm-layout.el | 103 +++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 46 deletions(-) diff --git a/exwm-layout.el b/exwm-layout.el index 8f3c47f..b8c5bb3 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -261,39 +261,50 @@ selected by `other-buffer'." ;; `window-configuration-change-hook' makes the frame selected. (unless frame (setq frame (selected-frame))) + (if (not (exwm-workspace--workspace-p frame)) + (if (frame-parameter frame 'exwm-outer-id) + (exwm-layout--refresh-floating frame) + (exwm-layout--refresh-other frame)) + (exwm-layout--refresh-workspace frame))) + +(defun exwm-layout--refresh-floating (frame) + "Refresh floating frame FRAME." + (exwm--log "Refresh floating %s" frame) + (let ((window (frame-first-window frame))) + (with-current-buffer (window-buffer window) + (when (and (derived-mode-p 'exwm-mode) + ;; It may be a buffer waiting to be killed. + (exwm--id->buffer exwm--id)) + (exwm--log "Refresh floating window #x%x" exwm--id) + (if (exwm-workspace--active-p exwm--frame) + (exwm-layout--show exwm--id window) + (exwm-layout--hide exwm--id)))))) + +(defun exwm-layout--refresh-other (frame) + "Refresh client or nox frame FRAME." + ;; Other frames (e.g. terminal/graphical frame of emacsclient) + ;; We shall bury all `exwm-mode' buffers in this case + (exwm--log "Refresh other %s" frame) + (let ((windows (window-list frame 'nomini)) ;exclude minibuffer + (exwm-layout--other-buffer-exclude-exwm-mode-buffers t)) + (dolist (window windows) + (with-current-buffer (window-buffer window) + (when (derived-mode-p 'exwm-mode) + (switch-to-prev-buffer window)))))) + +(defun exwm-layout--refresh-workspace (frame) + "Refresh workspace frame FRAME." + (exwm--log "Refresh workspace %s" frame) + ;; Workspaces other than the active one can also be refreshed (RandR) (let (covered-buffers ;EXWM-buffers covered by a new X window. - vacated-windows ;Windows previously displaying EXWM-buffers. - windows) - (if (not (exwm-workspace--workspace-p frame)) - (if (frame-parameter frame 'exwm-outer-id) - ;; Refresh a floating frame - (let ((window (frame-first-window frame))) - (with-current-buffer (window-buffer window) - (when (and (derived-mode-p 'exwm-mode) - ;; It may be a buffer waiting to be killed. - (exwm--id->buffer exwm--id)) - (exwm--log "Refresh floating window #x%x" exwm--id) - (if (exwm-workspace--active-p exwm--frame) - (exwm-layout--show exwm--id window) - (exwm-layout--hide exwm--id))))) - ;; Other frames (e.g. terminal/graphical frame of emacsclient) - ;; We shall bury all `exwm-mode' buffers in this case - (setq windows (window-list frame 'nomini)) - (let ((exwm-layout--other-buffer-exclude-exwm-mode-buffers t)) - (dolist (window windows) - (with-current-buffer (window-buffer window) - (when (derived-mode-p 'exwm-mode) - (switch-to-prev-buffer window)))))) - ;; Refresh the whole workspace - ;; Workspaces other than the active one can also be refreshed (RandR) - (exwm--log "Refresh workspace %s" frame) - (dolist (pair exwm--id-buffer-alist) - (with-current-buffer (cdr pair) - (when (and (not exwm--floating-frame) ;exclude floating X windows - (or exwm-layout-show-all-buffers - ;; Exclude X windows on other workspaces - (eq frame exwm--frame))) - (setq windows (get-buffer-window-list (current-buffer) 'nomini frame)) + vacated-windows) ;Windows previously displaying EXWM-buffers. + (dolist (pair exwm--id-buffer-alist) + (with-current-buffer (cdr pair) + (when (and (not exwm--floating-frame) ;exclude floating X windows + (or exwm-layout-show-all-buffers + ;; Exclude X windows on other workspaces + (eq frame exwm--frame))) + (let ((windows (get-buffer-window-list (current-buffer) 'nomini frame))) (if (not windows) (when (eq frame exwm--frame) (exwm-layout--hide exwm--id)) @@ -318,20 +329,20 @@ selected by `other-buffer'." prev-buffer (with-current-buffer prev-buffer (derived-mode-p 'exwm-mode)) - (push prev-buffer covered-buffers)))))))) - ;; Set some sensible buffer to vacated windows. - (let ((exwm-layout--other-buffer-exclude-buffers covered-buffers)) - (dolist (window vacated-windows) - (switch-to-prev-buffer window))) - ;; Make sure windows floating / on other workspaces are excluded - (let ((exwm-layout--other-buffer-exclude-exwm-mode-buffers t)) - (dolist (window (window-list frame 'nomini)) - (with-current-buffer (window-buffer window) - (when (and (derived-mode-p 'exwm-mode) - (or exwm--floating-frame (not (eq frame exwm--frame)))) - (switch-to-prev-buffer window))))) - (exwm-layout--set-client-list-stacking) - (xcb:flush exwm--connection)))) + (push prev-buffer covered-buffers))))))))) + ;; Set some sensible buffer to vacated windows. + (let ((exwm-layout--other-buffer-exclude-buffers covered-buffers)) + (dolist (window vacated-windows) + (switch-to-prev-buffer window))) + ;; Make sure windows floating / on other workspaces are excluded + (let ((exwm-layout--other-buffer-exclude-exwm-mode-buffers t)) + (dolist (window (window-list frame 'nomini)) + (with-current-buffer (window-buffer window) + (when (and (derived-mode-p 'exwm-mode) + (or exwm--floating-frame (not (eq frame exwm--frame)))) + (switch-to-prev-buffer window))))) + (exwm-layout--set-client-list-stacking) + (xcb:flush exwm--connection))) (defun exwm-layout--on-minibuffer-setup () "Refresh layout when minibuffer grows." From d4a772f536eab469b17315e83d843ce3cba3092c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adri=C3=A1n=20Medra=C3=B1o=20Calvo?= Date: Thu, 16 Aug 2018 12:00:00 +0000 Subject: [PATCH 5/5] ; Comment layout algorithm. --- exwm-layout.el | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/exwm-layout.el b/exwm-layout.el index b8c5bb3..98a27d0 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -304,25 +304,31 @@ selected by `other-buffer'." (or exwm-layout-show-all-buffers ;; Exclude X windows on other workspaces (eq frame exwm--frame))) - (let ((windows (get-buffer-window-list (current-buffer) 'nomini frame))) + (let (;; List of windows in current frame displaying the `exwm-mode' + ;; buffers. + (windows (get-buffer-window-list (current-buffer) 'nomini + frame))) (if (not windows) (when (eq frame exwm--frame) + ;; Hide it if it was being shown in this workspace. (exwm-layout--hide exwm--id)) (let ((window (car windows))) (if (eq frame exwm--frame) (when (exwm-workspace--active-p frame) + ;; Show it if `frame' is active. (exwm-layout--show exwm--id window)) + ;; It was last shown in other workspace; move it here. (exwm-workspace-move-window frame exwm--id)) - ;; Make sure this buffer is not displayed elsewhere. Note down - ;; windows displaying an EXWM-buffer now displayed elsewhere; we - ;; need to display with some other buffer there. + ;; Vacate any other windows (in any workspace) showing this + ;; `exwm-mode' buffer. (setq vacated-windows (append vacated-windows (remove window (get-buffer-window-list (current-buffer) 'nomini t)))) - ;; Note down when an EXWM-buffer is being covered by this - ;; buffer; we don't want it to reappear in some vacated window. + ;; Note any `exwm-mode' buffer is being covered by another + ;; `exwm-mode' buffer. We want to avoid that `exwm-mode' + ;; buffer to be reappear in any of the vacated windows. (let ((prev-buffer (car-safe (car-safe (window-prev-buffers window))))) (and