Replace `frame-geometry'

* exwm-workspace.el (exwm-workspace--frame-y-offset)
exwm-workspace--window-y-offset, exwm-workspace--update-offsets): New
variables & function for the calculation of Emacs frame offsets, as
`frame-geometry' is not available in Emacs 24.
* exwm-floating.el (exwm-floating--set-floating)
(exwm-floating--do-moveresize):
* exwm-layout.el (exwm-layout--show):
* exwm-systemtray.el (exwm-systemtray--on-workspace-switch)
(exwm-systemtray--on-randr-refresh, exwm-systemtray--init): Use them.

* exwm-systemtray.el (exwm-systemtray--refresh-all): Renamed from
`exwm-systemtray--on-randr-refresh'.
(exwm-systemtray--init, exwm-systemtray--exit): Use it.

* exwm-floating.el (exwm-floating--stop-moveresize): Send a
ConfigureNotify event to floating frame to update its position (seems
required by Emacs 24).
This commit is contained in:
Chris Feng 2019-09-14 00:00:00 +00:00
parent eb49e57f76
commit f167bc979c
6 changed files with 122 additions and 66 deletions

View file

@ -124,12 +124,15 @@ This is also used by X window containers.")
"Calculate move/resize parameters [buffer event-mask x y width height].")
(defvar exwm-workspace--current)
(defvar exwm-workspace--frame-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--iconic-state-p "exwm-layout.el" (&optional id))
(declare-function exwm-layout--refresh "exwm-layout.el" ())
(declare-function exwm-layout--show "exwm-layout.el" (id &optional window))
(declare-function exwm-workspace--position "exwm-workspace.el" (frame))
(declare-function exwm-workspace--update-offsets "exwm-workspace.el" ())
(defun exwm-floating--set-allowed-actions (id tilling)
"Set _NET_WM_ALLOWED_ACTIONS."
@ -166,8 +169,8 @@ This is also used by X window containers.")
(get-buffer "*scratch*")))
(make-frame
`((minibuffer . ,(minibuffer-window exwm--frame))
(left . ,(* window-min-width -100))
(top . ,(* window-min-height -100))
(left . ,(* window-min-width -10000))
(top . ,(* window-min-height -10000))
(width . ,window-min-width)
(height . ,window-min-height)
(unsplittable . t))))) ;and fix the size later
@ -179,6 +182,9 @@ This is also used by X window containers.")
(y (slot-value exwm--geometry 'y))
(width (slot-value exwm--geometry 'width))
(height (slot-value exwm--geometry 'height)))
;; Force drawing menu-bar & tool-bar.
(redisplay t)
(exwm-workspace--update-offsets)
(exwm--log "Floating geometry (original): %dx%d%+d%+d" width height x y)
;; Save frame parameters.
(set-frame-parameter frame 'exwm-outer-id outer-id)
@ -261,14 +267,12 @@ This is also used by X window containers.")
;; The frame will be made visible by `select-frame-set-input-focus'.
(make-frame-invisible frame)
(let* ((edges (window-inside-pixel-edges window))
(geometry (frame-geometry frame))
(frame-width (+ width (- (frame-pixel-width frame)
(- (elt edges 2) (elt edges 0)))))
(frame-height (+ height (- (frame-pixel-height frame)
(- (elt edges 3) (elt edges 1)))
;; Use `frame-outer-height' in the future.
(or (cddr (assq 'menu-bar-size geometry)) 0)
(or (cddr (assq 'tool-bar-size geometry)) 0)))
exwm-workspace--frame-y-offset))
(floating-mode-line (plist-get exwm--configurations
'floating-mode-line))
(floating-header-line (plist-get exwm--configurations
@ -293,7 +297,7 @@ This is also used by X window containers.")
'floating-header-line))
exwm--mwm-hints-decorations)
(setq header-line-format nil)
;; The header-line need to be hidden in floating header.
;; The header-line need to be hidden in floating mode.
(setq frame-height (- frame-height (window-header-line-height
(frame-root-window frame)))
header-line-format nil)))
@ -304,8 +308,8 @@ This is also used by X window containers.")
:depth 0
:wid frame-container
:parent exwm--root
:x (- x (elt edges 0))
:y (- y (elt edges 1))
:x x
:y (- y exwm-workspace--window-y-offset)
:width width
:height height
:border-width
@ -377,7 +381,7 @@ This is also used by X window containers.")
(with-current-buffer (exwm--id->buffer id)
(run-hooks 'exwm-floating-setup-hook))
;; Redraw the frame.
(redisplay))
(redisplay t))
(defun exwm-floating--unset-floating (id)
"Make window ID non-floating."
@ -644,11 +648,38 @@ This is also used by X window containers.")
(xcb:+request exwm--connection
(make-instance 'xcb:UngrabPointer :time xcb:Time:CurrentTime))
(when exwm-floating--moveresize-calculate
(let (result buffer-or-id)
(let (result buffer-or-id outer-id container-id)
(setq result (funcall exwm-floating--moveresize-calculate 0 0)
buffer-or-id (aref result 0))
(when (bufferp buffer-or-id)
(with-current-buffer buffer-or-id
(setq outer-id (frame-parameter exwm--floating-frame 'exwm-outer-id)
container-id (frame-parameter exwm--floating-frame
'exwm-container))
(with-slots (x y width height border-width)
(xcb:+request-unchecked+reply exwm--connection
(make-instance 'xcb:GetGeometry
:drawable container-id))
;; Notify Emacs frame about this the position change.
(xcb:+request exwm--connection
(make-instance 'xcb:SendEvent
:propagate 0
:destination outer-id
:event-mask xcb:EventMask:StructureNotify
:event
(xcb:marshal
(make-instance 'xcb:ConfigureNotify
:event outer-id
:window outer-id
:above-sibling xcb:Window:None
:x (+ x border-width)
:y (+ y border-width)
:width width
:height height
:border-width 0
:override-redirect 0)
exwm--connection)))
(xcb:flush exwm--connection))
(exwm-layout--show exwm--id
(frame-root-window exwm--floating-frame)))))
(setq exwm-floating--moveresize-calculate nil)))
@ -657,8 +688,7 @@ This is also used by X window containers.")
"Perform move/resize."
(when exwm-floating--moveresize-calculate
(let* ((obj (make-instance 'xcb:MotionNotify))
result value-mask x y width height buffer-or-id container-or-id
geometry y-offset)
result value-mask x y width height buffer-or-id container-or-id)
(xcb:unmarshal obj data)
(setq result (funcall exwm-floating--moveresize-calculate
(slot-value obj 'root-x) (slot-value obj 'root-y))
@ -675,12 +705,11 @@ This is also used by X window containers.")
(setq container-or-id
(with-current-buffer buffer-or-id
(frame-parameter exwm--floating-frame 'exwm-container))
geometry (frame-geometry exwm--floating-frame)
x (- x exwm-floating-border-width)
;; Use `frame-outer-height' in the future.
y-offset (+ (or (cddr (assq 'menu-bar-size geometry)) 0)
(or (cddr (assq 'tool-bar-size geometry)) 0))
y (- y y-offset)
height (+ height y-offset)))
y (- y exwm-floating-border-width
exwm-workspace--window-y-offset)
height (+ height exwm-workspace--window-y-offset)))
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window container-or-id

View file

@ -52,6 +52,7 @@
(defvar exwm-layout--timer nil "Timer used to track echo area changes.")
(defvar exwm-workspace--current)
(defvar exwm-workspace--frame-y-offset)
(declare-function exwm-input--release-keyboard "exwm-input.el")
(declare-function exwm-input--grab-keyboard "exwm-input.el")
(declare-function exwm-input-grab-keyboard "exwm-input.el")
@ -105,15 +106,13 @@
(y (pop edges))
(width (- (pop edges) x))
(height (- (pop edges) y))
geometry frame-x frame-y frame-width frame-height)
frame-x frame-y frame-width frame-height)
(with-current-buffer (exwm--id->buffer id)
(when exwm--floating-frame
(setq frame-width (frame-pixel-width exwm--floating-frame)
geometry (frame-geometry exwm--floating-frame)
frame-height (+ (frame-pixel-height exwm--floating-frame)
;; Use `frame-outer-height' in the future.
(or (cddr (assq 'menu-bar-size geometry)) 0)
(or (cddr (assq 'tool-bar-size geometry)) 0)))
exwm-workspace--frame-y-offset))
(when exwm--floating-frame-position
(setq frame-x (elt exwm--floating-frame-position 0)
frame-y (elt exwm--floating-frame-position 1)

View file

@ -331,7 +331,7 @@ You shall use the default value if using auto-hide minibuffer."
"Reparent/Refresh the system tray in `exwm-workspace-switch-hook'."
(exwm--log)
(unless (exwm-workspace--minibuffer-own-frame-p)
(let ((geometry (frame-geometry exwm-workspace--current)))
(exwm-workspace--update-offsets)
(xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ReparentWindow
:window exwm-systemtray--embedder-window
@ -342,16 +342,15 @@ You shall use the default value if using auto-hide minibuffer."
:y (- (elt (elt exwm-workspace--workareas
exwm-workspace-current-index)
3)
(or (cddr (assq 'menu-bar-size geometry)) 0)
(or (cddr (assq 'tool-bar-size geometry)) 0)
exwm-systemtray-height)))))
exwm-workspace--frame-y-offset
exwm-systemtray-height))))
(exwm-systemtray--refresh))
(defun exwm-systemtray--on-randr-refresh ()
"Reposition/Refresh the system tray in `exwm-randr-refresh-hook'."
(defun exwm-systemtray--refresh-all ()
"Reposition/Refresh the system tray."
(exwm--log)
(unless (exwm-workspace--minibuffer-own-frame-p)
(let ((geometry (frame-geometry exwm-workspace--current)))
(exwm-workspace--update-offsets)
(xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ConfigureWindow
:window exwm-systemtray--embedder-window
@ -359,14 +358,10 @@ You shall use the default value if using auto-hide minibuffer."
:y (- (elt (elt exwm-workspace--workareas
exwm-workspace-current-index)
3)
(or (cddr (assq 'menu-bar-size geometry)) 0)
(or (cddr (assq 'tool-bar-size geometry)) 0)
exwm-systemtray-height)))))
exwm-workspace--frame-y-offset
exwm-systemtray-height))))
(exwm-systemtray--refresh))
(defalias 'exwm-systemtray--on-struts-update
#'exwm-systemtray--on-randr-refresh)
(cl-defun exwm-systemtray--init ()
"Initialize system tray module."
(exwm--log)
@ -452,11 +447,14 @@ You shall use the default value if using auto-hide minibuffer."
(- (line-pixel-height) exwm-systemtray-height)
;; Vertically centered.
(/ (- (line-pixel-height) exwm-systemtray-height) 2)))
(let ((workarea (elt exwm-workspace--workareas
exwm-workspace-current-index)))
(exwm-workspace--update-offsets)
(setq frame exwm-workspace--current
;; Bottom aligned.
y (- (aref workarea 3) exwm-systemtray-height))))
y (- (elt (elt exwm-workspace--workareas
exwm-workspace-current-index)
3)
exwm-workspace--frame-y-offset
exwm-systemtray-height)))
(setq parent (string-to-number (frame-parameter frame 'window-id))
depth (slot-value (xcb:+request-unchecked+reply
exwm-systemtray--connection
@ -501,12 +499,14 @@ You shall use the default value if using auto-hide minibuffer."
;; Add hook to move/reparent the embedder.
(add-hook 'exwm-workspace-switch-hook #'exwm-systemtray--on-workspace-switch)
(add-hook 'exwm-workspace--update-workareas-hook
#'exwm-systemtray--on-struts-update)
#'exwm-systemtray--refresh-all)
(add-hook 'menu-bar-mode-hook #'exwm-systemtray--refresh-all)
(add-hook 'tool-bar-mode-hook #'exwm-systemtray--refresh-all)
(when (boundp 'exwm-randr-refresh-hook)
(add-hook 'exwm-randr-refresh-hook #'exwm-systemtray--on-randr-refresh))
(add-hook 'exwm-randr-refresh-hook #'exwm-systemtray--refresh-all))
;; The struts can be updated already.
(when exwm-workspace--workareas
(exwm-systemtray--on-struts-update)))
(exwm-systemtray--refresh-all)))
(defun exwm-systemtray--exit ()
"Exit the systemtray module."
@ -532,10 +532,11 @@ You shall use the default value if using auto-hide minibuffer."
(remove-hook 'exwm-workspace-switch-hook
#'exwm-systemtray--on-workspace-switch)
(remove-hook 'exwm-workspace--update-workareas-hook
#'exwm-systemtray--on-struts-update)
#'exwm-systemtray--refresh-all)
(remove-hook 'menu-bar-mode-hook #'exwm-systemtray--refresh-all)
(remove-hook 'tool-bar-mode-hook #'exwm-systemtray--refresh-all)
(when (boundp 'exwm-randr-refresh-hook)
(remove-hook 'exwm-randr-refresh-hook
#'exwm-systemtray--on-randr-refresh))))
(remove-hook 'exwm-randr-refresh-hook #'exwm-systemtray--refresh-all))))
(defun exwm-systemtray-enable ()
"Enable system tray support for EXWM."

View file

@ -134,6 +134,11 @@ Please manually run the hook `exwm-workspace-list-change-hook' afterwards.")
(defvar exwm-workspace--workareas nil "Workareas (struts excluded).")
(defvar exwm-workspace--frame-y-offset 0
"Offset between Emacs inner & outer frame in Y.")
(defvar exwm-workspace--window-y-offset 0
"Offset between Emacs first window & outer frame in Y.")
(defvar exwm-input--during-command)
(defvar exwm-input--event-hook)
(defvar exwm-layout-show-all-buffers)
@ -397,6 +402,28 @@ NIL if FRAME is not a workspace"
(exwm--log "%s" exwm-workspace--workareas)
(run-hooks 'exwm-workspace--update-workareas-hook))
(defun exwm-workspace--update-offsets ()
"Update `exwm-workspace--frame-y-offset'/`exwm-workspace--window-y-offset'."
(exwm--log)
(if (not (and exwm-workspace--list
(or menu-bar-mode tool-bar-mode)))
(setq exwm-workspace--frame-y-offset 0
exwm-workspace--window-y-offset 0)
(redisplay t)
(let* ((frame (elt exwm-workspace--list 0))
(edges (window-inside-absolute-pixel-edges (frame-first-window
frame))))
(with-slots (y)
(xcb:+request-unchecked+reply exwm--connection
(make-instance 'xcb:GetGeometry
:drawable (frame-parameter frame 'exwm-outer-id)))
(with-slots ((y* y))
(xcb:+request-unchecked+reply exwm--connection
(make-instance 'xcb:GetGeometry
:drawable (frame-parameter frame 'exwm-id)))
(setq exwm-workspace--frame-y-offset (- y* y)
exwm-workspace--window-y-offset (- (elt edges 1) y)))))))
(defun exwm-workspace--set-active (frame active)
"Make frame FRAME active on its monitor."
(exwm--log "active=%s; frame=%s" frame active)