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:
Philip 2015-08-24 19:09:42 +00:00
parent 5882015eb5
commit 94bdbfc0da
4 changed files with 60 additions and 6 deletions

View file

@ -162,6 +162,34 @@
(setq exwm--fullscreen nil) (setq exwm--fullscreen nil)
(exwm-input-grab-keyboard))) (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 () (defun exwm-layout--refresh ()
"Refresh layout." "Refresh layout."
(let ((frame (selected-frame)) (let ((frame (selected-frame))

View file

@ -85,6 +85,12 @@
(setq geometry default-geometry (setq geometry default-geometry
output nil)) output nil))
(set-frame-parameter frame 'exwm-randr-output output) (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-x (elt geometry 0))
(set-frame-parameter frame 'exwm-y (elt geometry 1)) (set-frame-parameter frame 'exwm-y (elt geometry 1))
(xcb:+request exwm--connection (xcb:+request exwm--connection

View file

@ -231,13 +231,11 @@ The optional FORCE option is for internal use only."
(unless (frame-parameter i 'window-id) (unless (frame-parameter i 'window-id)
(setq exwm-workspace--list (delq i exwm-workspace--list))))) (setq exwm-workspace--list (delq i exwm-workspace--list)))))
(cl-assert (= 1 (length 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 ;; Create remaining frames
(dotimes (i (1- exwm-workspace-number)) (dotimes (i (1- exwm-workspace-number))
(nconc exwm-workspace--list (nconc exwm-workspace--list
(list (make-frame '((window-system . x) (fullscreen . fullboth)))))) (list (make-frame '((window-system . x)
(visibility . nil))))))
;; Configure workspaces ;; Configure workspaces
(dolist (i exwm-workspace--list) (dolist (i exwm-workspace--list)
(let ((window-id (string-to-int (frame-parameter i 'window-id))) (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 :window window-id :value-mask xcb:CW:EventMask
:event-mask xcb:EventMask:SubstructureRedirect)))) :event-mask xcb:EventMask:SubstructureRedirect))))
(xcb:flush exwm--connection) (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 ;; Handle unexpected frame switch
(add-hook 'focus-in-hook 'exwm-workspace--on-focus-in) (add-hook 'focus-in-hook 'exwm-workspace--on-focus-in)
;; Switch to the first workspace ;; Switch to the first workspace

18
exwm.el
View file

@ -441,6 +441,20 @@
(props (list (elt data 1) (elt data 2))) (props (list (elt data 1) (elt data 2)))
(buffer (exwm--id->buffer id)) (buffer (exwm--id->buffer id))
props-new) 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 (when buffer ;ensure it's managed
(with-current-buffer buffer (with-current-buffer buffer
;; _NET_WM_STATE_MODAL ;; _NET_WM_STATE_MODAL
@ -609,14 +623,14 @@
;; (xcb:icccm:init exwm--connection) ;; (xcb:icccm:init exwm--connection)
(xcb:ewmh:init exwm--connection) (xcb:ewmh:init exwm--connection)
(exwm--lock) (exwm--lock)
(exwm-workspace--init)
(exwm--init-icccm-ewmh) (exwm--init-icccm-ewmh)
(exwm-layout--init) (exwm-layout--init)
(exwm-floating--init) (exwm-floating--init)
(exwm-manage--init) (exwm-manage--init)
(exwm-input--init) (exwm-input--init)
(exwm--unlock) (exwm--unlock)
;; Manage exiting windows (exwm-workspace--init)
;; Manage existing windows
(exwm-manage--scan) (exwm-manage--scan)
(run-hooks 'exwm-init-hook))))) (run-hooks 'exwm-init-hook)))))