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

@ -47,8 +47,8 @@
([?\s-w] . exwm-workspace-switch)
;; 's-&': Launch application.
([?\s-&] . (lambda (command)
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
(interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command)))
;; 's-N': Switch to certain workspace.
,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" i)) .

View file

@ -168,8 +168,8 @@ The action is to call FUNCTION with arguments ARGS. If Emacs is not idle,
defer the action until Emacs is idle. Otherwise, defer the action until at
least SECS seconds later."
`(run-with-idle-timer (+ (float-time (or (current-idle-time)
(seconds-to-time (- ,secs))))
,secs)
(seconds-to-time (- ,secs))))
,secs)
nil
,function
,@args))

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,42 +331,37 @@ 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)))
(xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ReparentWindow
:window exwm-systemtray--embedder-window
:parent (string-to-number
(frame-parameter exwm-workspace--current
'window-id))
:x 0
: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--update-offsets)
(xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ReparentWindow
:window exwm-systemtray--embedder-window
:parent (string-to-number
(frame-parameter exwm-workspace--current
'window-id))
:x 0
:y (- (elt (elt exwm-workspace--workareas
exwm-workspace-current-index)
3)
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)))
(xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ConfigureWindow
:window exwm-systemtray--embedder-window
:value-mask xcb:ConfigWindow:Y
: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--update-offsets)
(xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ConfigureWindow
:window exwm-systemtray--embedder-window
:value-mask xcb:ConfigWindow:Y
:y (- (elt (elt exwm-workspace--workareas
exwm-workspace-current-index)
3)
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)))
(setq frame exwm-workspace--current
;; Bottom aligned.
y (- (aref workarea 3) exwm-systemtray-height))))
(exwm-workspace--update-offsets)
(setq frame exwm-workspace--current
;; Bottom aligned.
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)