mirror of
https://github.com/emacs-exwm/exwm.git
synced 2024-11-30 16:07:59 +01:00
Fix floating X window bugs introduced by 9c95c03e
* exwm-floating.el (exwm-floating--set-floating): Make floating frames invisible before resizing them. (exwm-floating--fit-frame-to-window): Removed since unused. * exwm-layout.el (exwm-layout-hide-mode-line, exwm-layout-show-mode-line): Use set frame height instead of exwm-floating--fit-frame-to-window. * exwm-core.el (exwm-mode): Replace `exwm-manage--close-window' with `exwm-manage--kill-buffer-query-function'. * exwm-floating.el (exwm-floating--unset-floating): Reparent out floating frames. * exwm-manage.el (exwm-manage--unmanage-window): Reparent out floating frames. Hide floating frames. (exwm-manage--close-window, exwm-manage--kill-buffer-query-function): Rename `exwm-manage--close-window' since it's only used in `kill-buffer-query-functions'. Reparent out floating frames.
This commit is contained in:
parent
12e2d574c9
commit
3f7722079c
4 changed files with 137 additions and 114 deletions
|
@ -142,9 +142,7 @@
|
||||||
(add-hook 'change-major-mode-hook #'kill-buffer nil t)
|
(add-hook 'change-major-mode-hook #'kill-buffer nil t)
|
||||||
;; Kill buffer -> close window
|
;; Kill buffer -> close window
|
||||||
(add-hook 'kill-buffer-query-functions
|
(add-hook 'kill-buffer-query-functions
|
||||||
(lambda ()
|
#'exwm-manage--kill-buffer-query-function nil t)
|
||||||
(exwm-manage--close-window exwm--id (current-buffer)))
|
|
||||||
nil t)
|
|
||||||
(setq buffer-read-only t
|
(setq buffer-read-only t
|
||||||
left-margin-width nil
|
left-margin-width nil
|
||||||
right-margin-width nil
|
right-margin-width nil
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
(defvar exwm-floating--cursor-bottom-left nil)
|
(defvar exwm-floating--cursor-bottom-left nil)
|
||||||
(defvar exwm-floating--cursor-left nil)
|
(defvar exwm-floating--cursor-left nil)
|
||||||
|
|
||||||
|
(declare-function exwm-layout--refresh "exwm-layout.el")
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun exwm-floating--set-floating (id)
|
(defun exwm-floating--set-floating (id)
|
||||||
"Make window ID floating."
|
"Make window ID floating."
|
||||||
|
@ -78,6 +80,8 @@
|
||||||
(internal-border-width . ,exwm-floating-border-width)
|
(internal-border-width . ,exwm-floating-border-width)
|
||||||
(left . 10000)
|
(left . 10000)
|
||||||
(top . 10000)
|
(top . 10000)
|
||||||
|
(width . ,window-min-width)
|
||||||
|
(height . ,window-min-height)
|
||||||
(unsplittable . t))))) ;and fix the size later
|
(unsplittable . t))))) ;and fix the size later
|
||||||
(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)
|
||||||
|
@ -151,7 +155,17 @@
|
||||||
y (/ (- display-height height) 2))))))
|
y (/ (- display-height height) 2))))))
|
||||||
(exwm--log "Floating geometry (corrected): %dx%d%+d%+d" width height x y)
|
(exwm--log "Floating geometry (corrected): %dx%d%+d%+d" width height x y)
|
||||||
;; Fit frame to client
|
;; Fit frame to client
|
||||||
(exwm-floating--fit-frame-to-window outer-id width height)
|
;; It seems we have to make the frame invisible in order to resize it
|
||||||
|
;; timely.
|
||||||
|
;; The frame will be made visible by `select-frame-set-input-focus'.
|
||||||
|
(make-frame-invisible frame)
|
||||||
|
(let ((edges (window-inside-pixel-edges window)))
|
||||||
|
(set-frame-size frame
|
||||||
|
(+ width (- (frame-pixel-width frame)
|
||||||
|
(- (elt edges 2) (elt edges 0))))
|
||||||
|
(+ height (- (frame-pixel-height frame)
|
||||||
|
(- (elt edges 3) (elt edges 1))))
|
||||||
|
t))
|
||||||
;; Reparent this frame to the container
|
;; Reparent this frame to the container
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
@ -171,8 +185,12 @@
|
||||||
(setq window-size-fixed exwm--fixed-size
|
(setq window-size-fixed exwm--fixed-size
|
||||||
exwm--frame original-frame
|
exwm--frame original-frame
|
||||||
exwm--floating-frame frame)
|
exwm--floating-frame frame)
|
||||||
|
;; Do the refresh manually.
|
||||||
|
(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
|
||||||
(set-window-dedicated-p window t))
|
(add-hook 'window-configuration-change-hook #'exwm-layout--refresh)
|
||||||
|
(set-window-dedicated-p window t)
|
||||||
|
(exwm-layout--show id window))
|
||||||
(select-frame-set-input-focus frame))
|
(select-frame-set-input-focus frame))
|
||||||
(run-hooks 'exwm-floating-setup-hook))
|
(run-hooks 'exwm-floating-setup-hook))
|
||||||
|
|
||||||
|
@ -182,6 +200,16 @@
|
||||||
(interactive)
|
(interactive)
|
||||||
(let ((buffer (exwm--id->buffer id)))
|
(let ((buffer (exwm--id->buffer id)))
|
||||||
(with-current-buffer buffer
|
(with-current-buffer buffer
|
||||||
|
;; Reparent the frame back to the root window.
|
||||||
|
(when exwm--floating-frame
|
||||||
|
(let ((frame-id (frame-parameter exwm--floating-frame 'exwm-outer-id)))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:UnmapWindow :window frame-id))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
:window frame-id
|
||||||
|
:parent exwm--root
|
||||||
|
:x 0 :y 0))))
|
||||||
;; Reparent the container to the workspace
|
;; Reparent the container to the workspace
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ReparentWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
@ -221,34 +249,6 @@
|
||||||
(exwm-floating--unset-floating exwm--id)
|
(exwm-floating--unset-floating exwm--id)
|
||||||
(exwm-floating--set-floating exwm--id))))
|
(exwm-floating--set-floating exwm--id))))
|
||||||
|
|
||||||
;;;###autoload
|
|
||||||
(defun exwm-floating--fit-frame-to-window (&optional frame-outer-id
|
|
||||||
width height)
|
|
||||||
"Resize a floating frame to make it fit the size of the window.
|
|
||||||
|
|
||||||
Default to resize `exwm--floating-frame' unless FRAME-OUTER-ID is non-nil.
|
|
||||||
This function will issue an `xcb:GetGeometry' request unless WIDTH and HEIGHT
|
|
||||||
are provided. You should call `xcb:flush' and restore the value of
|
|
||||||
`window-size-fixed' afterwards."
|
|
||||||
(setq window-size-fixed nil)
|
|
||||||
(unless (and width height)
|
|
||||||
(let ((geometry (xcb:+request-unchecked+reply exwm--connection
|
|
||||||
(make-instance 'xcb:GetGeometry :drawable exwm--id))))
|
|
||||||
(setq width (slot-value geometry 'width)
|
|
||||||
height (slot-value geometry 'height))))
|
|
||||||
(xcb:+request exwm--connection
|
|
||||||
(make-instance 'xcb:ConfigureWindow
|
|
||||||
:window (or frame-outer-id
|
|
||||||
(frame-parameter exwm--floating-frame
|
|
||||||
'exwm-outer-id))
|
|
||||||
:value-mask (eval-when-compile
|
|
||||||
(logior xcb:ConfigWindow:Width
|
|
||||||
xcb:ConfigWindow:Height))
|
|
||||||
:width (+ width (* 2 exwm-floating-border-width))
|
|
||||||
:height (+ height (* 2 exwm-floating-border-width)
|
|
||||||
(window-mode-line-height)
|
|
||||||
(window-header-line-height)))))
|
|
||||||
|
|
||||||
(define-obsolete-function-alias 'exwm-floating-hide-mode-line
|
(define-obsolete-function-alias 'exwm-floating-hide-mode-line
|
||||||
'exwm-layout-hide-mode-line "25.1" "Hide mode-line of a floating frame.")
|
'exwm-layout-hide-mode-line "25.1" "Hide mode-line of a floating frame.")
|
||||||
(define-obsolete-function-alias 'exwm-floating-show-mode-line
|
(define-obsolete-function-alias 'exwm-floating-show-mode-line
|
||||||
|
|
|
@ -396,13 +396,18 @@ See also `exwm-layout-enlarge-window'."
|
||||||
"Hide mode-line."
|
"Hide mode-line."
|
||||||
(interactive)
|
(interactive)
|
||||||
(when (and (eq major-mode 'exwm-mode) mode-line-format)
|
(when (and (eq major-mode 'exwm-mode) mode-line-format)
|
||||||
|
(let (mode-line-height)
|
||||||
|
(when exwm--floating-frame
|
||||||
|
(setq mode-line-height (window-mode-line-height
|
||||||
|
(frame-root-window exwm--floating-frame))))
|
||||||
(setq exwm--mode-line-format mode-line-format
|
(setq exwm--mode-line-format mode-line-format
|
||||||
mode-line-format nil)
|
mode-line-format nil)
|
||||||
(if (not exwm--floating-frame)
|
(if (not exwm--floating-frame)
|
||||||
(exwm-layout--show exwm--id)
|
(exwm-layout--show exwm--id)
|
||||||
(exwm-floating--fit-frame-to-window)
|
(set-frame-height exwm--floating-frame
|
||||||
(xcb:flush exwm--connection)
|
(- (frame-pixel-height exwm--floating-frame)
|
||||||
(setq window-size-fixed exwm--fixed-size))))
|
mode-line-height)
|
||||||
|
nil t)))))
|
||||||
|
|
||||||
(defun exwm-layout-show-mode-line ()
|
(defun exwm-layout-show-mode-line ()
|
||||||
"Show mode-line."
|
"Show mode-line."
|
||||||
|
@ -412,10 +417,12 @@ See also `exwm-layout-enlarge-window'."
|
||||||
exwm--mode-line-format nil)
|
exwm--mode-line-format nil)
|
||||||
(if (not exwm--floating-frame)
|
(if (not exwm--floating-frame)
|
||||||
(exwm-layout--show exwm--id)
|
(exwm-layout--show exwm--id)
|
||||||
(exwm-floating--fit-frame-to-window)
|
(set-frame-height exwm--floating-frame
|
||||||
(exwm-input-grab-keyboard)
|
(+ (frame-pixel-height exwm--floating-frame)
|
||||||
(xcb:flush exwm--connection)
|
(window-mode-line-height (frame-root-window
|
||||||
(setq window-size-fixed exwm--fixed-size))))
|
exwm--floating-frame)))
|
||||||
|
nil t)
|
||||||
|
(exwm-input-grab-keyboard))))
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun exwm-layout-toggle-mode-line ()
|
(defun exwm-layout-toggle-mode-line ()
|
||||||
|
|
112
exwm-manage.el
112
exwm-manage.el
|
@ -103,7 +103,7 @@ corresponding buffer.")
|
||||||
exwm-window-type))))
|
exwm-window-type))))
|
||||||
(exwm--log "No need to manage #x%x" id)
|
(exwm--log "No need to manage #x%x" id)
|
||||||
;; Remove all events
|
;; Remove all events
|
||||||
(xcb:+request-checked+request-check exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ChangeWindowAttributes
|
(make-instance 'xcb:ChangeWindowAttributes
|
||||||
:window id :value-mask xcb:CW:EventMask
|
:window id :value-mask xcb:CW:EventMask
|
||||||
:event-mask xcb:EventMask:NoEvent))
|
:event-mask xcb:EventMask:NoEvent))
|
||||||
|
@ -173,7 +173,7 @@ corresponding buffer.")
|
||||||
:border-width 0))
|
:border-width 0))
|
||||||
(dolist (button ;grab buttons to set focus / move / resize
|
(dolist (button ;grab buttons to set focus / move / resize
|
||||||
(list xcb:ButtonIndex:1 xcb:ButtonIndex:2 xcb:ButtonIndex:3))
|
(list xcb:ButtonIndex:1 xcb:ButtonIndex:2 xcb:ButtonIndex:3))
|
||||||
(xcb:+request-checked+request-check exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:GrabButton
|
(make-instance 'xcb:GrabButton
|
||||||
:owner-events 0 :grab-window id
|
:owner-events 0 :grab-window id
|
||||||
:event-mask xcb:EventMask:ButtonPress
|
:event-mask xcb:EventMask:ButtonPress
|
||||||
|
@ -206,13 +206,10 @@ corresponding buffer.")
|
||||||
(let ((buffer (exwm--id->buffer id)))
|
(let ((buffer (exwm--id->buffer id)))
|
||||||
(exwm--log "Unmanage #x%x (buffer: %s)" id buffer)
|
(exwm--log "Unmanage #x%x (buffer: %s)" id buffer)
|
||||||
(setq exwm--id-buffer-alist (assq-delete-all id exwm--id-buffer-alist))
|
(setq exwm--id-buffer-alist (assq-delete-all id exwm--id-buffer-alist))
|
||||||
(xcb:+request exwm--connection ;update _NET_CLIENT_LIST
|
|
||||||
(make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST
|
|
||||||
:window exwm--root
|
|
||||||
:data (vconcat (mapcar #'car exwm--id-buffer-alist))))
|
|
||||||
(xcb:flush exwm--connection)
|
|
||||||
(when (buffer-live-p buffer)
|
(when (buffer-live-p buffer)
|
||||||
(with-current-buffer buffer
|
(with-current-buffer buffer
|
||||||
|
;; Hide the floating frame as early as possible.
|
||||||
|
(when exwm--floating-frame (make-frame-invisible exwm--floating-frame))
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:UnmapWindow :window exwm--container))
|
(make-instance 'xcb:UnmapWindow :window exwm--container))
|
||||||
(setq exwm-workspace--switch-history-outdated t)
|
(setq exwm-workspace--switch-history-outdated t)
|
||||||
|
@ -245,21 +242,29 @@ corresponding buffer.")
|
||||||
;; Delete WM_STATE property
|
;; Delete WM_STATE property
|
||||||
(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)))
|
||||||
(xcb:flush exwm--connection))
|
|
||||||
;; Destroy the container (it seems it has to be delayed).
|
;; Destroy the container (it seems it has to be delayed).
|
||||||
(run-with-idle-timer 0 nil
|
(when exwm--floating-frame
|
||||||
`(lambda ()
|
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
,(make-instance 'xcb:DestroyWindow
|
(make-instance 'xcb:ReparentWindow
|
||||||
:window exwm--container))
|
:window (frame-parameter exwm--floating-frame
|
||||||
(xcb:flush exwm--connection)))
|
'exwm-outer-id)
|
||||||
|
:parent exwm--root
|
||||||
|
:x 0 :y 0)))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(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)
|
||||||
(when floating
|
(when floating
|
||||||
(select-window
|
(select-window
|
||||||
(frame-selected-window exwm-workspace--current))))))))
|
(frame-selected-window exwm-workspace--current))))))
|
||||||
|
(xcb:+request exwm--connection ;update _NET_CLIENT_LIST
|
||||||
|
(make-instance 'xcb:ewmh:set-_NET_CLIENT_LIST
|
||||||
|
:window exwm--root
|
||||||
|
:data (vconcat (mapcar #'car exwm--id-buffer-alist))))
|
||||||
|
(xcb:flush exwm--connection)))
|
||||||
|
|
||||||
(defun exwm-manage--scan ()
|
(defun exwm-manage--scan ()
|
||||||
"Search for existing windows and try to manage them."
|
"Search for existing windows and try to manage them."
|
||||||
|
@ -280,64 +285,77 @@ corresponding buffer.")
|
||||||
(defvar exwm-manage-ping-timeout 3 "Seconds to wait before killing a client.")
|
(defvar exwm-manage-ping-timeout 3 "Seconds to wait before killing a client.")
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(defun exwm-manage--close-window (id &optional buffer)
|
(defun exwm-manage--kill-buffer-query-function ()
|
||||||
"Close window ID in a proper way."
|
"Run in `kill-buffer-query-functions'."
|
||||||
(let (container)
|
|
||||||
(catch 'return
|
(catch 'return
|
||||||
(unless (exwm--id->buffer id)
|
(when (xcb:+request-checked+request-check exwm--connection
|
||||||
(throw 'return t))
|
(make-instance 'xcb:MapWindow :window exwm--id))
|
||||||
(unless buffer (setq buffer (exwm--id->buffer id)))
|
;; The X window is no longer alive so just close the buffer.
|
||||||
(when (buffer-live-p buffer)
|
;; Destroy the container.
|
||||||
(setq container exwm--container))
|
(when exwm--floating-frame
|
||||||
;; Destroy the client window if it does not support WM_DELETE_WINDOW
|
|
||||||
(unless (and (buffer-live-p buffer)
|
|
||||||
(with-current-buffer buffer
|
|
||||||
(memq xcb:Atom:WM_DELETE_WINDOW exwm--protocols)))
|
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:DestroyWindow :window id))
|
(make-instance 'xcb:ReparentWindow
|
||||||
|
:window (frame-parameter exwm--floating-frame
|
||||||
|
'exwm-outer-id)
|
||||||
|
:parent exwm--root
|
||||||
|
:x 0 :y 0)))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:DestroyWindow :window exwm--container))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
|
(throw 'return t))
|
||||||
|
(unless (memq xcb:Atom:WM_DELETE_WINDOW exwm--protocols)
|
||||||
|
;; The X window does not support WM_DELETE_WINDOW; destroy it.
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:DestroyWindow :window exwm--id))
|
||||||
|
(xcb:flush exwm--connection)
|
||||||
|
;; Wait for DestroyNotify event.
|
||||||
(throw 'return nil))
|
(throw 'return nil))
|
||||||
;; Try to close the window with WM_DELETE_WINDOW client message
|
;; Try to close the X window with WM_DELETE_WINDOW client message.
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:icccm:SendEvent
|
(make-instance 'xcb:icccm:SendEvent
|
||||||
:destination id
|
:destination exwm--id
|
||||||
:event (xcb:marshal
|
:event (xcb:marshal
|
||||||
(make-instance 'xcb:icccm:WM_DELETE_WINDOW
|
(make-instance 'xcb:icccm:WM_DELETE_WINDOW
|
||||||
:window id)
|
:window exwm--id)
|
||||||
exwm--connection)))
|
exwm--connection)))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
;; Try to determine if the client stop responding
|
;;
|
||||||
(with-current-buffer buffer
|
|
||||||
(unless (memq xcb:Atom:_NET_WM_PING exwm--protocols)
|
(unless (memq xcb:Atom:_NET_WM_PING exwm--protocols)
|
||||||
;; Ensure it's dead
|
;; The window does not support _NET_WM_PING. To make sure it'll die,
|
||||||
|
;; kill it after the time runs out.
|
||||||
(run-with-timer exwm-manage-ping-timeout nil
|
(run-with-timer exwm-manage-ping-timeout nil
|
||||||
`(lambda () (exwm-manage--kill-client ,id)))
|
`(lambda () (exwm-manage--kill-client ,exwm--id)))
|
||||||
|
;; Wait for DestroyNotify event.
|
||||||
(throw 'return nil))
|
(throw 'return nil))
|
||||||
|
;; Try to determine if the X window is dead with _NET_WM_PING.
|
||||||
(setq exwm-manage--ping-lock t)
|
(setq exwm-manage--ping-lock t)
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:SendEvent
|
(make-instance 'xcb:SendEvent
|
||||||
:propagate 0 :destination id
|
:propagate 0
|
||||||
|
:destination exwm--id
|
||||||
:event-mask xcb:EventMask:NoEvent
|
:event-mask xcb:EventMask:NoEvent
|
||||||
:event (xcb:marshal
|
:event (xcb:marshal
|
||||||
(make-instance 'xcb:ewmh:_NET_WM_PING
|
(make-instance 'xcb:ewmh:_NET_WM_PING
|
||||||
:window id :timestamp 0
|
:window exwm--id
|
||||||
:client-window id)
|
:timestamp 0
|
||||||
|
:client-window exwm--id)
|
||||||
exwm--connection)))
|
exwm--connection)))
|
||||||
(xcb:flush exwm--connection)
|
(xcb:flush exwm--connection)
|
||||||
(with-timeout (exwm-manage-ping-timeout
|
(with-timeout (exwm-manage-ping-timeout
|
||||||
(if (yes-or-no-p (format "`%s' is not responding. \
|
(if (yes-or-no-p (format "'%s' is not responding. \
|
||||||
Would you like to kill it? "
|
Would you like to kill it? "
|
||||||
(buffer-name buffer)))
|
(buffer-name)))
|
||||||
(progn (exwm-manage--kill-client id)
|
(progn (exwm-manage--kill-client exwm--id)
|
||||||
|
;; Kill the unresponsive X window and
|
||||||
|
;; wait for DestroyNotify event.
|
||||||
(throw 'return nil))
|
(throw 'return nil))
|
||||||
|
;; Give up.
|
||||||
(throw 'return nil)))
|
(throw 'return nil)))
|
||||||
(while (and exwm-manage--ping-lock
|
(while (and exwm-manage--ping-lock
|
||||||
(exwm--id->buffer id)) ;may have been destroyed
|
(exwm--id->buffer exwm--id)) ;may have been destroyed.
|
||||||
(accept-process-output nil 0.1)))))
|
(accept-process-output nil 0.1))
|
||||||
;; Finally destroy the container
|
;; Give up.
|
||||||
(xcb:+request exwm--connection
|
(throw 'return nil))))
|
||||||
(make-instance 'xcb:DestroyWindow :window container))
|
|
||||||
(xcb:flush exwm--connection)))
|
|
||||||
|
|
||||||
(defun exwm-manage--kill-client (&optional id)
|
(defun exwm-manage--kill-client (&optional id)
|
||||||
"Kill an X client."
|
"Kill an X client."
|
||||||
|
|
Loading…
Reference in a new issue