diff options
author | Chris Feng <chris.w.feng@gmail.com> | 2016-02-03T05·30+0800 |
---|---|---|
committer | Chris Feng <chris.w.feng@gmail.com> | 2016-02-03T05·30+0800 |
commit | 2d42fee327f92b01444718cfc83ce5f00716fa33 (patch) | |
tree | 90074501f43a1c61b0f88508c5ecdcff50b09981 /exwm-layout.el | |
parent | 0db666b4fbbf0ce4446e5e5205fa70822cd93fd6 (diff) | |
parent | d8281abca4bc5182040a7866560a1806c59176d4 (diff) |
Merge branch 'feat/virtual-root'
Diffstat (limited to 'exwm-layout.el')
-rw-r--r-- | exwm-layout.el | 157 |
1 files changed, 75 insertions, 82 deletions
diff --git a/exwm-layout.el b/exwm-layout.el index 2374823feabb..a290876bb35c 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -30,41 +30,72 @@ (defvar exwm-floating-border-width) +(defun exwm-layout--resize-container (id container x y width height + &optional container-only) + "Resize a container (and its content unless CONTAINER-ONLY is non-nil)." + (xcb:+request exwm--connection + (make-instance 'xcb:ConfigureWindow + :window container + :value-mask (eval-when-compile + (logior xcb:ConfigWindow:X + xcb:ConfigWindow:Y + xcb:ConfigWindow:Width + xcb:ConfigWindow:Height)) + :x x :y y :width width :height height)) + (unless container-only + (xcb:+request exwm--connection + (make-instance 'xcb:ConfigureWindow + :window id + :value-mask (eval-when-compile + (logior xcb:ConfigWindow:Width + xcb:ConfigWindow:Height)) + :width width :height height)))) + ;;;###autoload (defun exwm-layout--show (id &optional window) "Show window ID exactly fit in the Emacs window WINDOW." (exwm--log "Show #x%x in %s" id window) (xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window id)) + (with-current-buffer (exwm--id->buffer id) + (xcb:+request exwm--connection + (make-instance 'xcb:MapWindow :window exwm--container))) (xcb:+request exwm--connection (make-instance 'xcb:icccm:set-WM_STATE :window id :state xcb:icccm:WM_STATE:NormalState :icon xcb:Window:None)) - (let* ((buffer (exwm--id->buffer id)) - (edges (or (and buffer - (with-current-buffer buffer exwm--floating-edges)) - (window-inside-absolute-pixel-edges window))) + (let* ((edges (window-inside-absolute-pixel-edges window)) (width (- (elt edges 2) (elt edges 0))) - (height (- (elt edges 3) (elt edges 1))) - x y) - (if exwm--floating-edges - ;; The relative position of a floating X window is determinate - (setq x exwm-floating-border-width - y exwm-floating-border-width) - (let ((relative-edges (window-inside-pixel-edges window))) - (setq x (elt relative-edges 0) - y (elt relative-edges 1)))) - (xcb:+request exwm--connection - (make-instance 'xcb:ConfigureWindow - :window id - :value-mask (eval-when-compile - (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y - xcb:ConfigWindow:Width - xcb:ConfigWindow:Height - xcb:ConfigWindow:StackMode)) - :x x :y y :width width :height height - ;; In order to put non-floating window at bottom - :stack-mode xcb:StackMode:Below)) + (height (- (elt edges 3) (elt edges 1)))) + (with-current-buffer (exwm--id->buffer id) + (if exwm--floating-frame + ;; A floating X window is of the same size as the Emacs window, + ;; whereas its container is of the same size as the Emacs frame. + (progn + (xcb:+request exwm--connection + (make-instance 'xcb:ConfigureWindow + :window exwm--container + :value-mask (logior xcb:ConfigWindow:Width + xcb:ConfigWindow:Height) + :width (frame-pixel-width exwm--floating-frame) + :height (frame-pixel-height + exwm--floating-frame))) + (xcb:+request exwm--connection + (make-instance 'xcb:ConfigureWindow + :window exwm--id + :value-mask (logior xcb:ConfigWindow:X + xcb:ConfigWindow:Y + xcb:ConfigWindow:Width + xcb:ConfigWindow:Height) + :x exwm-floating-border-width + :y exwm-floating-border-width + :width width + :height height))) + (let ((relative-edges (window-inside-pixel-edges window))) + (exwm-layout--resize-container id exwm--container + (elt relative-edges 0) + (elt relative-edges 1) + width height + (active-minibuffer-window))))) (xcb:+request exwm--connection (make-instance 'xcb:SendEvent :propagate 0 :destination id @@ -96,6 +127,9 @@ (make-instance 'xcb:ChangeWindowAttributes :window id :value-mask xcb:CW:EventMask :event-mask exwm--client-event-mask)) + (with-current-buffer (exwm--id->buffer id) + (xcb:+request exwm--connection + (make-instance 'xcb:UnmapWindow :window exwm--container))) (xcb:+request exwm--connection (make-instance 'xcb:icccm:set-WM_STATE :window id @@ -112,38 +146,16 @@ (user-error "Already in full-screen mode.")) ;; Set the floating frame fullscreen first when the client is floating (when exwm--floating-frame - (let* ((outer-id (frame-parameter exwm--floating-frame 'exwm-outer-id)) - (geometry (xcb:+request-unchecked+reply exwm--connection + (let* ((geometry (xcb:+request-unchecked+reply exwm--connection (make-instance 'xcb:GetGeometry - :drawable outer-id)))) - (setq exwm--floating-frame-geometry - (vector (slot-value geometry 'x) (slot-value geometry 'y) - (slot-value geometry 'width) - (slot-value geometry 'height))) - (xcb:+request exwm--connection - (make-instance 'xcb:ConfigureWindow - :window outer-id - :value-mask (eval-when-compile - (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y - xcb:ConfigWindow:Width - xcb:ConfigWindow:Height)) - :x 0 :y 0 - :width (frame-pixel-width exwm-workspace--current) - :height (frame-pixel-height - exwm-workspace--current)))) + :drawable exwm--container)))) + (setq exwm--floating-frame-position + (vector (slot-value geometry 'x) (slot-value geometry 'y)))) (xcb:flush exwm--connection)) - (xcb:+request exwm--connection - (make-instance 'xcb:ConfigureWindow - :window exwm--id - :value-mask (eval-when-compile - (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y - xcb:ConfigWindow:Width - xcb:ConfigWindow:Height)) - :x 0 :y 0 - :width (frame-pixel-width exwm-workspace--current) - :height (frame-pixel-height exwm-workspace--current))) + (exwm-layout--resize-container exwm--id exwm--container 0 0 + (frame-pixel-width exwm-workspace--current) + (frame-pixel-height + exwm-workspace--current)) (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_WM_STATE :window exwm--id @@ -162,17 +174,12 @@ (when exwm--floating-frame (xcb:+request exwm--connection (make-instance 'xcb:ConfigureWindow - :window (frame-parameter exwm--floating-frame - 'exwm-outer-id) + :window exwm--container :value-mask (eval-when-compile (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y - xcb:ConfigWindow:Width - xcb:ConfigWindow:Height)) - :x (elt exwm--floating-frame-geometry 0) - :y (elt exwm--floating-frame-geometry 1) - :width (elt exwm--floating-frame-geometry 2) - :height (elt exwm--floating-frame-geometry 3)))) + xcb:ConfigWindow:Y)) + :x (elt exwm--floating-frame-position 0) + :y (elt exwm--floating-frame-position 1)))) (exwm-layout--show exwm--id) (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_WM_STATE :window exwm--id :data [])) @@ -193,19 +200,10 @@ (make-instance 'xcb:RECTANGLE :x 0 :y 0 :width (x-display-pixel-width) :height (x-display-pixel-height)))) - (id (frame-parameter frame 'exwm-outer-id))) + (id (frame-parameter frame 'exwm-outer-id)) + (workspace (frame-parameter frame 'exwm-workspace))) (with-slots (x y width height) geometry - (xcb:+request exwm--connection - (make-instance 'xcb:ConfigureWindow - :window id - :value-mask (eval-when-compile - (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y - xcb:ConfigWindow:Width - xcb:ConfigWindow:Height)) - :x x :y y - :width width - :height height)) + (exwm-layout--resize-container id workspace x y width height) (xcb:flush exwm--connection)))) (defvar exwm-layout-show-all-buffers nil @@ -221,7 +219,7 @@ (get-buffer "*scratch*")))) windows) (if (not (memq frame exwm-workspace--list)) - (if (frame-parameter frame 'exwm-window-id) + (if (frame-parameter frame 'exwm-outer-id) ;; Refresh a floating frame (when (eq major-mode 'exwm-mode) (let ((window (frame-first-window frame))) @@ -230,9 +228,6 @@ (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) @@ -329,7 +324,6 @@ windows." (setq width (max (+ exwm--normal-hints-min-width margin) (+ width delta)))))) (when width - (setq exwm--floating-edges nil) ;invalid from now on (xcb:+request exwm--connection (make-instance 'xcb:ConfigureWindow :window (frame-parameter exwm--floating-frame @@ -356,7 +350,6 @@ windows." (setq height (max (+ exwm--normal-hints-min-height margin) (+ height delta)))))) (when height - (setq exwm--floating-edges nil) ;invalid from now on (xcb:+request exwm--connection (make-instance 'xcb:ConfigureWindow :window (frame-parameter exwm--floating-frame |