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-w] . exwm-workspace-switch)
;; 's-&': Launch application. ;; 's-&': Launch application.
([?\s-&] . (lambda (command) ([?\s-&] . (lambda (command)
(interactive (list (read-shell-command "$ "))) (interactive (list (read-shell-command "$ ")))
(start-process-shell-command command nil command))) (start-process-shell-command command nil command)))
;; 's-N': Switch to certain workspace. ;; 's-N': Switch to certain workspace.
,@(mapcar (lambda (i) ,@(mapcar (lambda (i)
`(,(kbd (format "s-%d" 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 defer the action until Emacs is idle. Otherwise, defer the action until at
least SECS seconds later." least SECS seconds later."
`(run-with-idle-timer (+ (float-time (or (current-idle-time) `(run-with-idle-timer (+ (float-time (or (current-idle-time)
(seconds-to-time (- ,secs)))) (seconds-to-time (- ,secs))))
,secs) ,secs)
nil nil
,function ,function
,@args)) ,@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].") "Calculate move/resize parameters [buffer event-mask x y width height].")
(defvar exwm-workspace--current) (defvar exwm-workspace--current)
(defvar exwm-workspace--frame-y-offset)
(defvar exwm-workspace--window-y-offset)
(defvar exwm-workspace--workareas) (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" ())
(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."
@ -166,8 +169,8 @@ This is also used by X window containers.")
(get-buffer "*scratch*"))) (get-buffer "*scratch*")))
(make-frame (make-frame
`((minibuffer . ,(minibuffer-window exwm--frame)) `((minibuffer . ,(minibuffer-window exwm--frame))
(left . ,(* window-min-width -100)) (left . ,(* window-min-width -10000))
(top . ,(* window-min-height -100)) (top . ,(* window-min-height -10000))
(width . ,window-min-width) (width . ,window-min-width)
(height . ,window-min-height) (height . ,window-min-height)
(unsplittable . t))))) ;and fix the size later (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)) (y (slot-value exwm--geometry 'y))
(width (slot-value exwm--geometry 'width)) (width (slot-value exwm--geometry 'width))
(height (slot-value exwm--geometry 'height))) (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) (exwm--log "Floating geometry (original): %dx%d%+d%+d" width height x y)
;; Save frame parameters. ;; Save frame parameters.
(set-frame-parameter frame 'exwm-outer-id outer-id) (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'. ;; The frame will be made visible by `select-frame-set-input-focus'.
(make-frame-invisible frame) (make-frame-invisible frame)
(let* ((edges (window-inside-pixel-edges window)) (let* ((edges (window-inside-pixel-edges window))
(geometry (frame-geometry frame))
(frame-width (+ width (- (frame-pixel-width frame) (frame-width (+ width (- (frame-pixel-width frame)
(- (elt edges 2) (elt edges 0))))) (- (elt edges 2) (elt edges 0)))))
(frame-height (+ height (- (frame-pixel-height frame) (frame-height (+ height (- (frame-pixel-height frame)
(- (elt edges 3) (elt edges 1))) (- (elt edges 3) (elt edges 1)))
;; Use `frame-outer-height' in the future. ;; Use `frame-outer-height' in the future.
(or (cddr (assq 'menu-bar-size geometry)) 0) exwm-workspace--frame-y-offset))
(or (cddr (assq 'tool-bar-size geometry)) 0)))
(floating-mode-line (plist-get exwm--configurations (floating-mode-line (plist-get exwm--configurations
'floating-mode-line)) 'floating-mode-line))
(floating-header-line (plist-get exwm--configurations (floating-header-line (plist-get exwm--configurations
@ -293,7 +297,7 @@ This is also used by X window containers.")
'floating-header-line)) 'floating-header-line))
exwm--mwm-hints-decorations) exwm--mwm-hints-decorations)
(setq header-line-format nil) (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 (setq frame-height (- frame-height (window-header-line-height
(frame-root-window frame))) (frame-root-window frame)))
header-line-format nil))) header-line-format nil)))
@ -304,8 +308,8 @@ This is also used by X window containers.")
:depth 0 :depth 0
:wid frame-container :wid frame-container
:parent exwm--root :parent exwm--root
:x (- x (elt edges 0)) :x x
:y (- y (elt edges 1)) :y (- y exwm-workspace--window-y-offset)
:width width :width width
:height height :height height
:border-width :border-width
@ -377,7 +381,7 @@ This is also used by X window containers.")
(with-current-buffer (exwm--id->buffer id) (with-current-buffer (exwm--id->buffer id)
(run-hooks 'exwm-floating-setup-hook)) (run-hooks 'exwm-floating-setup-hook))
;; Redraw the frame. ;; Redraw the frame.
(redisplay)) (redisplay t))
(defun exwm-floating--unset-floating (id) (defun exwm-floating--unset-floating (id)
"Make window ID non-floating." "Make window ID non-floating."
@ -644,11 +648,38 @@ This is also used by X window containers.")
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:UngrabPointer :time xcb:Time:CurrentTime)) (make-instance 'xcb:UngrabPointer :time xcb:Time:CurrentTime))
(when exwm-floating--moveresize-calculate (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) (setq result (funcall exwm-floating--moveresize-calculate 0 0)
buffer-or-id (aref result 0)) buffer-or-id (aref result 0))
(when (bufferp buffer-or-id) (when (bufferp buffer-or-id)
(with-current-buffer 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 (exwm-layout--show exwm--id
(frame-root-window exwm--floating-frame))))) (frame-root-window exwm--floating-frame)))))
(setq exwm-floating--moveresize-calculate nil))) (setq exwm-floating--moveresize-calculate nil)))
@ -657,8 +688,7 @@ This is also used by X window containers.")
"Perform move/resize." "Perform move/resize."
(when exwm-floating--moveresize-calculate (when exwm-floating--moveresize-calculate
(let* ((obj (make-instance 'xcb:MotionNotify)) (let* ((obj (make-instance 'xcb:MotionNotify))
result value-mask x y width height buffer-or-id container-or-id result value-mask x y width height buffer-or-id container-or-id)
geometry y-offset)
(xcb:unmarshal obj data) (xcb:unmarshal obj data)
(setq result (funcall exwm-floating--moveresize-calculate (setq result (funcall exwm-floating--moveresize-calculate
(slot-value obj 'root-x) (slot-value obj 'root-y)) (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 (setq container-or-id
(with-current-buffer buffer-or-id (with-current-buffer buffer-or-id
(frame-parameter exwm--floating-frame 'exwm-container)) (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. ;; Use `frame-outer-height' in the future.
y-offset (+ (or (cddr (assq 'menu-bar-size geometry)) 0) y (- y exwm-floating-border-width
(or (cddr (assq 'tool-bar-size geometry)) 0)) exwm-workspace--window-y-offset)
y (- y y-offset) height (+ height exwm-workspace--window-y-offset)))
height (+ height y-offset)))
(xcb:+request exwm--connection (xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow (make-instance 'xcb:ConfigureWindow
:window container-or-id :window container-or-id

View file

@ -52,6 +52,7 @@
(defvar exwm-layout--timer nil "Timer used to track echo area changes.") (defvar exwm-layout--timer nil "Timer used to track echo area changes.")
(defvar exwm-workspace--current) (defvar exwm-workspace--current)
(defvar exwm-workspace--frame-y-offset)
(declare-function exwm-input--release-keyboard "exwm-input.el") (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")
(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)) (y (pop edges))
(width (- (pop edges) x)) (width (- (pop edges) x))
(height (- (pop edges) y)) (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) (with-current-buffer (exwm--id->buffer id)
(when exwm--floating-frame (when exwm--floating-frame
(setq frame-width (frame-pixel-width 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) frame-height (+ (frame-pixel-height exwm--floating-frame)
;; Use `frame-outer-height' in the future. ;; Use `frame-outer-height' in the future.
(or (cddr (assq 'menu-bar-size geometry)) 0) exwm-workspace--frame-y-offset))
(or (cddr (assq 'tool-bar-size geometry)) 0)))
(when exwm--floating-frame-position (when exwm--floating-frame-position
(setq frame-x (elt exwm--floating-frame-position 0) (setq frame-x (elt exwm--floating-frame-position 0)
frame-y (elt exwm--floating-frame-position 1) 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'." "Reparent/Refresh the system tray in `exwm-workspace-switch-hook'."
(exwm--log) (exwm--log)
(unless (exwm-workspace--minibuffer-own-frame-p) (unless (exwm-workspace--minibuffer-own-frame-p)
(let ((geometry (frame-geometry exwm-workspace--current))) (exwm-workspace--update-offsets)
(xcb:+request exwm-systemtray--connection (xcb:+request exwm-systemtray--connection
(make-instance 'xcb:ReparentWindow (make-instance 'xcb:ReparentWindow
:window exwm-systemtray--embedder-window :window exwm-systemtray--embedder-window
:parent (string-to-number :parent (string-to-number
(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 (- (elt (elt exwm-workspace--workareas
exwm-workspace-current-index) exwm-workspace-current-index)
3) 3)
(or (cddr (assq 'menu-bar-size geometry)) 0) exwm-workspace--frame-y-offset
(or (cddr (assq 'tool-bar-size geometry)) 0) exwm-systemtray-height))))
exwm-systemtray-height)))))
(exwm-systemtray--refresh)) (exwm-systemtray--refresh))
(defun exwm-systemtray--on-randr-refresh () (defun exwm-systemtray--refresh-all ()
"Reposition/Refresh the system tray in `exwm-randr-refresh-hook'." "Reposition/Refresh the system tray."
(exwm--log) (exwm--log)
(unless (exwm-workspace--minibuffer-own-frame-p) (unless (exwm-workspace--minibuffer-own-frame-p)
(let ((geometry (frame-geometry exwm-workspace--current))) (exwm-workspace--update-offsets)
(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 xcb:ConfigWindow:Y :value-mask xcb:ConfigWindow:Y
:y (- (elt (elt exwm-workspace--workareas :y (- (elt (elt exwm-workspace--workareas
exwm-workspace-current-index) exwm-workspace-current-index)
3) 3)
(or (cddr (assq 'menu-bar-size geometry)) 0) exwm-workspace--frame-y-offset
(or (cddr (assq 'tool-bar-size geometry)) 0) exwm-systemtray-height))))
exwm-systemtray-height)))))
(exwm-systemtray--refresh)) (exwm-systemtray--refresh))
(defalias 'exwm-systemtray--on-struts-update
#'exwm-systemtray--on-randr-refresh)
(cl-defun exwm-systemtray--init () (cl-defun exwm-systemtray--init ()
"Initialize system tray module." "Initialize system tray module."
(exwm--log) (exwm--log)
@ -452,11 +447,14 @@ You shall use the default value if using auto-hide minibuffer."
(- (line-pixel-height) exwm-systemtray-height) (- (line-pixel-height) exwm-systemtray-height)
;; Vertically centered. ;; Vertically centered.
(/ (- (line-pixel-height) exwm-systemtray-height) 2))) (/ (- (line-pixel-height) exwm-systemtray-height) 2)))
(let ((workarea (elt exwm-workspace--workareas (exwm-workspace--update-offsets)
exwm-workspace-current-index))) (setq frame exwm-workspace--current
(setq frame exwm-workspace--current ;; Bottom aligned.
;; Bottom aligned. y (- (elt (elt exwm-workspace--workareas
y (- (aref workarea 3) exwm-systemtray-height)))) exwm-workspace-current-index)
3)
exwm-workspace--frame-y-offset
exwm-systemtray-height)))
(setq parent (string-to-number (frame-parameter frame 'window-id)) (setq parent (string-to-number (frame-parameter frame 'window-id))
depth (slot-value (xcb:+request-unchecked+reply depth (slot-value (xcb:+request-unchecked+reply
exwm-systemtray--connection 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 to move/reparent the embedder.
(add-hook 'exwm-workspace-switch-hook #'exwm-systemtray--on-workspace-switch) (add-hook 'exwm-workspace-switch-hook #'exwm-systemtray--on-workspace-switch)
(add-hook 'exwm-workspace--update-workareas-hook (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) (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. ;; The struts can be updated already.
(when exwm-workspace--workareas (when exwm-workspace--workareas
(exwm-systemtray--on-struts-update))) (exwm-systemtray--refresh-all)))
(defun exwm-systemtray--exit () (defun exwm-systemtray--exit ()
"Exit the systemtray module." "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 (remove-hook 'exwm-workspace-switch-hook
#'exwm-systemtray--on-workspace-switch) #'exwm-systemtray--on-workspace-switch)
(remove-hook 'exwm-workspace--update-workareas-hook (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) (when (boundp 'exwm-randr-refresh-hook)
(remove-hook 'exwm-randr-refresh-hook (remove-hook 'exwm-randr-refresh-hook #'exwm-systemtray--refresh-all))))
#'exwm-systemtray--on-randr-refresh))))
(defun exwm-systemtray-enable () (defun exwm-systemtray-enable ()
"Enable system tray support for EXWM." "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--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--during-command)
(defvar exwm-input--event-hook) (defvar exwm-input--event-hook)
(defvar exwm-layout-show-all-buffers) (defvar exwm-layout-show-all-buffers)
@ -397,6 +402,28 @@ NIL if FRAME is not a workspace"
(exwm--log "%s" exwm-workspace--workareas) (exwm--log "%s" exwm-workspace--workareas)
(run-hooks 'exwm-workspace--update-workareas-hook)) (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) (defun exwm-workspace--set-active (frame active)
"Make frame FRAME active on its monitor." "Make frame FRAME active on its monitor."
(exwm--log "active=%s; frame=%s" frame active) (exwm--log "active=%s; frame=%s" frame active)