Avoid using the "no window manager" code in Emacs
* exwm.el (exwm--on-ClientMessage): Handle fullscreen requests for frames. (exwm-init): Initialize workspaces after unlocking events. * exwm-workspace.el (exwm-workspace--init): Create frames as invisible, then make them visible only once their OverrideRedirect property has been set. * exwm-randr.el (exwm-randr--refresh): New frame parameter `exwm-geometry'. * exwm-layout.el (exwm-layout--set-frame-fullscreen): New function. The Emacs code is buggy, see https://github.com/ch11ng/exwm/issues/39 https://github.com/ch11ng/exwm/pull/42
This commit is contained in:
parent
5882015eb5
commit
94bdbfc0da
4 changed files with 60 additions and 6 deletions
|
@ -162,6 +162,34 @@
|
|||
(setq exwm--fullscreen nil)
|
||||
(exwm-input-grab-keyboard)))
|
||||
|
||||
;; This function is superficially similar to `exwm-layout-set-fullscreen', but
|
||||
;; they do very different things: `exwm-layout--set-frame-fullscreen' resizes a
|
||||
;; frame to the actual monitor size, `exwm-layout-set-fullscreen' resizes an X
|
||||
;; window to the frame size.
|
||||
(defun exwm-layout--set-frame-fullscreen (frame)
|
||||
"Make frame FRAME fullscreen, with regard to its XRandR output if applicable."
|
||||
(let ((geometry (or (frame-parameter frame 'exwm-geometry)
|
||||
(xcb:+request-unchecked+reply
|
||||
exwm--connection
|
||||
(make-instance 'xcb:GetGeometry
|
||||
:drawable exwm--root))
|
||||
(make-instance 'xcb:RECTANGLE :x 0 :y 0
|
||||
:width (x-display-width)
|
||||
:height (x-display-height))))
|
||||
(id (frame-parameter frame 'exwm-outer-id)))
|
||||
(with-slots (x y width height) geometry
|
||||
(xcb:+request exwm--connection
|
||||
(make-instance 'xcb:ConfigureWindow
|
||||
:window id
|
||||
:value-mask (logior xcb:ConfigWindow:X
|
||||
xcb:ConfigWindow:Y
|
||||
xcb:ConfigWindow:Width
|
||||
xcb:ConfigWindow:Height)
|
||||
:x x :y y
|
||||
:width width
|
||||
:height height))
|
||||
(xcb:flush exwm--connection))))
|
||||
|
||||
(defun exwm-layout--refresh ()
|
||||
"Refresh layout."
|
||||
(let ((frame (selected-frame))
|
||||
|
|
|
@ -85,6 +85,12 @@
|
|||
(setq geometry default-geometry
|
||||
output nil))
|
||||
(set-frame-parameter frame 'exwm-randr-output output)
|
||||
(set-frame-parameter frame 'exwm-geometry
|
||||
(make-instance 'xcb:RECTANGLE
|
||||
:x (elt geometry 0)
|
||||
:y (elt geometry 1)
|
||||
:width (elt geometry 2)
|
||||
:height (elt geometry 3)))
|
||||
(set-frame-parameter frame 'exwm-x (elt geometry 0))
|
||||
(set-frame-parameter frame 'exwm-y (elt geometry 1))
|
||||
(xcb:+request exwm--connection
|
||||
|
|
|
@ -231,13 +231,11 @@ The optional FORCE option is for internal use only."
|
|||
(unless (frame-parameter i 'window-id)
|
||||
(setq exwm-workspace--list (delq i exwm-workspace--list)))))
|
||||
(cl-assert (= 1 (length exwm-workspace--list)))
|
||||
(exwm--make-emacs-idle-for 0.1) ;wait for the frame ready
|
||||
;; Configure the existing frame
|
||||
(set-frame-parameter (car exwm-workspace--list) 'fullscreen 'fullboth)
|
||||
;; Create remaining frames
|
||||
(dotimes (i (1- exwm-workspace-number))
|
||||
(nconc exwm-workspace--list
|
||||
(list (make-frame '((window-system . x) (fullscreen . fullboth))))))
|
||||
(list (make-frame '((window-system . x)
|
||||
(visibility . nil))))))
|
||||
;; Configure workspaces
|
||||
(dolist (i exwm-workspace--list)
|
||||
(let ((window-id (string-to-int (frame-parameter i 'window-id)))
|
||||
|
@ -256,6 +254,14 @@ The optional FORCE option is for internal use only."
|
|||
:window window-id :value-mask xcb:CW:EventMask
|
||||
:event-mask xcb:EventMask:SubstructureRedirect))))
|
||||
(xcb:flush exwm--connection)
|
||||
;; We have to delay making the frame visible until the
|
||||
;; override-redirect flag has been set.
|
||||
(select-frame-set-input-focus (car exwm-workspace--list))
|
||||
(dolist (i exwm-workspace--list)
|
||||
(set-frame-parameter i 'visibility t)
|
||||
(lower-frame i)
|
||||
(set-frame-parameter i 'fullscreen 'fullboth))
|
||||
(raise-frame (car exwm-workspace--list))
|
||||
;; Handle unexpected frame switch
|
||||
(add-hook 'focus-in-hook 'exwm-workspace--on-focus-in)
|
||||
;; Switch to the first workspace
|
||||
|
|
18
exwm.el
18
exwm.el
|
@ -441,6 +441,20 @@
|
|||
(props (list (elt data 1) (elt data 2)))
|
||||
(buffer (exwm--id->buffer id))
|
||||
props-new)
|
||||
;; only support _NET_WM_STATE_FULLSCREEN / _NET_WM_STATE_ADD for frames
|
||||
(when (and (not buffer)
|
||||
(memq xcb:Atom:_NET_WM_STATE_FULLSCREEN props)
|
||||
(= action xcb:ewmh:_NET_WM_STATE_ADD))
|
||||
(dolist (f exwm-workspace--list)
|
||||
(when (equal (frame-parameter f 'exwm-outer-id) id)
|
||||
(exwm-layout--set-frame-fullscreen f)
|
||||
(xcb:+request
|
||||
exwm--connection
|
||||
(make-instance 'xcb:ewmh:set-_NET_WM_STATE
|
||||
:window id
|
||||
:data (vector
|
||||
xcb:Atom:_NET_WM_STATE_FULLSCREEN)))
|
||||
(xcb:flush exwm--connection))))
|
||||
(when buffer ;ensure it's managed
|
||||
(with-current-buffer buffer
|
||||
;; _NET_WM_STATE_MODAL
|
||||
|
@ -609,14 +623,14 @@
|
|||
;; (xcb:icccm:init exwm--connection)
|
||||
(xcb:ewmh:init exwm--connection)
|
||||
(exwm--lock)
|
||||
(exwm-workspace--init)
|
||||
(exwm--init-icccm-ewmh)
|
||||
(exwm-layout--init)
|
||||
(exwm-floating--init)
|
||||
(exwm-manage--init)
|
||||
(exwm-input--init)
|
||||
(exwm--unlock)
|
||||
;; Manage exiting windows
|
||||
(exwm-workspace--init)
|
||||
;; Manage existing windows
|
||||
(exwm-manage--scan)
|
||||
(run-hooks 'exwm-init-hook)))))
|
||||
|
||||
|
|
Loading…
Reference in a new issue