Convert exwm-workspace--workareas' to a list of xcb:RECTANGLE's

* exwm-workspace.el (exwm-workspace--set-fullscreen)
(exwm-workspace--resize-minibuffer-frame)
(exwm-workspace--on-ConfigureNotify):
* exwm-floating.el (exwm-floating--set-floating):
* exwm-manage.el (exwm-manage--manage-window):
* exwm-systemtray.el (exwm-systemtray--refresh)
(exwm-systemtray--on-workspace-switch)
(exwm-systemtray--refresh-all, exwm-systemtray--init):
Adjust to `xcb:RECTANGLE'
workarea.
This commit is contained in:
Adrián Medraño Calvo 2023-06-09 00:00:00 +00:00
parent 4970d6ad4e
commit 67c5b316be
4 changed files with 114 additions and 118 deletions

View file

@ -118,13 +118,13 @@ context of the corresponding buffer."
(defvar exwm-workspace--current) (defvar exwm-workspace--current)
(defvar exwm-workspace--frame-y-offset) (defvar exwm-workspace--frame-y-offset)
(defvar exwm-workspace--window-y-offset) (defvar exwm-workspace--window-y-offset)
(defvar exwm-workspace--workareas)
(declare-function exwm-layout--hide "exwm-layout.el" (id)) (declare-function exwm-layout--hide "exwm-layout.el" (id))
(declare-function exwm-layout--iconic-state-p "exwm-layout.el" (&optional id)) (declare-function exwm-layout--iconic-state-p "exwm-layout.el" (&optional id))
(declare-function exwm-layout--refresh "exwm-layout.el" ()) (declare-function exwm-layout--refresh "exwm-layout.el" ())
(declare-function exwm-layout--show "exwm-layout.el" (id &optional window)) (declare-function exwm-layout--show "exwm-layout.el" (id &optional window))
(declare-function exwm-workspace--position "exwm-workspace.el" (frame)) (declare-function exwm-workspace--position "exwm-workspace.el" (frame))
(declare-function exwm-workspace--update-offsets "exwm-workspace.el" ()) (declare-function exwm-workspace--update-offsets "exwm-workspace.el" ())
(declare-function exwm-workspace--workarea "exwm-workspace.el" (frame))
(defun exwm-floating--set-allowed-actions (id tilling) (defun exwm-floating--set-allowed-actions (id tilling)
"Set _NET_WM_ALLOWED_ACTIONS." "Set _NET_WM_ALLOWED_ACTIONS."
@ -186,12 +186,8 @@ context of the corresponding buffer."
(set-frame-parameter frame 'exwm-container frame-container) (set-frame-parameter frame 'exwm-container frame-container)
;; Fix illegal parameters ;; Fix illegal parameters
;; FIXME: check normal hints restrictions ;; FIXME: check normal hints restrictions
(let* ((workarea (elt exwm-workspace--workareas (with-slots ((x* x) (y* y) (width* width) (height* height))
(exwm-workspace--position original-frame))) (exwm-workspace--workarea original-frame)
(x* (aref workarea 0))
(y* (aref workarea 1))
(width* (aref workarea 2))
(height* (aref workarea 3)))
;; Center floating windows ;; Center floating windows
(when (and (or (= x 0) (= x x*)) (when (and (or (= x 0) (= x x*))
(or (= y 0) (= y y*))) (or (= y 0) (= y y*)))

View file

@ -157,7 +157,6 @@ want to match against EXWM internal variables such as `exwm-title',
(defvar exwm-workspace--id-struts-alist) (defvar exwm-workspace--id-struts-alist)
(defvar exwm-workspace--list) (defvar exwm-workspace--list)
(defvar exwm-workspace--switch-history-outdated) (defvar exwm-workspace--switch-history-outdated)
(defvar exwm-workspace--workareas)
(defvar exwm-workspace-current-index) (defvar exwm-workspace-current-index)
(declare-function exwm--update-class "exwm.el" (id &optional force)) (declare-function exwm--update-class "exwm.el" (id &optional force))
(declare-function exwm--update-hints "exwm.el" (id &optional force)) (declare-function exwm--update-hints "exwm.el" (id &optional force))
@ -178,6 +177,7 @@ want to match against EXWM internal variables such as `exwm-title',
(declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame)) (declare-function exwm-workspace--set-fullscreen "exwm-workspace.el" (frame))
(declare-function exwm-workspace--update-struts "exwm-workspace.el" ()) (declare-function exwm-workspace--update-struts "exwm-workspace.el" ())
(declare-function exwm-workspace--update-workareas "exwm-workspace.el" ()) (declare-function exwm-workspace--update-workareas "exwm-workspace.el" ())
(declare-function exwm-workspace--workarea "exwm-workspace.el" (frame))
(defun exwm-manage--update-geometry (id &optional force) (defun exwm-manage--update-geometry (id &optional force)
"Update window geometry." "Update window geometry."
@ -326,12 +326,8 @@ want to match against EXWM internal variables such as `exwm-title',
(with-slots (x y width height) exwm--geometry (with-slots (x y width height) exwm--geometry
;; Center window of type _NET_WM_WINDOW_TYPE_SPLASH ;; Center window of type _NET_WM_WINDOW_TYPE_SPLASH
(when (memq xcb:Atom:_NET_WM_WINDOW_TYPE_SPLASH exwm-window-type) (when (memq xcb:Atom:_NET_WM_WINDOW_TYPE_SPLASH exwm-window-type)
(let* ((workarea (elt exwm-workspace--workareas (with-slots ((x* x) (y* y) (width* width) (height* height))
(exwm-workspace--position exwm--frame))) (exwm-workspace--workarea exwm--frame)
(x* (aref workarea 0))
(y* (aref workarea 1))
(width* (aref workarea 2))
(height* (aref workarea 3)))
(exwm--set-geometry id (exwm--set-geometry id
(+ x* (/ (- width* width) 2)) (+ x* (/ (- width* width) 2))
(+ y* (/ (- height* height) 2)) (+ y* (/ (- height* height) 2))

View file

@ -38,6 +38,8 @@
(require 'exwm-core) (require 'exwm-core)
(require 'exwm-workspace) (require 'exwm-workspace)
(declare-function exwm-workspace--workarea "exwm-workspace.el" (frame))
(defclass exwm-systemtray--icon () (defclass exwm-systemtray--icon ()
((width :initarg :width) ((width :initarg :width)
(height :initarg :height) (height :initarg :height)
@ -240,14 +242,13 @@ using 32-bit depth. Using `workspace-background' instead.")
(setq x (+ x (slot-value (cdr pair) 'width) (setq x (+ x (slot-value (cdr pair) 'width)
exwm-systemtray-icon-gap)) exwm-systemtray-icon-gap))
(setq map t))) (setq map t)))
(let ((workarea (elt exwm-workspace--workareas (let ((workarea (exwm-workspace--workarea exwm-workspace-current-index)))
exwm-workspace-current-index)))
(xcb:+request exwm-systemtray--connection (xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ConfigureWindow (make-instance 'xcb:ConfigureWindow
:window exwm-systemtray--embedder-window :window exwm-systemtray--embedder-window
:value-mask (logior xcb:ConfigWindow:X :value-mask (logior xcb:ConfigWindow:X
xcb:ConfigWindow:Width) xcb:ConfigWindow:Width)
:x (- (aref workarea 2) x) :x (- (slot-value workarea 'width) x)
:width x))) :width x)))
(when map (when map
(xcb:+request exwm-systemtray--connection (xcb:+request exwm-systemtray--connection
@ -450,9 +451,9 @@ indicate how to support actual transparency."
(frame-parameter exwm-workspace--current (frame-parameter exwm-workspace--current
'window-id)) 'window-id))
:x 0 :x 0
:y (- (elt (elt exwm-workspace--workareas :y (- (slot-value (exwm-workspace--workarea
exwm-workspace-current-index) exwm-workspace-current-index)
3) 'height)
exwm-workspace--frame-y-offset exwm-workspace--frame-y-offset
exwm-systemtray-height)))) exwm-systemtray-height))))
(exwm-systemtray--refresh-background-color) (exwm-systemtray--refresh-background-color)
@ -471,9 +472,9 @@ indicate how to support actual transparency."
(make-instance 'xcb:ConfigureWindow (make-instance 'xcb:ConfigureWindow
:window exwm-systemtray--embedder-window :window exwm-systemtray--embedder-window
:value-mask xcb:ConfigWindow:Y :value-mask xcb:ConfigWindow:Y
:y (- (elt (elt exwm-workspace--workareas :y (- (slot-value (exwm-workspace--workarea
exwm-workspace-current-index) exwm-workspace-current-index)
3) 'height)
exwm-workspace--frame-y-offset exwm-workspace--frame-y-offset
exwm-systemtray-height)))) exwm-systemtray-height))))
(exwm-systemtray--refresh)) (exwm-systemtray--refresh))
@ -567,9 +568,9 @@ indicate how to support actual transparency."
(exwm-workspace--update-offsets) (exwm-workspace--update-offsets)
(setq frame exwm-workspace--current (setq frame exwm-workspace--current
;; Bottom aligned. ;; Bottom aligned.
y (- (elt (elt exwm-workspace--workareas y (- (slot-value (exwm-workspace--workarea
exwm-workspace-current-index) exwm-workspace-current-index)
3) 'height)
exwm-workspace--frame-y-offset exwm-workspace--frame-y-offset
exwm-systemtray-height))) exwm-systemtray-height)))
(setq parent (string-to-number (frame-parameter frame 'window-id))) (setq parent (string-to-number (frame-parameter frame 'window-id)))

View file

@ -162,6 +162,15 @@ NIL if FRAME is not a workspace"
"Return t if FRAME is a workspace." "Return t if FRAME is a workspace."
(memq frame exwm-workspace--list)) (memq frame exwm-workspace--list))
(defsubst exwm-workspace--workarea (frame)
"Return workarea corresponding to FRAME.
FRAME may be either a workspace frame or a workspace position."
(declare (indent defun))
(elt exwm-workspace--workareas
(if (integerp frame)
frame
(exwm-workspace--position frame))))
(defvar exwm-workspace--switch-map nil (defvar exwm-workspace--switch-map nil
"Keymap used for interactively selecting workspace.") "Keymap used for interactively selecting workspace.")
@ -331,68 +340,68 @@ NIL if FRAME is not a workspace"
(defun exwm-workspace--update-workareas () (defun exwm-workspace--update-workareas ()
"Update `exwm-workspace--workareas'." "Update `exwm-workspace--workareas'."
(let ((root-width (x-display-pixel-width)) (let* ((root-width (x-display-pixel-width))
(root-height (x-display-pixel-height)) (root-height (x-display-pixel-height))
workareas ;; Get workareas prior to struts.
edge width position (workareas (mapcar (lambda (f)
delta) (or
;; Calculate workareas with no struts. ;; Use the 'exwm-geometry' frame parameter if
(if (frame-parameter (car exwm-workspace--list) 'exwm-geometry) ;; possible.
;; Use the 'exwm-geometry' frame parameter if possible. (frame-parameter f 'exwm-geometry)
(dolist (f exwm-workspace--list) ;; Fall back to use the screen size.
(with-slots (x y width height) (frame-parameter f 'exwm-geometry) (make-instance 'xcb:RECTANGLE
(setq workareas (append workareas :x 0
(list (vector x y width height)))))) :y 0
;; Fall back to use the screen size. :width root-width
(let ((workarea (vector 0 0 root-width root-height))) :height root-height)))
(setq workareas (make-list (exwm-workspace--count) workarea)))) exwm-workspace--list)))
;; Exclude areas occupied by struts. ;; Exclude areas occupied by struts.
(dolist (struts exwm-workspace--struts) (dolist (struts exwm-workspace--struts)
(setq edge (aref struts 0) (let* ((edge (aref struts 0))
width (aref struts 1) (size (aref struts 1))
position (aref struts 2)) (position (aref struts 2))
(dolist (w workareas) (beg (and position (aref position 0)))
(pcase edge (end (and position (aref position 1)))
;; Left and top are always processed first. delta)
(`left (dolist (w workareas)
(setq delta (- (aref w 0) width)) (with-slots (x y width height) w
(when (and (< delta 0) (pcase edge
(or (not position) ;; Left and top are always processed first.
(< (max (aref position 0) (aref w 1)) (`left
(min (aref position 1) (setq delta (- x size))
(+ (aref w 1) (aref w 3)))))) (when (and (< delta 0)
(cl-incf (aref w 2) delta) (or (not position)
(setf (aref w 0) width))) (< (max beg y)
(`right (min end (+ y height)))))
(setq delta (- root-width (aref w 0) (aref w 2) width)) (cl-incf width delta)
(when (and (< delta 0) (setf x size)))
(or (not position) (`right
(< (max (aref position 0) (aref w 1)) (setq delta (- root-width x width size))
(min (aref position 1) (when (and (< delta 0)
(+ (aref w 1) (aref w 3)))))) (or (not position)
(cl-incf (aref w 2) delta))) (< (max beg y)
(`top (min end (+ y height)))))
(setq delta (- (aref w 1) width)) (cl-incf width delta)))
(when (and (< delta 0) (`top
(or (not position) (setq delta (- y size))
(< (max (aref position 0) (aref w 0)) (when (and (< delta 0)
(min (aref position 1) (or (not position)
(+ (aref w 0) (aref w 2))))) (< (max beg x)
(< width (+ (aref w 1) (aref w 3))) (min end (+ x width))))
(> width (aref w 1))) (< size (+ y height))
(cl-incf (aref w 3) delta) (> size y))
(setf (aref w 1) width))) (cl-incf height delta)
(`bottom (setf y size)))
(setq delta (- root-height (aref w 1) (aref w 3) width)) (`bottom
(when (and (< delta 0) (setq delta (- root-height y height size))
(or (not position) (when (and (< delta 0)
(< (max (aref position 0) (aref w 0)) (or (not position)
(min (aref position 1) (< (max beg x)
(+ (aref w 0) (aref w 2))))) (min end (+ x width))))
(< (- root-height width) (< (- root-height size)
(+ (aref w 1) (aref w 3))) (+ y height))
(> (- root-height width) (aref w 1))) (> (- root-height size) y))
(cl-incf (aref w 3) delta)))))) (cl-incf height delta))))))))
;; Save the result. ;; Save the result.
(setq exwm-workspace--workareas workareas) (setq exwm-workspace--workareas workareas)
(xcb:flush exwm--connection)) (xcb:flush exwm--connection))
@ -444,24 +453,19 @@ NIL if FRAME is not a workspace"
(defun exwm-workspace--set-fullscreen (frame) (defun exwm-workspace--set-fullscreen (frame)
"Make frame FRAME fullscreen according to `exwm-workspace--workareas'." "Make frame FRAME fullscreen according to `exwm-workspace--workareas'."
(exwm--log "frame=%s" frame) (exwm--log "frame=%s" frame)
(let ((workarea (elt exwm-workspace--workareas (let ((id (frame-parameter frame 'exwm-outer-id))
(exwm-workspace--position frame))) (container (frame-parameter frame 'exwm-container)))
(id (frame-parameter frame 'exwm-outer-id)) (with-slots (x y width height)
(container (frame-parameter frame 'exwm-container)) (exwm-workspace--workarea frame)
x y width height) (exwm--log "x=%s; y=%s; w=%s; h=%s" x y width height)
(setq x (aref workarea 0) (when (and (eq frame exwm-workspace--current)
y (aref workarea 1) (exwm-workspace--minibuffer-own-frame-p))
width (aref workarea 2) (exwm-workspace--resize-minibuffer-frame))
height (aref workarea 3)) (if (exwm-workspace--active-p frame)
(exwm--log "x=%s; y=%s; w=%s; h=%s" x y width height) (exwm--set-geometry container x y width height)
(when (and (eq frame exwm-workspace--current) (exwm--set-geometry container x y 1 1))
(exwm-workspace--minibuffer-own-frame-p)) (exwm--set-geometry id nil nil width height)
(exwm-workspace--resize-minibuffer-frame)) (xcb:flush exwm--connection)))
(if (exwm-workspace--active-p frame)
(exwm--set-geometry container x y width height)
(exwm--set-geometry container x y 1 1))
(exwm--set-geometry id nil nil width height)
(xcb:flush exwm--connection))
;; This is only used for workspace initialization. ;; This is only used for workspace initialization.
(when exwm-workspace--fullscreen-frame-count (when exwm-workspace--fullscreen-frame-count
(cl-incf exwm-workspace--fullscreen-frame-count))) (cl-incf exwm-workspace--fullscreen-frame-count)))
@ -469,20 +473,20 @@ NIL if FRAME is not a workspace"
(defun exwm-workspace--resize-minibuffer-frame () (defun exwm-workspace--resize-minibuffer-frame ()
"Resize minibuffer (and its container) to fit the size of workspace." "Resize minibuffer (and its container) to fit the size of workspace."
(cl-assert (exwm-workspace--minibuffer-own-frame-p)) (cl-assert (exwm-workspace--minibuffer-own-frame-p))
(let ((workarea (elt exwm-workspace--workareas exwm-workspace-current-index)) (let ((workarea (exwm-workspace--workarea exwm-workspace-current-index))
(container (frame-parameter exwm-workspace--minibuffer (container (frame-parameter exwm-workspace--minibuffer
'exwm-container)) 'exwm-container))
y width) y width)
(setq y (if (eq exwm-workspace-minibuffer-position 'top) (setq y (if (eq exwm-workspace-minibuffer-position 'top)
(- (aref workarea 1) (- (slot-value workarea 'y)
exwm-workspace--attached-minibuffer-height) exwm-workspace--attached-minibuffer-height)
;; Reset the frame size. ;; Reset the frame size.
(set-frame-height exwm-workspace--minibuffer 1) (set-frame-height exwm-workspace--minibuffer 1)
(redisplay) ;FIXME. (redisplay) ;FIXME.
(+ (aref workarea 1) (aref workarea 3) (+ (slot-value workarea 'y) (slot-value workarea 'height)
(- (frame-pixel-height exwm-workspace--minibuffer)) (- (frame-pixel-height exwm-workspace--minibuffer))
exwm-workspace--attached-minibuffer-height)) exwm-workspace--attached-minibuffer-height))
width (aref workarea 2)) width (slot-value workarea 'width))
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow (make-instance 'xcb:ConfigureWindow
:window container :window container
@ -493,7 +497,7 @@ NIL if FRAME is not a workspace"
xcb:ConfigWindow:Sibling xcb:ConfigWindow:Sibling
0) 0)
xcb:ConfigWindow:StackMode) xcb:ConfigWindow:StackMode)
:x (aref workarea 0) :x (slot-value workarea 'x)
:y y :y y
:width width :width width
:sibling exwm-manage--desktop :sibling exwm-manage--desktop
@ -1138,8 +1142,7 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
(defun exwm-workspace--on-ConfigureNotify (data _synthetic) (defun exwm-workspace--on-ConfigureNotify (data _synthetic)
"Adjust the container to fit the minibuffer frame." "Adjust the container to fit the minibuffer frame."
(let ((obj (make-instance 'xcb:ConfigureNotify)) (let ((obj (make-instance 'xcb:ConfigureNotify)) y)
workarea y)
(xcb:unmarshal obj data) (xcb:unmarshal obj data)
(with-slots (window height) obj (with-slots (window height) obj
(when (eq (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id) (when (eq (frame-parameter exwm-workspace--minibuffer 'exwm-outer-id)
@ -1159,13 +1162,13 @@ Please check `exwm-workspace--minibuffer-own-frame-p' first."
(when (/= (exwm-workspace--count) (length exwm-workspace--workareas)) (when (/= (exwm-workspace--count) (length exwm-workspace--workareas))
;; There is a chance the workareas are not updated timely. ;; There is a chance the workareas are not updated timely.
(exwm-workspace--update-workareas)) (exwm-workspace--update-workareas))
(setq workarea (elt exwm-workspace--workareas (with-slots ((y* y) (height* height))
exwm-workspace-current-index) (exwm-workspace--workarea exwm-workspace-current-index)
y (if (eq exwm-workspace-minibuffer-position 'top) (setq y (if (eq exwm-workspace-minibuffer-position 'top)
(- (aref workarea 1) (- y*
exwm-workspace--attached-minibuffer-height) exwm-workspace--attached-minibuffer-height)
(+ (aref workarea 1) (aref workarea 3) (- height) (+ y* height* (- height)
exwm-workspace--attached-minibuffer-height))) exwm-workspace--attached-minibuffer-height))))
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow (make-instance 'xcb:ConfigureWindow
:window (frame-parameter exwm-workspace--minibuffer :window (frame-parameter exwm-workspace--minibuffer