mirror of
https://github.com/ch11ng/exwm.git
synced 2024-11-23 19:47:58 +01:00
Prevent Emacs frames from restacking themselves
Putting Emacs frames (workspace frames, floating frames) into dedicated containers greatly simplifies the stacking order management and totally fixes relevant issues. * exwm-floating.el (exwm-floating--set-floating): Create floating frame container. Remove redundant stacking order modification code. (exwm-floating--unset-floating): Destroy the floating frame container. No need to reparent the X window container. (exwm-floating--do-moveresize): Resize the floating frame container. * exwm-input.el (exwm-input--update-focus): No need to restack frames. * exwm-layout.el (exwm-layout--show, exwm-layout--set-frame-fullscreen) (exwm-layout-enlarge-window): Resize the floating frame container. * exwm-manage.el (exwm-manage--on-ConfigureRequest): Re-enable stacking order modification on ConfigureRequest. * exwm-workspace.el (exwm-workspace--confirm-kill-emacs): Reparent out all frames on exit. No need to remove selected events or created resources. (exwm-workspace--init): Create workspace frame containers. * exwm-layout.el (exwm-layout-set-fullscreen): * exwm-manage.el (exwm-manage--unmanage-window): Remove a redundant call to `xcb:flush'. * exwm-manage.el (exwm-manage--unmanage-window): Force unmap the X window. Unmap the floating frame before reparent it.
This commit is contained in:
parent
1c79e1c238
commit
e3d33a4aad
5 changed files with 192 additions and 121 deletions
105
exwm-floating.el
105
exwm-floating.el
|
@ -90,6 +90,7 @@
|
||||||
(outer-id (string-to-number (frame-parameter frame 'outer-window-id)))
|
(outer-id (string-to-number (frame-parameter frame 'outer-window-id)))
|
||||||
(container (with-current-buffer (exwm--id->buffer id)
|
(container (with-current-buffer (exwm--id->buffer id)
|
||||||
exwm--container))
|
exwm--container))
|
||||||
|
(frame-container (xcb:generate-id exwm--connection))
|
||||||
(window (frame-first-window frame)) ;and it's the only window
|
(window (frame-first-window frame)) ;and it's the only window
|
||||||
(x (slot-value exwm--geometry 'x))
|
(x (slot-value exwm--geometry 'x))
|
||||||
(y (slot-value exwm--geometry 'y))
|
(y (slot-value exwm--geometry 'y))
|
||||||
|
@ -103,8 +104,9 @@
|
||||||
y (- y (slot-value frame-geometry 'y))))
|
y (- y (slot-value frame-geometry 'y))))
|
||||||
(exwm--log "Floating geometry (original, relative): %dx%d%+d%+d"
|
(exwm--log "Floating geometry (original, relative): %dx%d%+d%+d"
|
||||||
width height x y)
|
width height x y)
|
||||||
;; Save window IDs
|
;; Save frame parameters.
|
||||||
(set-frame-parameter frame 'exwm-outer-id outer-id)
|
(set-frame-parameter frame 'exwm-outer-id outer-id)
|
||||||
|
(set-frame-parameter frame 'exwm-container frame-container)
|
||||||
;; Set urgency flag if it's not appear in the active workspace
|
;; Set urgency flag if it's not appear in the active workspace
|
||||||
(let ((idx (cl-position original-frame exwm-workspace--list)))
|
(let ((idx (cl-position original-frame exwm-workspace--list)))
|
||||||
(when (/= idx exwm-workspace-current-index)
|
(when (/= idx exwm-workspace-current-index)
|
||||||
|
@ -163,18 +165,43 @@
|
||||||
;; timely.
|
;; timely.
|
||||||
;; 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))
|
||||||
(set-frame-size frame
|
(frame-width (+ width (- (frame-pixel-width frame)
|
||||||
(+ width (- (frame-pixel-width frame)
|
(- (elt edges 2) (elt edges 0)))))
|
||||||
(- (elt edges 2) (elt edges 0))))
|
(frame-height (+ height (- (frame-pixel-height frame)
|
||||||
(+ height (- (frame-pixel-height frame)
|
(- (elt edges 3) (elt edges 1))))))
|
||||||
(- (elt edges 3) (elt edges 1))))
|
(set-frame-size frame frame-width frame-height t)
|
||||||
t))
|
;; Create the frame container as the parent of the frame and
|
||||||
;; Reparent this frame to the container
|
;; a child of the X window container.
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:CreateWindow
|
||||||
|
:depth 0 :wid frame-container
|
||||||
|
:parent container
|
||||||
|
:x 0 :y 0 :width width :height height :border-width 0
|
||||||
|
:class xcb:WindowClass:CopyFromParent
|
||||||
|
:visual 0 ;CopyFromParent
|
||||||
|
:value-mask xcb:CW:OverrideRedirect
|
||||||
|
:override-redirect 1))
|
||||||
|
;; Put it at bottom.
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ConfigureWindow
|
||||||
|
:window frame-container
|
||||||
|
:value-mask xcb:ConfigWindow:StackMode
|
||||||
|
:stack-mode xcb:StackMode:Below))
|
||||||
|
;; Map it.
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:MapWindow :window frame-container))
|
||||||
|
(exwm--debug
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
||||||
|
:window frame-container
|
||||||
|
:data
|
||||||
|
(format "floating frame container for 0x%x" id)))))
|
||||||
|
;; Reparent this frame to its container.
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
:window outer-id :parent container :x 0 :y 0))
|
:window outer-id :parent frame-container :x 0 :y 0))
|
||||||
;; Place the container
|
;; Place the X window container.
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window container
|
:window container
|
||||||
|
@ -193,16 +220,9 @@
|
||||||
(remove-hook 'window-configuration-change-hook #'exwm-layout--refresh)
|
(remove-hook 'window-configuration-change-hook #'exwm-layout--refresh)
|
||||||
(set-window-buffer window (current-buffer)) ;this changes current buffer
|
(set-window-buffer window (current-buffer)) ;this changes current buffer
|
||||||
(add-hook 'window-configuration-change-hook #'exwm-layout--refresh)
|
(add-hook 'window-configuration-change-hook #'exwm-layout--refresh)
|
||||||
(set-window-dedicated-p window t))
|
(set-window-dedicated-p window t)
|
||||||
(select-frame-set-input-focus frame)
|
|
||||||
;; `x_make_frame_visible' autoraises the frame. Force lowering it.
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:ConfigureWindow
|
|
||||||
:window outer-id
|
|
||||||
:value-mask xcb:ConfigWindow:StackMode
|
|
||||||
:stack-mode xcb:StackMode:Below))
|
|
||||||
;; Show the X window with its container (and flush).
|
|
||||||
(exwm-layout--show id window))
|
(exwm-layout--show id window))
|
||||||
|
(select-frame-set-input-focus frame))
|
||||||
(run-hooks 'exwm-floating-setup-hook)
|
(run-hooks 'exwm-floating-setup-hook)
|
||||||
;; Redraw the frame.
|
;; Redraw the frame.
|
||||||
(redisplay))
|
(redisplay))
|
||||||
|
@ -229,29 +249,28 @@
|
||||||
:window id :value-mask xcb:CW:EventMask
|
:window id :value-mask xcb:CW:EventMask
|
||||||
:event-mask exwm--client-event-mask))
|
:event-mask exwm--client-event-mask))
|
||||||
;; Reparent the floating frame back to the root window.
|
;; Reparent the floating frame back to the root window.
|
||||||
(let ((frame-id (frame-parameter exwm--floating-frame 'exwm-outer-id)))
|
(let ((frame-id (frame-parameter exwm--floating-frame 'exwm-outer-id))
|
||||||
|
(frame-container (frame-parameter exwm--floating-frame
|
||||||
|
'exwm-container)))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:UnmapWindow :window frame-id))
|
(make-instance 'xcb:UnmapWindow :window frame-id))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
:window frame-id
|
:window frame-id
|
||||||
:parent exwm--root
|
:parent exwm--root
|
||||||
:x 0 :y 0))))
|
:x 0 :y 0))
|
||||||
;; Reparent the container to the workspace
|
;; Also destroy its container.
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:DestroyWindow :window frame-container))))
|
||||||
:window exwm--container
|
;; Put the X window container just above the Emacs frame container
|
||||||
:parent (frame-parameter exwm-workspace--current
|
;; (the stacking order won't change from now on).
|
||||||
'exwm-workspace)
|
|
||||||
:x 0 :y 0)) ;temporary position
|
|
||||||
;; Put the container just above the Emacs frame
|
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window exwm--container
|
:window exwm--container
|
||||||
:value-mask (logior xcb:ConfigWindow:Sibling
|
:value-mask (logior xcb:ConfigWindow:Sibling
|
||||||
xcb:ConfigWindow:StackMode)
|
xcb:ConfigWindow:StackMode)
|
||||||
:sibling (frame-parameter exwm-workspace--current
|
:sibling (frame-parameter exwm-workspace--current
|
||||||
'exwm-outer-id)
|
'exwm-container)
|
||||||
:stack-mode xcb:StackMode:Above)))
|
:stack-mode xcb:StackMode:Above)))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
(with-current-buffer buffer
|
(with-current-buffer buffer
|
||||||
|
@ -466,13 +485,19 @@
|
||||||
(geometry (frame-parameter exwm-workspace--current 'exwm-geometry))
|
(geometry (frame-parameter exwm-workspace--current 'exwm-geometry))
|
||||||
(frame-x 0)
|
(frame-x 0)
|
||||||
(frame-y 0)
|
(frame-y 0)
|
||||||
result)
|
result value-mask width height)
|
||||||
(when geometry
|
(when geometry
|
||||||
(setq frame-x (slot-value geometry 'x)
|
(setq frame-x (slot-value geometry 'x)
|
||||||
frame-y (slot-value geometry 'y)))
|
frame-y (slot-value geometry 'y)))
|
||||||
(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))
|
||||||
|
value-mask (logand (aref result 1)
|
||||||
|
(eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:Width
|
||||||
|
xcb:ConfigWindow:Height)))
|
||||||
|
width (aref result 4)
|
||||||
|
height (aref result 5))
|
||||||
(with-current-buffer (aref result 0)
|
(with-current-buffer (aref result 0)
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
|
@ -483,16 +508,20 @@
|
||||||
xcb:ConfigWindow:Y)))
|
xcb:ConfigWindow:Y)))
|
||||||
:x (- (aref result 2) frame-x)
|
:x (- (aref result 2) frame-x)
|
||||||
:y (- (aref result 3) frame-y)))
|
:y (- (aref result 3) frame-y)))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ConfigureWindow
|
||||||
|
:window (frame-parameter exwm--floating-frame
|
||||||
|
'exwm-container)
|
||||||
|
:value-mask value-mask
|
||||||
|
:width width
|
||||||
|
:height height))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window (frame-parameter exwm--floating-frame
|
:window (frame-parameter exwm--floating-frame
|
||||||
'exwm-outer-id)
|
'exwm-outer-id)
|
||||||
:value-mask
|
:value-mask value-mask
|
||||||
(logand (aref result 1)
|
:width width
|
||||||
(eval-when-compile
|
:height height)))
|
||||||
(logior xcb:ConfigWindow:Width
|
|
||||||
xcb:ConfigWindow:Height)))
|
|
||||||
:width (aref result 4) :height (aref result 5))))
|
|
||||||
(xcb:flush exwm--connection))))
|
(xcb:flush exwm--connection))))
|
||||||
|
|
||||||
(defun exwm-floating-move (&optional delta-x delta-y)
|
(defun exwm-floating-move (&optional delta-x delta-y)
|
||||||
|
|
|
@ -113,8 +113,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
|
||||||
(exwm-workspace-switch exwm-workspace-current-index t))
|
(exwm-workspace-switch exwm-workspace-current-index t))
|
||||||
(exwm--log "Set focus on #x%x" exwm--id)
|
(exwm--log "Set focus on #x%x" exwm--id)
|
||||||
(exwm-input--set-focus exwm--id)
|
(exwm-input--set-focus exwm--id)
|
||||||
;; Adjust stacking orders
|
|
||||||
(when exwm--floating-frame
|
(when exwm--floating-frame
|
||||||
|
;; Adjust stacking orders of the floating container.
|
||||||
(if (exwm-workspace--minibuffer-own-frame-p)
|
(if (exwm-workspace--minibuffer-own-frame-p)
|
||||||
;; Put this floating X window just below the minibuffer.
|
;; Put this floating X window just below the minibuffer.
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
|
@ -132,16 +132,8 @@ It's updated in several occasions, and only used by `exwm-input--set-focus'.")
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window exwm--container
|
:window exwm--container
|
||||||
:value-mask xcb:ConfigWindow:StackMode
|
:value-mask xcb:ConfigWindow:StackMode
|
||||||
:stack-mode xcb:StackMode:Above))))
|
:stack-mode xcb:StackMode:Above)))
|
||||||
;; Make sure Emacs frames are at bottom.
|
(xcb:flush exwm--connection)))
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:ConfigureWindow
|
|
||||||
:window (frame-parameter
|
|
||||||
(or exwm--floating-frame exwm--frame)
|
|
||||||
'exwm-outer-id)
|
|
||||||
:value-mask xcb:ConfigWindow:StackMode
|
|
||||||
:stack-mode xcb:StackMode:BottomIf))
|
|
||||||
(xcb:flush exwm--connection))
|
|
||||||
(when (eq (selected-window) exwm-input--focus-window)
|
(when (eq (selected-window) exwm-input--focus-window)
|
||||||
(exwm--log "Focus on %s" exwm-input--focus-window)
|
(exwm--log "Focus on %s" exwm-input--focus-window)
|
||||||
(select-frame-set-input-focus (window-frame exwm-input--focus-window)
|
(select-frame-set-input-focus (window-frame exwm-input--focus-window)
|
||||||
|
|
|
@ -55,20 +55,35 @@
|
||||||
(exwm--log "Show #x%x in %s" id window)
|
(exwm--log "Show #x%x in %s" id window)
|
||||||
(let* ((edges (window-inside-absolute-pixel-edges window))
|
(let* ((edges (window-inside-absolute-pixel-edges window))
|
||||||
(width (- (elt edges 2) (elt edges 0)))
|
(width (- (elt edges 2) (elt edges 0)))
|
||||||
(height (- (elt edges 3) (elt edges 1))))
|
(height (- (elt edges 3) (elt edges 1)))
|
||||||
|
frame-width frame-height)
|
||||||
(with-current-buffer (exwm--id->buffer id)
|
(with-current-buffer (exwm--id->buffer id)
|
||||||
(if exwm--floating-frame
|
(if (not exwm--floating-frame)
|
||||||
|
(let ((relative-edges (window-inside-pixel-edges window)))
|
||||||
|
(exwm-layout--resize-container id exwm--container
|
||||||
|
(elt relative-edges 0)
|
||||||
|
(elt relative-edges 1)
|
||||||
|
width height
|
||||||
|
(active-minibuffer-window)))
|
||||||
;; A floating X window is of the same size as the Emacs window,
|
;; A floating X window is of the same size as the Emacs window,
|
||||||
;; whereas its container is of the same size as the Emacs frame.
|
;; whereas its container is of the same size as the Emacs frame.
|
||||||
(progn
|
(setq frame-width (frame-pixel-width exwm--floating-frame)
|
||||||
|
frame-height (frame-pixel-height exwm--floating-frame))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window exwm--container
|
:window exwm--container
|
||||||
:value-mask (logior xcb:ConfigWindow:Width
|
:value-mask (logior xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height)
|
||||||
:width (frame-pixel-width exwm--floating-frame)
|
:width frame-width
|
||||||
:height (frame-pixel-height
|
:height frame-height))
|
||||||
exwm--floating-frame)))
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ConfigureWindow
|
||||||
|
:window (frame-parameter exwm--floating-frame
|
||||||
|
'exwm-container)
|
||||||
|
:value-mask (logior xcb:ConfigWindow:Width
|
||||||
|
xcb:ConfigWindow:Height)
|
||||||
|
:width frame-width
|
||||||
|
:height frame-height))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window exwm--id
|
:window exwm--id
|
||||||
|
@ -80,12 +95,6 @@
|
||||||
:y exwm-floating-border-width
|
:y exwm-floating-border-width
|
||||||
:width width
|
:width width
|
||||||
:height height)))
|
:height height)))
|
||||||
(let ((relative-edges (window-inside-pixel-edges window)))
|
|
||||||
(exwm-layout--resize-container id exwm--container
|
|
||||||
(elt relative-edges 0)
|
|
||||||
(elt relative-edges 1)
|
|
||||||
width height
|
|
||||||
(active-minibuffer-window))))
|
|
||||||
;; Make the resizing take effect.
|
;; Make the resizing take effect.
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
(xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window id))
|
(xcb:+request exwm--connection (make-instance 'xcb:MapWindow :window id))
|
||||||
|
@ -151,8 +160,7 @@
|
||||||
(make-instance 'xcb:GetGeometry
|
(make-instance 'xcb:GetGeometry
|
||||||
:drawable exwm--container))))
|
:drawable exwm--container))))
|
||||||
(setq exwm--floating-frame-position
|
(setq exwm--floating-frame-position
|
||||||
(vector (slot-value geometry 'x) (slot-value geometry 'y))))
|
(vector (slot-value geometry 'x) (slot-value geometry 'y)))))
|
||||||
(xcb:flush exwm--connection))
|
|
||||||
(exwm-layout--resize-container exwm--id exwm--container 0 0
|
(exwm-layout--resize-container exwm--id exwm--container 0 0
|
||||||
(exwm-workspace--current-width)
|
(exwm-workspace--current-width)
|
||||||
(exwm-workspace--current-height))
|
(exwm-workspace--current-height))
|
||||||
|
@ -205,12 +213,14 @@
|
||||||
:width (x-display-pixel-width)
|
:width (x-display-pixel-width)
|
||||||
:height (x-display-pixel-height))))
|
:height (x-display-pixel-height))))
|
||||||
(id (frame-parameter frame 'exwm-outer-id))
|
(id (frame-parameter frame 'exwm-outer-id))
|
||||||
|
(container (frame-parameter frame 'exwm-container))
|
||||||
(workspace (frame-parameter frame 'exwm-workspace)))
|
(workspace (frame-parameter frame 'exwm-workspace)))
|
||||||
(with-slots (x y width height) geometry
|
(with-slots (x y width height) geometry
|
||||||
(when (and (eq frame exwm-workspace--current)
|
(when (and (eq frame exwm-workspace--current)
|
||||||
(exwm-workspace--minibuffer-own-frame-p))
|
(exwm-workspace--minibuffer-own-frame-p))
|
||||||
(exwm-workspace--resize-minibuffer-frame width height))
|
(exwm-workspace--resize-minibuffer-frame width height))
|
||||||
(exwm-layout--resize-container id workspace x y width height)
|
(exwm-layout--resize-container id container 0 0 width height)
|
||||||
|
(exwm-layout--resize-container nil workspace x y width height t)
|
||||||
(xcb:flush exwm--connection)))
|
(xcb:flush exwm--connection)))
|
||||||
(cl-incf exwm-layout--fullscreen-frame-count))
|
(cl-incf exwm-layout--fullscreen-frame-count))
|
||||||
|
|
||||||
|
@ -349,6 +359,12 @@ windows."
|
||||||
'exwm-outer-id)
|
'exwm-outer-id)
|
||||||
:value-mask xcb:ConfigWindow:Width
|
:value-mask xcb:ConfigWindow:Width
|
||||||
:width width))
|
:width width))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ConfigureWindow
|
||||||
|
:window (frame-parameter exwm--floating-frame
|
||||||
|
'exwm-container)
|
||||||
|
:value-mask xcb:ConfigWindow:Width
|
||||||
|
:width width))
|
||||||
(xcb:flush exwm--connection))))
|
(xcb:flush exwm--connection))))
|
||||||
(t
|
(t
|
||||||
(let* ((height (frame-pixel-height))
|
(let* ((height (frame-pixel-height))
|
||||||
|
@ -375,6 +391,12 @@ windows."
|
||||||
'exwm-outer-id)
|
'exwm-outer-id)
|
||||||
:value-mask xcb:ConfigWindow:Height
|
:value-mask xcb:ConfigWindow:Height
|
||||||
:height height))
|
:height height))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ConfigureWindow
|
||||||
|
:window (frame-parameter exwm--floating-frame
|
||||||
|
'exwm-container)
|
||||||
|
:value-mask xcb:ConfigWindow:Height
|
||||||
|
:height height))
|
||||||
(xcb:flush exwm--connection))))))
|
(xcb:flush exwm--connection))))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
|
|
|
@ -224,6 +224,9 @@ corresponding buffer.")
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:UnmapWindow :window exwm--container))
|
(make-instance 'xcb:UnmapWindow :window exwm--container))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
|
;; Unmap the X window.
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:UnmapWindow :window id))
|
||||||
;;
|
;;
|
||||||
(setq exwm-workspace--switch-history-outdated t)
|
(setq exwm-workspace--switch-history-outdated t)
|
||||||
;;
|
;;
|
||||||
|
@ -256,18 +259,17 @@ corresponding buffer.")
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:DeleteProperty
|
(make-instance 'xcb:DeleteProperty
|
||||||
:window id :property xcb:Atom:WM_STATE)))
|
:window id :property xcb:Atom:WM_STATE)))
|
||||||
;; Destroy the container (it seems it has to be delayed).
|
|
||||||
(when exwm--floating-frame
|
(when exwm--floating-frame
|
||||||
;; Unmap the floating frame.
|
;; Unmap the floating frame before destroying the containers.
|
||||||
(let ((window (frame-parameter exwm--floating-frame 'exwm-outer-id)))
|
(let ((window (frame-parameter exwm--floating-frame 'exwm-outer-id)))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:UnmapWindow :window window))
|
(make-instance 'xcb:UnmapWindow :window window))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
:window window :parent exwm--root :x 0 :y 0))))
|
:window window :parent exwm--root :x 0 :y 0))))
|
||||||
|
;; Destroy the X window container (and the frame container if any).
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:DestroyWindow :window exwm--container))
|
(make-instance 'xcb:DestroyWindow :window exwm--container))
|
||||||
(xcb:flush exwm--connection)
|
|
||||||
(let ((kill-buffer-query-functions nil)
|
(let ((kill-buffer-query-functions nil)
|
||||||
(floating exwm--floating-frame))
|
(floating exwm--floating-frame))
|
||||||
(kill-buffer)
|
(kill-buffer)
|
||||||
|
@ -310,12 +312,14 @@ corresponding buffer.")
|
||||||
(make-instance 'xcb:UnmapWindow :window exwm--container))
|
(make-instance 'xcb:UnmapWindow :window exwm--container))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
(when exwm--floating-frame
|
(when exwm--floating-frame
|
||||||
|
(let ((window (frame-parameter exwm--floating-frame 'exwm-outer-id)))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:UnmapWindow :window window))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
:window (frame-parameter exwm--floating-frame
|
:window window
|
||||||
'exwm-outer-id)
|
|
||||||
:parent exwm--root
|
:parent exwm--root
|
||||||
:x 0 :y 0)))
|
:x 0 :y 0))))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:DestroyWindow :window exwm--container))
|
(make-instance 'xcb:DestroyWindow :window exwm--container))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
|
@ -410,10 +414,13 @@ Would you like to kill it? "
|
||||||
(let ((obj (make-instance 'xcb:ConfigureRequest))
|
(let ((obj (make-instance 'xcb:ConfigureRequest))
|
||||||
buffer edges)
|
buffer edges)
|
||||||
(xcb:unmarshal obj data)
|
(xcb:unmarshal obj data)
|
||||||
(with-slots (window x y width height border-width value-mask)
|
(with-slots (window x y width height
|
||||||
|
border-width sibling stack-mode value-mask)
|
||||||
obj
|
obj
|
||||||
(exwm--log "ConfigureRequest from #x%x (#x%x) @%dx%d%+d%+d, border: %d"
|
(exwm--log "ConfigureRequest from #x%x (#x%x) @%dx%d%+d%+d; \
|
||||||
window value-mask width height x y border-width)
|
border-width: %d; sibling: #x%x; stack-mode: %d"
|
||||||
|
window value-mask width height x y
|
||||||
|
border-width sibling stack-mode)
|
||||||
(if (setq buffer (exwm--id->buffer window))
|
(if (setq buffer (exwm--id->buffer window))
|
||||||
;; Send client message for managed windows
|
;; Send client message for managed windows
|
||||||
(with-current-buffer buffer
|
(with-current-buffer buffer
|
||||||
|
@ -440,16 +447,15 @@ Would you like to kill it? "
|
||||||
:border-width 0 :override-redirect 0)
|
:border-width 0 :override-redirect 0)
|
||||||
exwm--connection))))
|
exwm--connection))))
|
||||||
(exwm--log "ConfigureWindow (preserve geometry)")
|
(exwm--log "ConfigureWindow (preserve geometry)")
|
||||||
;; Configure the unmanaged window without changing the stacking order.
|
;; Configure the unmanaged window.
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window window
|
:window window
|
||||||
:value-mask
|
:value-mask value-mask
|
||||||
(logand value-mask
|
|
||||||
(lognot xcb:ConfigWindow:Sibling)
|
|
||||||
(lognot xcb:ConfigWindow:StackMode))
|
|
||||||
:x x :y y :width width :height height
|
:x x :y y :width width :height height
|
||||||
:border-width border-width)))))
|
:border-width border-width
|
||||||
|
:sibling sibling
|
||||||
|
:stack-mode stack-mode)))))
|
||||||
(xcb:flush exwm--connection))
|
(xcb:flush exwm--connection))
|
||||||
|
|
||||||
(defun exwm-manage--on-MapRequest (data _synthetic)
|
(defun exwm-manage--on-MapRequest (data _synthetic)
|
||||||
|
|
|
@ -252,7 +252,7 @@ The optional FORCE option is for internal use only."
|
||||||
(concat " " name)))))
|
(concat " " name)))))
|
||||||
(setq exwm--frame frame)
|
(setq exwm--frame frame)
|
||||||
(if exwm--floating-frame
|
(if exwm--floating-frame
|
||||||
;; Move the floating frame is enough
|
;; Move the floating container.
|
||||||
(progn
|
(progn
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
@ -261,7 +261,7 @@ The optional FORCE option is for internal use only."
|
||||||
(frame-parameter frame 'exwm-workspace)
|
(frame-parameter frame 'exwm-workspace)
|
||||||
:x 0 :y 0))
|
:x 0 :y 0))
|
||||||
(xcb:flush exwm--connection))
|
(xcb:flush exwm--connection))
|
||||||
;; Move the window itself
|
;; Move the X window container.
|
||||||
(if (/= index exwm-workspace-current-index)
|
(if (/= index exwm-workspace-current-index)
|
||||||
(bury-buffer)
|
(bury-buffer)
|
||||||
(set-window-buffer (get-buffer-window (current-buffer) t)
|
(set-window-buffer (get-buffer-window (current-buffer) t)
|
||||||
|
@ -483,28 +483,30 @@ This functions is modified from `display-buffer-reuse-window' and
|
||||||
(0 (y-or-n-p prompt))
|
(0 (y-or-n-p prompt))
|
||||||
(x (yes-or-no-p (format "[EXWM] %d window%s currently alive. %s"
|
(x (yes-or-no-p (format "[EXWM] %d window%s currently alive. %s"
|
||||||
x (if (= x 1) "" "s") prompt))))
|
x (if (= x 1) "" "s") prompt))))
|
||||||
;; Remove SubstructureRedirect event.
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:ChangeWindowAttributes
|
|
||||||
:window exwm--root :value-mask xcb:CW:EventMask
|
|
||||||
:event-mask 0))
|
|
||||||
;; Remove the _NET_SUPPORTING_WM_CHECK X window.
|
|
||||||
(with-slots (value)
|
|
||||||
(xcb:+request-unchecked+reply exwm--connection
|
|
||||||
(make-instance 'xcb:ewmh:get-_NET_SUPPORTING_WM_CHECK
|
|
||||||
:window exwm--root))
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:DeleteProperty
|
|
||||||
:window exwm--root
|
|
||||||
:property xcb:Atom:_NET_SUPPORTING_WM_CHECK))
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:DestroyWindow :window value)))
|
|
||||||
;; Unmanage all X windows.
|
;; Unmanage all X windows.
|
||||||
(dolist (i exwm--id-buffer-alist)
|
(dolist (i exwm--id-buffer-alist)
|
||||||
(exwm-manage--unmanage-window (car i) t)
|
(exwm-manage--unmanage-window (car i) t)
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:MapWindow :window (car i))))
|
(make-instance 'xcb:MapWindow :window (car i))))
|
||||||
|
;; Reparent out the minibuffer frame.
|
||||||
|
(when exwm-workspace-minibuffer-position
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
:window (frame-parameter exwm-workspace--minibuffer
|
||||||
|
'exwm-outer-id)
|
||||||
|
:parent exwm--root
|
||||||
|
:x 0
|
||||||
|
:y 0)))
|
||||||
|
;; Reparent out all workspace frames.
|
||||||
|
(dolist (f exwm-workspace--list)
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
:window (frame-parameter f 'exwm-outer-id)
|
||||||
|
:parent exwm--root
|
||||||
|
:x 0
|
||||||
|
:y 0)))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
|
;; Destroy all resources created by this connection.
|
||||||
(xcb:disconnect exwm--connection)
|
(xcb:disconnect exwm--connection)
|
||||||
t))
|
t))
|
||||||
|
|
||||||
|
@ -589,9 +591,11 @@ This functions is modified from `display-buffer-reuse-window' and
|
||||||
;; Configure workspaces
|
;; Configure workspaces
|
||||||
(dolist (i exwm-workspace--list)
|
(dolist (i exwm-workspace--list)
|
||||||
(let ((outer-id (string-to-number (frame-parameter i 'outer-window-id)))
|
(let ((outer-id (string-to-number (frame-parameter i 'outer-window-id)))
|
||||||
|
(container (xcb:generate-id exwm--connection))
|
||||||
(workspace (xcb:generate-id exwm--connection)))
|
(workspace (xcb:generate-id exwm--connection)))
|
||||||
;; Save window IDs
|
;; Save window IDs
|
||||||
(set-frame-parameter i 'exwm-outer-id outer-id)
|
(set-frame-parameter i 'exwm-outer-id outer-id)
|
||||||
|
(set-frame-parameter i 'exwm-container container)
|
||||||
(set-frame-parameter i 'exwm-workspace workspace)
|
(set-frame-parameter i 'exwm-workspace workspace)
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:CreateWindow
|
(make-instance 'xcb:CreateWindow
|
||||||
|
@ -605,16 +609,34 @@ This functions is modified from `display-buffer-reuse-window' and
|
||||||
xcb:CW:EventMask)
|
xcb:CW:EventMask)
|
||||||
:override-redirect 1
|
:override-redirect 1
|
||||||
:event-mask xcb:EventMask:SubstructureRedirect))
|
:event-mask xcb:EventMask:SubstructureRedirect))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:CreateWindow
|
||||||
|
:depth 0 :wid container :parent workspace
|
||||||
|
:x 0 :y 0
|
||||||
|
:width (x-display-pixel-width)
|
||||||
|
:height (x-display-pixel-height)
|
||||||
|
:border-width 0 :class xcb:WindowClass:CopyFromParent
|
||||||
|
:visual 0 ;CopyFromParent
|
||||||
|
:value-mask xcb:CW:OverrideRedirect
|
||||||
|
:override-redirect 1))
|
||||||
(exwm--debug
|
(exwm--debug
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
||||||
:window workspace
|
:window workspace
|
||||||
:data
|
:data
|
||||||
(format "EXWM workspace %d"
|
(format "EXWM workspace %d"
|
||||||
|
(cl-position i exwm-workspace--list))))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ewmh:set-_NET_WM_NAME
|
||||||
|
:window container
|
||||||
|
:data
|
||||||
|
(format "EXWM workspace %d frame container"
|
||||||
(cl-position i exwm-workspace--list)))))
|
(cl-position i exwm-workspace--list)))))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
:window outer-id :parent workspace :x 0 :y 0))
|
:window outer-id :parent container :x 0 :y 0))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:MapWindow :window container))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:MapWindow :window workspace))))
|
(make-instance 'xcb:MapWindow :window workspace))))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
|
|
Loading…
Reference in a new issue