mirror of
https://github.com/ch11ng/exwm.git
synced 2024-11-30 14:38:00 +01:00
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:
parent
edc70eb661
commit
2d4104a0ec
4 changed files with 49 additions and 33 deletions
|
@ -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
|
||||||
|
|
|
@ -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))))
|
||||||
|
|
|
@ -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."
|
||||||
|
|
9
exwm.el
9
exwm.el
|
@ -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)))))
|
||||||
|
|
Loading…
Reference in a new issue