From 2d4104a0eceb7d043ed1cd6bdd1bda1db4f91a73 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Mon, 10 Aug 2015 10:55:28 +0800 Subject: [PATCH] Fix emacsclient bugs `emacsclient` started with `-c` or `-t` argument create a new frame that shall not be used to manage X windows. Also fix some related input focus issues (with some remaining unfixed). Close #17. --- exwm-floating.el | 14 +++++++------ exwm-input.el | 6 ++++-- exwm-layout.el | 53 +++++++++++++++++++++++++++++------------------- exwm.el | 9 ++++---- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/exwm-floating.el b/exwm-floating.el index 3e9cade..bc7ee33 100644 --- a/exwm-floating.el +++ b/exwm-floating.el @@ -53,12 +53,14 @@ (original-id (frame-parameter original-frame 'exwm-window-id)) ;; Create new frame (frame (with-current-buffer "*scratch*" - (make-frame `((minibuffer . nil) ;use the one on workspace - (background-color - . ,exwm-floating-border-color) - (internal-border-width - . ,exwm-floating-border-width) - (unsplittable . t))))) ;and fix the size later + (prog2 + (exwm--lock) + (make-frame + `((minibuffer . nil) ;use the one on workspace + (background-color . ,exwm-floating-border-color) + (internal-border-width . ,exwm-floating-border-width) + (unsplittable . t))) ;and fix the size later + (exwm--unlock)))) (frame-id (string-to-int (frame-parameter frame 'window-id))) (outer-id (string-to-int (frame-parameter frame 'outer-window-id))) (window (frame-first-window frame)) ;and it's the only window diff --git a/exwm-input.el b/exwm-input.el index c312ff7..97dfd53 100644 --- a/exwm-input.el +++ b/exwm-input.el @@ -88,7 +88,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.") "Update input focus." (unless exwm-input--focus-lock (setq exwm-input--focus-lock t) - (when (eq (current-buffer) (window-buffer)) ;e.g. with-temp-buffer + (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) @@ -163,7 +164,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.") ;; Click to focus (unless (and (boundp 'exwm--id) (= event exwm--id)) (exwm--with-current-id event - (raise-frame (or exwm--floating-frame exwm--frame)) + (select-frame-set-input-focus (or exwm--floating-frame + exwm--frame)) (select-window (get-buffer-window nil 'visible)))) ;; The event should be replayed (setq mode xcb:Allow:ReplayPointer)))) diff --git a/exwm-layout.el b/exwm-layout.el index 414aa37..4ae4859 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -160,32 +160,43 @@ (defun exwm-layout--refresh () "Refresh layout." (let ((frame (selected-frame)) - windows placeholder) + (placeholder (get-buffer "*scratch*")) + windows) (if (not (memq frame exwm-workspace--list)) - ;; Refresh a floating frame - (progn - (cl-assert (eq major-mode 'exwm-mode)) - (let ((window (frame-first-window frame))) + (if (frame-parameter frame 'exwm-window-id) + ;; Refresh a floating frame + (progn + (cl-assert (eq major-mode 'exwm-mode)) + (let ((window (frame-first-window frame))) + (with-current-buffer (window-buffer window) + (exwm--log "Refresh floating window #x%x" exwm--id) + (exwm-layout--show exwm--id window)))) + ;; Other frames (e.g. terminal/graphical frame of emacsclient) + ;; We shall bury all `exwm-mode' buffers in this case + (unless placeholder ;create the *scratch* buffer if it's killed + (setq placeholder (get-buffer-create "*scratch*")) + (set-buffer-major-mode placeholder)) + (setq windows (window-list frame 0)) ;exclude minibuffer + (dolist (window windows) (with-current-buffer (window-buffer window) - (exwm--log "Refresh floating window #x%x" exwm--id) - (exwm-layout--show exwm--id window)))) + (when (eq major-mode 'exwm-mode) + (set-window-buffer window placeholder))))) ;; Refresh the whole workspace ;; Workspaces other than the active one can also be refreshed (RandR) (exwm--log "Refresh workspace %s" frame) - (let ((placeholder (get-buffer "*scratch*"))) - (unless placeholder ;create the *scratch* buffer if it's killed - (setq placeholder (get-buffer-create "*scratch*")) - (set-buffer-major-mode placeholder)) - (dolist (pair exwm--id-buffer-alist) - (with-current-buffer (cdr pair) - ;; Exclude windows on other workspaces and floating frames - (when (and (eq frame exwm--frame) (not exwm--floating-frame)) - (setq windows (get-buffer-window-list (current-buffer) 0)) - (if (not windows) - (exwm-layout--hide exwm--id) - (exwm-layout--show exwm--id (car windows)) - (dolist (i (cdr windows)) - (set-window-buffer i placeholder)))))))))) + (unless placeholder ;create the *scratch* buffer if it's killed + (setq placeholder (get-buffer-create "*scratch*")) + (set-buffer-major-mode placeholder)) + (dolist (pair exwm--id-buffer-alist) + (with-current-buffer (cdr pair) + ;; Exclude windows on other workspaces and floating frames + (when (and (eq frame exwm--frame) (not exwm--floating-frame)) + (setq windows (get-buffer-window-list (current-buffer) 0)) + (if (not windows) + (exwm-layout--hide exwm--id) + (exwm-layout--show exwm--id (car windows)) + (dolist (i (cdr windows)) + (set-window-buffer i placeholder))))))))) (defun exwm-layout--on-minibuffer-setup () "Refresh layout when minibuffer grows." diff --git a/exwm.el b/exwm.el index 7c9fa59..4c4d4af 100644 --- a/exwm.el +++ b/exwm.el @@ -195,6 +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)) @@ -400,7 +403,8 @@ (exwm--update-state id t)) ((= atom xcb:Atom:_NET_WM_USER_TIME)) ;ignored (t (exwm--log "Unhandled PropertyNotify: %s(%d)" - (x-get-atom-name atom) atom))))))) + (x-get-atom-name atom exwm-workspace--current) + atom))))))) (defun exwm--on-ClientMessage (raw-data synthetic) "Handle ClientMessage event." @@ -628,9 +632,6 @@ (exwm-input--init) (exwm-randr--init) (exwm--unlock) - ;; Disable events during new frame creation - (add-hook 'before-make-frame-hook 'exwm--lock) - (add-hook 'after-make-frame-functions 'exwm--unlock) ;; Manage exiting windows (exwm-manage--scan) (run-hooks 'exwm-init-hook)))))