mirror of
https://github.com/ch11ng/exwm.git
synced 2024-11-30 14:38:00 +01:00
Allow moving/resizing undecorated X windows
* exwm-manage.el (exwm-manage--manage-window): Do not manage undecorated floating X windows (set in _MOTIF_WM_HINTS). * exwm-floating.el (exwm-floating--start-moveresize) (exwm-floating--stop-moveresize, exwm-floating--do-moveresize): Allow moving/resizing undecorated X windows with _NET_WM_MOVERESIZE client message.
This commit is contained in:
parent
fe9be0b3ef
commit
8706e490fb
2 changed files with 91 additions and 68 deletions
152
exwm-floating.el
152
exwm-floating.el
|
@ -310,18 +310,23 @@
|
||||||
|
|
||||||
(defun exwm-floating--start-moveresize (id &optional type)
|
(defun exwm-floating--start-moveresize (id &optional type)
|
||||||
"Start move/resize."
|
"Start move/resize."
|
||||||
(let ((buffer (exwm--id->buffer id))
|
(let ((buffer-or-id (or (exwm--id->buffer id) id))
|
||||||
frame container x y width height cursor)
|
frame container-or-id x y width height cursor)
|
||||||
(when (and buffer
|
(if (bufferp buffer-or-id)
|
||||||
(with-current-buffer buffer
|
;; Managed.
|
||||||
(setq frame exwm--floating-frame
|
(with-current-buffer buffer-or-id
|
||||||
container exwm--container))
|
(setq frame exwm--floating-frame
|
||||||
|
container-or-id exwm--container))
|
||||||
|
;; Unmanaged.
|
||||||
|
(setq container-or-id id))
|
||||||
|
(when (and container-or-id
|
||||||
;; Test if the pointer can be grabbed
|
;; Test if the pointer can be grabbed
|
||||||
(= xcb:GrabStatus:Success
|
(= xcb:GrabStatus:Success
|
||||||
(slot-value
|
(slot-value
|
||||||
(xcb:+request-unchecked+reply exwm--connection
|
(xcb:+request-unchecked+reply exwm--connection
|
||||||
(make-instance 'xcb:GrabPointer
|
(make-instance 'xcb:GrabPointer
|
||||||
:owner-events 0 :grab-window container
|
:owner-events 0
|
||||||
|
:grab-window container-or-id
|
||||||
:event-mask xcb:EventMask:NoEvent
|
:event-mask xcb:EventMask:NoEvent
|
||||||
:pointer-mode xcb:GrabMode:Async
|
:pointer-mode xcb:GrabMode:Async
|
||||||
:keyboard-mode xcb:GrabMode:Async
|
:keyboard-mode xcb:GrabMode:Async
|
||||||
|
@ -332,33 +337,43 @@
|
||||||
(with-slots (root-x root-y win-x win-y)
|
(with-slots (root-x root-y win-x win-y)
|
||||||
(xcb:+request-unchecked+reply exwm--connection
|
(xcb:+request-unchecked+reply exwm--connection
|
||||||
(make-instance 'xcb:QueryPointer :window id))
|
(make-instance 'xcb:QueryPointer :window id))
|
||||||
(select-window (frame-first-window frame)) ;transfer input focus
|
(if (not (bufferp buffer-or-id))
|
||||||
(setq width (frame-pixel-width frame)
|
;; Unmanaged.
|
||||||
height (frame-pixel-height frame))
|
(unless (eq type xcb:ewmh:_NET_WM_MOVERESIZE_MOVE)
|
||||||
(unless type
|
(with-slots ((width* width)
|
||||||
;; Determine the resize type according to the pointer position
|
(height* height))
|
||||||
;; Clicking the center 1/3 part to resize has not effect
|
(xcb:+request-unchecked+reply exwm--connection
|
||||||
(setq x (/ (* 3 win-x) (float width))
|
(make-instance 'xcb:GetGeometry :drawable id))
|
||||||
y (/ (* 3 win-y) (float height))
|
(setq width width*
|
||||||
type (cond ((and (< x 1) (< y 1))
|
height height*)))
|
||||||
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPLEFT)
|
;; Managed.
|
||||||
((and (> x 2) (< y 1))
|
(select-window (frame-first-window frame)) ;transfer input focus
|
||||||
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPRIGHT)
|
(setq width (frame-pixel-width frame)
|
||||||
((and (> x 2) (> y 2))
|
height (frame-pixel-height frame))
|
||||||
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT)
|
(unless type
|
||||||
((and (< x 1) (> y 2))
|
;; Determine the resize type according to the pointer position
|
||||||
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)
|
;; Clicking the center 1/3 part to resize has not effect
|
||||||
((< y 1) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOP)
|
(setq x (/ (* 3 win-x) (float width))
|
||||||
((> x 2) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_RIGHT)
|
y (/ (* 3 win-y) (float height))
|
||||||
((> y 2) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOM)
|
type (cond ((and (< x 1) (< y 1))
|
||||||
((< x 1) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_LEFT))))
|
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPLEFT)
|
||||||
|
((and (> x 2) (< y 1))
|
||||||
|
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPRIGHT)
|
||||||
|
((and (> x 2) (> y 2))
|
||||||
|
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT)
|
||||||
|
((and (< x 1) (> y 2))
|
||||||
|
xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)
|
||||||
|
((> x 2) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_RIGHT)
|
||||||
|
((> y 2) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOM)
|
||||||
|
((< x 1) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_LEFT)
|
||||||
|
((< y 1) xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOP)))))
|
||||||
(if (not type)
|
(if (not type)
|
||||||
(exwm-floating--stop-moveresize)
|
(exwm-floating--stop-moveresize)
|
||||||
(cond ((= type xcb:ewmh:_NET_WM_MOVERESIZE_MOVE)
|
(cond ((= type xcb:ewmh:_NET_WM_MOVERESIZE_MOVE)
|
||||||
(setq cursor exwm-floating--cursor-move
|
(setq cursor exwm-floating--cursor-move
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,(eval-when-compile
|
,(eval-when-compile
|
||||||
(logior xcb:ConfigWindow:X
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y))
|
xcb:ConfigWindow:Y))
|
||||||
|
@ -367,7 +382,7 @@
|
||||||
(setq cursor exwm-floating--cursor-top-left
|
(setq cursor exwm-floating--cursor-top-left
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,(eval-when-compile
|
,(eval-when-compile
|
||||||
(logior xcb:ConfigWindow:X
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
|
@ -380,7 +395,7 @@
|
||||||
(setq cursor exwm-floating--cursor-top
|
(setq cursor exwm-floating--cursor-top
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,(eval-when-compile
|
,(eval-when-compile
|
||||||
(logior xcb:ConfigWindow:Y
|
(logior xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Height))
|
xcb:ConfigWindow:Height))
|
||||||
|
@ -389,7 +404,7 @@
|
||||||
(setq cursor exwm-floating--cursor-top-right
|
(setq cursor exwm-floating--cursor-top-right
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,(eval-when-compile
|
,(eval-when-compile
|
||||||
(logior xcb:ConfigWindow:Y
|
(logior xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
|
@ -400,13 +415,14 @@
|
||||||
(setq cursor exwm-floating--cursor-right
|
(setq cursor exwm-floating--cursor-right
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer ,xcb:ConfigWindow:Width
|
(vector ,buffer-or-id
|
||||||
|
,xcb:ConfigWindow:Width
|
||||||
0 0 (- x ,(- root-x width)) 0))))
|
0 0 (- x ,(- root-x width)) 0))))
|
||||||
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT)
|
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT)
|
||||||
(setq cursor exwm-floating--cursor-bottom-right
|
(setq cursor exwm-floating--cursor-bottom-right
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,(eval-when-compile
|
,(eval-when-compile
|
||||||
(logior xcb:ConfigWindow:Width
|
(logior xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height))
|
xcb:ConfigWindow:Height))
|
||||||
|
@ -416,14 +432,14 @@
|
||||||
(setq cursor exwm-floating--cursor-bottom
|
(setq cursor exwm-floating--cursor-bottom
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,xcb:ConfigWindow:Height
|
,xcb:ConfigWindow:Height
|
||||||
0 0 0 (- y ,(- root-y height))))))
|
0 0 0 (- y ,(- root-y height))))))
|
||||||
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)
|
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)
|
||||||
(setq cursor exwm-floating--cursor-bottom-left
|
(setq cursor exwm-floating--cursor-bottom-left
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,(eval-when-compile
|
,(eval-when-compile
|
||||||
(logior xcb:ConfigWindow:X
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
|
@ -436,7 +452,7 @@
|
||||||
(setq cursor exwm-floating--cursor-left
|
(setq cursor exwm-floating--cursor-left
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,buffer
|
(vector ,buffer-or-id
|
||||||
,(eval-when-compile
|
,(eval-when-compile
|
||||||
(logior xcb:ConfigWindow:X
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Width))
|
xcb:ConfigWindow:Width))
|
||||||
|
@ -444,7 +460,7 @@
|
||||||
;; Select events and change cursor (should always succeed)
|
;; Select events and change cursor (should always succeed)
|
||||||
(xcb:+request-unchecked+reply exwm--connection
|
(xcb:+request-unchecked+reply exwm--connection
|
||||||
(make-instance 'xcb:GrabPointer
|
(make-instance 'xcb:GrabPointer
|
||||||
:owner-events 0 :grab-window container
|
:owner-events 0 :grab-window container-or-id
|
||||||
:event-mask (eval-when-compile
|
:event-mask (eval-when-compile
|
||||||
(logior xcb:EventMask:ButtonRelease
|
(logior xcb:EventMask:ButtonRelease
|
||||||
xcb:EventMask:ButtonMotion))
|
xcb:EventMask:ButtonMotion))
|
||||||
|
@ -459,7 +475,9 @@
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:UngrabPointer :time xcb:Time:CurrentTime))
|
(make-instance 'xcb:UngrabPointer :time xcb:Time:CurrentTime))
|
||||||
;; Inform the X window that its absolute position is changed
|
;; Inform the X window that its absolute position is changed
|
||||||
(when exwm-floating--moveresize-calculate
|
(when (and exwm-floating--moveresize-calculate
|
||||||
|
;; Unmanaged.
|
||||||
|
(eq major-mode 'exwm-mode))
|
||||||
(let ((edges (window-inside-absolute-pixel-edges (frame-selected-window)))
|
(let ((edges (window-inside-absolute-pixel-edges (frame-selected-window)))
|
||||||
(id (with-current-buffer (window-buffer (frame-selected-window))
|
(id (with-current-buffer (window-buffer (frame-selected-window))
|
||||||
exwm--id)))
|
exwm--id)))
|
||||||
|
@ -490,7 +508,7 @@
|
||||||
(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 value-mask width height)
|
result value-mask width height buffer-or-id container-or-id)
|
||||||
(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)))
|
||||||
|
@ -503,30 +521,38 @@
|
||||||
xcb:ConfigWindow:Height)))
|
xcb:ConfigWindow:Height)))
|
||||||
width (aref result 4)
|
width (aref result 4)
|
||||||
height (aref result 5))
|
height (aref result 5))
|
||||||
(with-current-buffer (aref result 0)
|
(setq buffer-or-id (aref result 0))
|
||||||
(xcb:+request exwm--connection
|
(setq container-or-id
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(if (bufferp buffer-or-id)
|
||||||
:window exwm--container
|
;; Managed.
|
||||||
:value-mask (logand (aref result 1)
|
(with-current-buffer buffer-or-id exwm--container)
|
||||||
(eval-when-compile
|
;; Unmanaged.
|
||||||
(logior xcb:ConfigWindow:X
|
buffer-or-id))
|
||||||
xcb:ConfigWindow:Y)))
|
(xcb:+request exwm--connection
|
||||||
:x (- (aref result 2) frame-x)
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:y (- (aref result 3) frame-y)))
|
:window container-or-id
|
||||||
(xcb:+request exwm--connection
|
:value-mask (aref result 1)
|
||||||
(make-instance 'xcb:ConfigureWindow
|
:x (- (aref result 2) frame-x)
|
||||||
:window (frame-parameter exwm--floating-frame
|
:y (- (aref result 3) frame-y)
|
||||||
'exwm-container)
|
:width width
|
||||||
:value-mask value-mask
|
:height height))
|
||||||
:width width
|
(when (bufferp buffer-or-id)
|
||||||
:height height))
|
;; Managed.
|
||||||
(xcb:+request exwm--connection
|
(with-current-buffer buffer-or-id
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(xcb:+request exwm--connection
|
||||||
:window (frame-parameter exwm--floating-frame
|
(make-instance 'xcb:ConfigureWindow
|
||||||
'exwm-outer-id)
|
:window (frame-parameter exwm--floating-frame
|
||||||
:value-mask value-mask
|
'exwm-container)
|
||||||
:width width
|
:value-mask value-mask
|
||||||
:height height)))
|
:width width
|
||||||
|
:height height))
|
||||||
|
(xcb:+request exwm--connection
|
||||||
|
(make-instance 'xcb:ConfigureWindow
|
||||||
|
:window (frame-parameter exwm--floating-frame
|
||||||
|
'exwm-outer-id)
|
||||||
|
:value-mask value-mask
|
||||||
|
:width width
|
||||||
|
:height height))))
|
||||||
(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)
|
||||||
|
|
|
@ -99,15 +99,12 @@ corresponding buffer.")
|
||||||
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY exwm-window-type)
|
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY exwm-window-type)
|
||||||
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_DIALOG exwm-window-type)
|
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_DIALOG exwm-window-type)
|
||||||
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_NORMAL exwm-window-type)))
|
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_NORMAL exwm-window-type)))
|
||||||
;; Check _MOTIF_WM_HINTS for Java applications
|
;; Check the _MOTIF_WM_HINTS property.
|
||||||
;; See <Xm/MwmUtil.h> for the definitions of these fields
|
|
||||||
(and exwm--mwm-hints
|
(and exwm--mwm-hints
|
||||||
exwm-instance-name
|
;; See <Xm/MwmUtil.h> for fields definitions.
|
||||||
(/= 0 (logand (elt exwm--mwm-hints 0) ;MotifWmHints.flags
|
(/= 0 (logand (elt exwm--mwm-hints 0) ;MotifWmHints.flags
|
||||||
2)) ;MWM_HINTS_DECORATIONS
|
2)) ;MWM_HINTS_DECORATIONS
|
||||||
(= 0 (elt exwm--mwm-hints 2)) ;MotifWmHints.decorations
|
(= 0 (elt exwm--mwm-hints 2)) ;MotifWmHints.decorations
|
||||||
;; Java applications only
|
|
||||||
(string-prefix-p "sun-awt-X11-" exwm-instance-name)
|
|
||||||
;; Floating windows only
|
;; Floating windows only
|
||||||
(or exwm-transient-for exwm--fixed-size
|
(or exwm-transient-for exwm--fixed-size
|
||||||
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY
|
(memq xcb:Atom:_NET_WM_WINDOW_TYPE_UTILITY
|
||||||
|
|
Loading…
Reference in a new issue