From b50a6e6dd9f5a34e91fd544e3ead0c81a7217777 Mon Sep 17 00:00:00 2001 From: Chris Feng Date: Wed, 26 Aug 2015 17:25:21 +0800 Subject: [PATCH] Correct several EWMH properties The following EWMH properties on the root window are corrected in this commit: _NET_VIRTUAL_ROOTS, _NET_WORKAREA and _NET_DESKTOP_VIEWPORT. --- exwm-floating.el | 8 ++++++-- exwm-layout.el | 33 +++++++++++++++--------------- exwm-randr.el | 51 +++++++++++++++++++++++++---------------------- exwm-workspace.el | 8 ++++++++ exwm.el | 10 +--------- 5 files changed, 58 insertions(+), 52 deletions(-) diff --git a/exwm-floating.el b/exwm-floating.el index bc6b1a2..8c2a8f4 100644 --- a/exwm-floating.el +++ b/exwm-floating.el @@ -381,9 +381,13 @@ "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)) + (geometry (frame-parameter exwm-workspace--current 'exwm-geometry)) + (frame-x 0) + (frame-y 0) result) + (when geometry + (setq frame-x (slot-value geometry 'x) + frame-y (slot-value geometry 'y))) (xcb:unmarshal obj data) (setq result (funcall exwm-floating--moveresize-calculate (slot-value obj 'root-x) (slot-value obj 'root-y))) diff --git a/exwm-layout.el b/exwm-layout.el index 735b156..fe1645f 100644 --- a/exwm-layout.el +++ b/exwm-layout.el @@ -167,28 +167,27 @@ ;; frame to the actual monitor size, `exwm-layout-set-fullscreen' resizes an X ;; window to the frame size. (defun exwm-layout--set-frame-fullscreen (frame) - "Make frame FRAME fullscreen, with regard to its XRandR output if applicable." + "Make frame FRAME fullscreen, with regard to its RandR output if applicable." (let ((geometry (or (frame-parameter frame 'exwm-geometry) - (xcb:+request-unchecked+reply - exwm--connection + (xcb:+request-unchecked+reply exwm--connection (make-instance 'xcb:GetGeometry :drawable exwm--root)) (make-instance 'xcb:RECTANGLE :x 0 :y 0 - :width (x-display-width) - :height (x-display-height)))) - (id (frame-parameter frame 'exwm-outer-id))) + :width (x-display-pixel-width) + :height (x-display-pixel-height)))) + (id (frame-parameter frame 'exwm-outer-id))) (with-slots (x y width height) geometry - (xcb:+request exwm--connection - (make-instance 'xcb:ConfigureWindow - :window id - :value-mask (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y - xcb:ConfigWindow:Width - xcb:ConfigWindow:Height) - :x x :y y - :width width - :height height)) - (xcb:flush exwm--connection)))) + (xcb:+request exwm--connection + (make-instance 'xcb:ConfigureWindow + :window id + :value-mask (logior xcb:ConfigWindow:X + xcb:ConfigWindow:Y + xcb:ConfigWindow:Width + xcb:ConfigWindow:Height) + :x x :y y + :width width + :height height)) + (xcb:flush exwm--connection)))) (defun exwm-layout--refresh () "Refresh layout." diff --git a/exwm-randr.el b/exwm-randr.el index 6bddb00..57ad569 100644 --- a/exwm-randr.el +++ b/exwm-randr.el @@ -36,9 +36,6 @@ ;; With above lines, workspace 0 should be assigned to the output named "VGA1", ;; staying at the left of other workspaces on the output "LVDS1". -;; Todo: -;; + Update EWMH hints. - ;; References: ;; + RandR (http://www.x.org/archive/X11R7.7/doc/randrproto/randrproto.txt) @@ -50,7 +47,7 @@ (defun exwm-randr--refresh () "Refresh workspaces according to the updated RandR info." - (let (output-plist default-geometry) + (let (geometry output-plist default-geometry workareas viewports) ;; Query all outputs (with-slots (config-timestamp outputs) (xcb:+request-unchecked+reply exwm--connection @@ -72,10 +69,12 @@ (make-instance 'xcb:randr:GetCrtcInfo :crtc crtc :config-timestamp config-timestamp)) - (setq output-plist (plist-put output-plist name - (vector x y width height))) + (setq geometry (make-instance 'xcb:RECTANGLE + :x x :y y + :width width :height height) + output-plist (plist-put output-plist name geometry)) (unless default-geometry ;assume the first output as primary - (setq default-geometry (vector x y width height)))))))) + (setq default-geometry geometry))))))) (cl-assert (<= 2 (length output-plist))) (dotimes (i exwm-workspace-number) (let* ((output (plist-get exwm-randr-workspace-output-plist i)) @@ -85,23 +84,27 @@ (setq geometry default-geometry output nil)) (set-frame-parameter frame 'exwm-randr-output output) - (set-frame-parameter frame 'exwm-geometry - (make-instance 'xcb:RECTANGLE - :x (elt geometry 0) - :y (elt geometry 1) - :width (elt geometry 2) - :height (elt geometry 3))) - (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) - :value-mask (logior xcb:ConfigWindow:X - xcb:ConfigWindow:Y - xcb:ConfigWindow:Width - xcb:ConfigWindow:Height) - :x (elt geometry 0) :y (elt geometry 1) - :width (elt geometry 2) :height (elt geometry 3))))) + (set-frame-parameter frame 'exwm-geometry geometry) + (with-slots (x y width height) geometry + (xcb:+request exwm--connection + (make-instance 'xcb:ConfigureWindow + :window (frame-parameter frame 'exwm-outer-id) + :value-mask (logior xcb:ConfigWindow:X + xcb:ConfigWindow:Y + xcb:ConfigWindow:Width + xcb:ConfigWindow:Height) + :x x :y y :width width :height height)) + (setq workareas (nconc workareas (list x y width height)) + viewports (nconc viewports (list x y)))))) + ;; Update _NET_WORKAREA + (xcb:+request exwm--connection + (make-instance 'xcb:ewmh:set-_NET_WORKAREA + :window exwm--root :data (vconcat workareas))) + ;; Update _NET_DESKTOP_VIEWPORT + (xcb:+request exwm--connection + (make-instance 'xcb:ewmh:set-_NET_DESKTOP_VIEWPORT + :window exwm--root + :data (vconcat viewports))) (xcb:flush exwm--connection))) (defun exwm-randr--init () diff --git a/exwm-workspace.el b/exwm-workspace.el index 8e3839f..cf8caa8 100644 --- a/exwm-workspace.el +++ b/exwm-workspace.el @@ -264,6 +264,14 @@ The optional FORCE option is for internal use only." (raise-frame (car exwm-workspace--list)) ;; Handle unexpected frame switch (add-hook 'focus-in-hook 'exwm-workspace--on-focus-in) + ;; Set _NET_VIRTUAL_ROOTS + (xcb:+request exwm--connection + (make-instance 'xcb:ewmh:set-_NET_VIRTUAL_ROOTS + :window exwm--root + :data (vconcat (mapcar + (lambda (i) + (frame-parameter i 'exwm-window-id)) + exwm-workspace--list)))) ;; Switch to the first workspace (exwm-workspace-switch 0 t)) diff --git a/exwm.el b/exwm.el index a52e114..3b2705a 100644 --- a/exwm.el +++ b/exwm.el @@ -579,20 +579,12 @@ :data (make-vector (* 2 exwm-workspace-number) 0))) ;; Set _NET_WORKAREA (with minibuffer and bottom mode-line excluded) (let* ((workareas - (vconcat (window-absolute-pixel-edges (get-largest-window t)))) + (vector 0 0 (x-display-pixel-width) (x-display-pixel-height))) (workareas (mapconcat (lambda (i) workareas) (make-list exwm-workspace-number 0) []))) (xcb:+request exwm--connection (make-instance 'xcb:ewmh:set-_NET_WORKAREA :window exwm--root :data workareas))) - ;; Set _NET_VIRTUAL_ROOTS - (xcb:+request exwm--connection - (make-instance 'xcb:ewmh:set-_NET_VIRTUAL_ROOTS - :window exwm--root - :data (vconcat (mapcar - (lambda (i) - (frame-parameter i 'exwm-window-id)) - exwm-workspace--list)))) (xcb:flush exwm--connection)) (defvar exwm-init-hook nil