about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChris Feng <chris.w.feng@gmail.com>2015-08-13T04·02+0800
committerChris Feng <chris.w.feng@gmail.com>2015-08-13T04·02+0800
commit07e59e0429c4b13a5036e9a207e37fc02135f599 (patch)
treed8bdf8d27ecdbbb115775e0ca8a1b4e4f91ea58f
parent35560a49d6c03f96c1f62bfee72ee667cffadb9e (diff)
Fix multi-screen bugs
* RandR module is now made optional; users can enable it with
  `exwm-randr-enable`.
* Correct the calculation of sizes/coordinates at various places.
* Input focus is now tracked with (Emacs) window instead of buffer since the
  latter can be ambiguous in multi-screen settings.
-rw-r--r--exwm-floating.el14
-rw-r--r--exwm-input.el23
-rw-r--r--exwm-layout.el19
-rw-r--r--exwm-manage.el13
-rw-r--r--exwm-randr.el13
-rw-r--r--exwm.el2
6 files changed, 54 insertions, 30 deletions
diff --git a/exwm-floating.el b/exwm-floating.el
index e1d8738270d5..06d6fa505c88 100644
--- a/exwm-floating.el
+++ b/exwm-floating.el
@@ -39,8 +39,9 @@
 (defun exwm-floating--set-floating (id)
   "Make window ID floating."
   (interactive)
-  (when (get-buffer-window (exwm--id->buffer id)) ;window in non-floating state
-    (set-window-buffer (selected-window) (other-buffer))) ;hide it first
+  (let ((window (get-buffer-window (exwm--id->buffer id))))
+    (when window                        ;window in non-floating state
+      (set-window-buffer window (other-buffer)))) ;hide it first
   (let* ((original-frame
           (with-current-buffer (exwm--id->buffer id)
             (if (and exwm-transient-for (exwm--id->buffer exwm-transient-for))
@@ -78,8 +79,8 @@
         (exwm-workspace--update-switch-history)))
     ;; Fix illegal parameters
     ;; FIXME: check normal hints restrictions
-    (let* ((display-width (x-display-pixel-width))
-           (display-height (- (x-display-pixel-height)
+    (let* ((display-width (frame-pixel-width original-frame))
+           (display-height (- (frame-pixel-height original-frame)
                               (window-pixel-height (minibuffer-window
                                                     original-frame))
                               (* 2 (window-mode-line-height))
@@ -373,6 +374,8 @@
   "Perform move/resize."
   (when exwm-floating--moveresize-calculate
     (let ((obj (make-instance 'xcb:MotionNotify))
+          (frame-x (or (frame-parameter exwm-workspace--current 'exwm-x) 0))
+          (frame-y (or (frame-parameter exwm-workspace--current 'exwm-y) 0))
           result)
       (xcb:unmarshal obj data)
       (setq result (funcall exwm-floating--moveresize-calculate
@@ -380,7 +383,8 @@
       (xcb:+request exwm--connection
           (make-instance 'xcb:ConfigureWindow
                          :window (elt result 0) :value-mask (elt result 1)
-                         :x (elt result 2) :y (elt result 3)
+                         :x (- (elt result 2) frame-x)
+                         :y (-  (elt result 3) frame-y)
                          :width (elt result 4) :height (elt result 5)))
       (xcb:flush exwm--connection))))
 
diff --git a/exwm-input.el b/exwm-input.el
index b9a5f206e799..0ef72325bb0a 100644
--- a/exwm-input.el
+++ b/exwm-input.el
@@ -77,7 +77,7 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
                          :time xcb:Time:CurrentTime)))
     (xcb:flush exwm--connection)))
 
-(defvar exwm-input--focus-buffer nil "The buffer to be focused.")
+(defvar exwm-input--focus-window nil "The (Emacs) window to be focused.")
 (defvar exwm-input--redirected nil
   "Indicate next update on buffer list is actually a result of redirection.")
 (defvar exwm-input--timer nil "Currently running timer.")
@@ -85,15 +85,17 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
 (defun exwm-input--on-buffer-list-update ()
   "Run in buffer-list-update-hook to track input focus."
   (let ((frame (selected-frame))
+        (window (selected-window))
         (buffer (current-buffer)))
     (when (and (not (minibufferp buffer))
                (frame-parameter frame 'exwm-window-id) ;e.g. emacsclient frame
                (eq buffer (window-buffer))) ;e.g. `with-temp-buffer'
       (unless (and exwm-input--redirected
-                   exwm-input--focus-buffer
-                   (with-current-buffer exwm-input--focus-buffer
+                   exwm-input--focus-window
+                   (with-current-buffer (window-buffer
+                                         exwm-input--focus-window)
                      exwm--floating-frame))
-        (setq exwm-input--focus-buffer buffer)
+        (setq exwm-input--focus-window window)
         (when exwm-input--timer (cancel-timer exwm-input--timer))
         (setq exwm-input--timer
               (run-with-timer 0.01 nil 'exwm-input--update-focus)))
@@ -108,22 +110,23 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
 
 (defun exwm-input--update-focus ()
   "Update input focus."
-  (when exwm-input--focus-buffer
-    (with-current-buffer exwm-input--focus-buffer
-      (exwm--log "Set focus on %s" exwm-input--focus-buffer)
-      (setq exwm-input--focus-buffer nil)
+  (when exwm-input--focus-window
+    (with-current-buffer (window-buffer exwm-input--focus-window)
+      (exwm--log "Set focus on %s" exwm-input--focus-window)
       (if (eq major-mode 'exwm-mode)
           (progn
             (when exwm--floating-frame
               (redirect-frame-focus exwm--floating-frame nil)
               (select-frame-set-input-focus exwm--floating-frame t))
             (exwm-input--set-focus exwm--id))
-        (select-frame-set-input-focus exwm-workspace--current t)
+        (select-frame-set-input-focus (window-frame exwm-input--focus-window)
+                                      t)
         (dolist (pair exwm--id-buffer-alist)
           (with-current-buffer (cdr pair)
             (when (and exwm--floating-frame
                        (eq exwm--frame exwm-workspace--current))
-              (redirect-frame-focus exwm--floating-frame exwm--frame))))))))
+              (redirect-frame-focus exwm--floating-frame exwm--frame)))))
+      (setq exwm-input--focus-window nil))))
 
 (defun exwm-input--finish-key-sequence ()
   "Mark the end of a key sequence (with the aid of `pre-command-hook')."
diff --git a/exwm-layout.el b/exwm-layout.el
index f2d4eb0cbeb9..a6b450f7daf5 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -111,8 +111,9 @@
                                                xcb:ConfigWindow:Width
                                                xcb:ConfigWindow:Height)
                            :x 0 :y 0
-                           :width (x-display-pixel-width)
-                           :height (x-display-pixel-height))))
+                           :width (frame-pixel-width exwm-workspace--current)
+                           :height (frame-pixel-height
+                                    exwm-workspace--current))))
       (xcb:flush exwm--connection))
     (xcb:+request exwm--connection
         (make-instance 'xcb:ConfigureWindow
@@ -122,8 +123,8 @@
                                            xcb:ConfigWindow:Width
                                            xcb:ConfigWindow:Height)
                        :x 0 :y 0
-                       :width (x-display-pixel-width)
-                       :height (x-display-pixel-height)))
+                       :width (frame-pixel-width exwm-workspace--current)
+                       :height (frame-pixel-height exwm-workspace--current)))
     (xcb:+request exwm--connection
         (make-instance 'xcb:ewmh:set-_NET_WM_STATE
                        :window exwm--id
@@ -168,11 +169,11 @@
         (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))))
+              (when (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
diff --git a/exwm-manage.el b/exwm-manage.el
index d1736ff9a4cf..4f11874d3a3e 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -98,8 +98,14 @@ corresponding buffer.")
                                :window id
                                :value-mask (logior xcb:ConfigWindow:X
                                                    xcb:ConfigWindow:Y)
-                               :x (/ (- (x-display-pixel-width) width) 2)
-                               :y (/ (- (x-display-pixel-height) height) 2)))))
+                               :x (/ (- (frame-pixel-width
+                                         exwm-workspace--current)
+                                        width)
+                                     2)
+                               :y (/ (- (frame-pixel-height
+                                         exwm-workspace--current)
+                                        height)
+                                     2)))))
         (xcb:flush exwm--connection)
         (setq kill-buffer-query-functions nil)
         (setq exwm--id-buffer-alist (assq-delete-all id exwm--id-buffer-alist))
@@ -277,7 +283,8 @@ corresponding buffer.")
             (setq edges
                   (if exwm--fullscreen
                       (list 0 0
-                            (x-display-pixel-width) (x-display-pixel-height))
+                            (frame-pixel-width exwm-workspace--current)
+                            (frame-pixel-height exwm-workspace--current))
                     (or exwm--floating-edges
                         (window-inside-absolute-pixel-edges
                          (get-buffer-window)))))
diff --git a/exwm-randr.el b/exwm-randr.el
index c9ad1ce6ae7b..cd40fb43bd3f 100644
--- a/exwm-randr.el
+++ b/exwm-randr.el
@@ -26,8 +26,11 @@
 ;; tools such as xrandr(1) to properly configure RandR first. This dependency
 ;; may be removed in the future, but more work is needed before that.
 
-;; To use this module, first set `exwm-randr-workspace-output-plist':
+;; To use this module, first load/enable it and properly configure the variable
+;; `exwm-randr-workspace-output-plist':
+;;   (require 'exwm-randr)
 ;;   (setq exwm-randr-workspace-output-plist '(0 "VGA1"))
+;;   (exwm-randr-enable)
 ;; Then configure RandR with 'xrandr':
 ;;   $ xrandr --output VGA1 --left-of LVDS1 --auto
 ;; With above lines, workspace 0 should be assigned to the output named "VGA1",
@@ -82,6 +85,8 @@
           (setq geometry default-geometry
                 output nil))
         (set-frame-parameter frame 'exwm-randr-output output)
+        (set-frame-parameter frame 'exwm-x (elt geometry 0))
+        (set-frame-parameter frame 'exwm-y (elt geometry 1))
         (xcb:+request exwm--connection
             (make-instance 'xcb:ConfigureWindow
                            :window (frame-parameter frame 'exwm-outer-id)
@@ -108,9 +113,11 @@
         (exwm-randr--refresh)
         (xcb:+event exwm--connection 'xcb:randr:ScreenChangeNotify
                     (lambda (data synthetic)
+                      (exwm--log "(RandR) ScreenChangeNotify")
                       (exwm-randr--refresh)))
         ;; (xcb:+event exwm--connection 'xcb:randr:Notify
         ;;             (lambda (data synthetic)
+        ;;               (exwm--log "(RandR) Notify")
         ;;               (exwm-randr--refresh)))
         (xcb:+request exwm--connection
             (make-instance 'xcb:randr:SelectInput
@@ -124,6 +131,10 @@
                            ))
         (xcb:flush exwm--connection)))))
 
+(defun exwm-randr-enable ()
+  "Enable RandR support for EXWM."
+  (add-hook 'exwm-init-hook 'exwm-randr--init))
+
 
 
 (provide 'exwm-randr)
diff --git a/exwm.el b/exwm.el
index d33ab2619044..7dffa87aec4b 100644
--- a/exwm.el
+++ b/exwm.el
@@ -144,7 +144,6 @@
 (require 'exwm-floating)
 (require 'exwm-manage)
 (require 'exwm-input)
-(require 'exwm-randr)
 
 (defvar exwm-debug-on nil "Non-nil to turn on debug for EXWM.")
 
@@ -616,7 +615,6 @@
         (exwm-floating--init)
         (exwm-manage--init)
         (exwm-input--init)
-        (exwm-randr--init)
         (exwm--unlock)
         ;; Manage exiting windows
         (exwm-manage--scan)