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.
This commit is contained in:
Chris Feng 2015-08-10 10:55:28 +08:00
parent edc70eb661
commit 2d4104a0ec
4 changed files with 49 additions and 33 deletions

View file

@ -53,12 +53,14 @@
(original-id (frame-parameter original-frame 'exwm-window-id)) (original-id (frame-parameter original-frame 'exwm-window-id))
;; Create new frame ;; Create new frame
(frame (with-current-buffer "*scratch*" (frame (with-current-buffer "*scratch*"
(make-frame `((minibuffer . nil) ;use the one on workspace (prog2
(background-color (exwm--lock)
. ,exwm-floating-border-color) (make-frame
(internal-border-width `((minibuffer . nil) ;use the one on workspace
. ,exwm-floating-border-width) (background-color . ,exwm-floating-border-color)
(unsplittable . t))))) ;and fix the size later (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))) (frame-id (string-to-int (frame-parameter frame 'window-id)))
(outer-id (string-to-int (frame-parameter frame 'outer-window-id))) (outer-id (string-to-int (frame-parameter frame 'outer-window-id)))
(window (frame-first-window frame)) ;and it's the only window (window (frame-first-window frame)) ;and it's the only window

View file

@ -88,7 +88,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
"Update input focus." "Update input focus."
(unless exwm-input--focus-lock (unless exwm-input--focus-lock
(setq exwm-input--focus-lock t) (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) (if (eq major-mode 'exwm-mode)
(progn (exwm--log "Set focus ID to #x%x" exwm--id) (progn (exwm--log "Set focus ID to #x%x" exwm--id)
(setq exwm-input--focus-id 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 ;; Click to focus
(unless (and (boundp 'exwm--id) (= event exwm--id)) (unless (and (boundp 'exwm--id) (= event exwm--id))
(exwm--with-current-id event (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)))) (select-window (get-buffer-window nil 'visible))))
;; The event should be replayed ;; The event should be replayed
(setq mode xcb:Allow:ReplayPointer)))) (setq mode xcb:Allow:ReplayPointer))))

View file

@ -160,8 +160,10 @@
(defun exwm-layout--refresh () (defun exwm-layout--refresh ()
"Refresh layout." "Refresh layout."
(let ((frame (selected-frame)) (let ((frame (selected-frame))
windows placeholder) (placeholder (get-buffer "*scratch*"))
windows)
(if (not (memq frame exwm-workspace--list)) (if (not (memq frame exwm-workspace--list))
(if (frame-parameter frame 'exwm-window-id)
;; Refresh a floating frame ;; Refresh a floating frame
(progn (progn
(cl-assert (eq major-mode 'exwm-mode)) (cl-assert (eq major-mode 'exwm-mode))
@ -169,10 +171,19 @@
(with-current-buffer (window-buffer window) (with-current-buffer (window-buffer window)
(exwm--log "Refresh floating window #x%x" exwm--id) (exwm--log "Refresh floating window #x%x" exwm--id)
(exwm-layout--show exwm--id window)))) (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)
(when (eq major-mode 'exwm-mode)
(set-window-buffer window placeholder)))))
;; Refresh the whole workspace ;; Refresh the whole workspace
;; Workspaces other than the active one can also be refreshed (RandR) ;; Workspaces other than the active one can also be refreshed (RandR)
(exwm--log "Refresh workspace %s" frame) (exwm--log "Refresh workspace %s" frame)
(let ((placeholder (get-buffer "*scratch*")))
(unless placeholder ;create the *scratch* buffer if it's killed (unless placeholder ;create the *scratch* buffer if it's killed
(setq placeholder (get-buffer-create "*scratch*")) (setq placeholder (get-buffer-create "*scratch*"))
(set-buffer-major-mode placeholder)) (set-buffer-major-mode placeholder))
@ -185,7 +196,7 @@
(exwm-layout--hide exwm--id) (exwm-layout--hide exwm--id)
(exwm-layout--show exwm--id (car windows)) (exwm-layout--show exwm--id (car windows))
(dolist (i (cdr windows)) (dolist (i (cdr windows))
(set-window-buffer i placeholder)))))))))) (set-window-buffer i placeholder)))))))))
(defun exwm-layout--on-minibuffer-setup () (defun exwm-layout--on-minibuffer-setup ()
"Refresh layout when minibuffer grows." "Refresh layout when minibuffer grows."

View file

@ -195,6 +195,9 @@
(defun exwm-reset () (defun exwm-reset ()
"Reset window to standard state: non-fullscreen, line-mode." "Reset window to standard state: non-fullscreen, line-mode."
(interactive) (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) (with-current-buffer (window-buffer)
(when (eq major-mode 'exwm-mode) (when (eq major-mode 'exwm-mode)
(when exwm--fullscreen (exwm-layout-unset-fullscreen)) (when exwm--fullscreen (exwm-layout-unset-fullscreen))
@ -400,7 +403,8 @@
(exwm--update-state id t)) (exwm--update-state id t))
((= atom xcb:Atom:_NET_WM_USER_TIME)) ;ignored ((= atom xcb:Atom:_NET_WM_USER_TIME)) ;ignored
(t (exwm--log "Unhandled PropertyNotify: %s(%d)" (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) (defun exwm--on-ClientMessage (raw-data synthetic)
"Handle ClientMessage event." "Handle ClientMessage event."
@ -628,9 +632,6 @@
(exwm-input--init) (exwm-input--init)
(exwm-randr--init) (exwm-randr--init)
(exwm--unlock) (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 ;; Manage exiting windows
(exwm-manage--scan) (exwm-manage--scan)
(run-hooks 'exwm-init-hook))))) (run-hooks 'exwm-init-hook)))))