about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Feng <chris.w.feng@gmail.com>2015-08-10T02·55+0800
committerChris Feng <chris.w.feng@gmail.com>2015-08-10T02·55+0800
commit2d4104a0eceb7d043ed1cd6bdd1bda1db4f91a73 (patch)
treef5c4ff13d71d6d2a843e7478398822112cac272a
parentedc70eb6616b818463c94b5ab8c9e3f1dfd177c9 (diff)
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.
-rw-r--r--exwm-floating.el14
-rw-r--r--exwm-input.el6
-rw-r--r--exwm-layout.el53
-rw-r--r--exwm.el9
4 files changed, 49 insertions, 33 deletions
diff --git a/exwm-floating.el b/exwm-floating.el
index 3e9cade15a9f..bc7ee338466b 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 c312ff762bd5..97dfd53e3640 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 414aa37cbc31..4ae4859a224f 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 7c9fa59410c1..4c4d4aff9cec 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)))))