[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[elpa] externals/exwm 5184f0d: Work around subrs that block EXWM; other
From: |
Chris Feng |
Subject: |
[elpa] externals/exwm 5184f0d: Work around subrs that block EXWM; other minor fixes |
Date: |
Sun, 27 Sep 2015 11:43:36 +0000 |
branch: externals/exwm
commit 5184f0d7c1b540a6241904528d068dce288a911e
Author: Chris Feng <address@hidden>
Commit: Chris Feng <address@hidden>
Work around subrs that block EXWM; other minor fixes
Some subrs (e.g. x-file-dialog) create X windows and block the execution of
EXWM, so they won't work normally. This commit partly fixes this issue by
invoking them in a subordinate Emacs instance and trying to fetch the
result back.
* exwm.el (exwm-blocking-subrs): New variable for specify such subrs.
* exwm.el (exwm-enable, exwm--server-name, exwm--server-stop)
(exwm--server-eval-at): The implementation.
* exwm-core.el:
* exwm-floating.el:
* exwm-layout.el:
* exwm-manage.el:
* exwm-randr.el:
Evaluate constants at compile-time.
* README.md: Renamed from README.org to make the 'Commentary:' section
used by GNU ELPA instead.
* exwm.el: Depends on XELB version 0.3.
---
README.org => README.md | 9 +++--
exwm-core.el | 8 +++--
exwm-floating.el | 62 +++++++++++++++++++++---------------
exwm-layout.el | 47 +++++++++++++++------------
exwm-manage.el | 5 ++-
exwm-randr.el | 20 ++++++-----
exwm.el | 79 ++++++++++++++++++++++++++++++++++++++++++----
7 files changed, 158 insertions(+), 72 deletions(-)
diff --git a/README.org b/README.md
similarity index 52%
rename from README.org
rename to README.md
index 49ba04b..09fe470 100644
--- a/README.org
+++ b/README.md
@@ -1,7 +1,7 @@
-#+TITLE: Emacs X Window Manager
+# Emacs X Window Manager
EXWM (Emacs X Window Manager) is a full-featured tiling X window manager for
-Emacs built on top of [[https://github.com/ch11ng/xelb][XELB]].
+Emacs built on top of [XELB](https://github.com/ch11ng/xelb).
It features:
+ Fully keyboard-driven operation
+ Hybrid layout modes (tiling & stacking)
@@ -9,7 +9,8 @@ It features:
+ ICCCM/EWMH compliance
+ Basic RandR support (optional)
-Please check the [[https://github.com/ch11ng/exwm/wiki][User Guide]] for more
details.
+Please check the [User Guide](https://github.com/ch11ng/exwm/wiki)
+for more details.
-*Note*: If you install EXWM from source, you need to manually install XELB
+**Note**: If you install EXWM from source, you need to manually install XELB
(either from source or GNU ELPA).
diff --git a/exwm-core.el b/exwm-core.el
index 0f39c2d..1ac8678 100644
--- a/exwm-core.el
+++ b/exwm-core.el
@@ -69,12 +69,14 @@
(make-instance 'xcb:ChangeWindowAttributes
:window exwm--root
:value-mask xcb:CW:EventMask
- :event-mask (logior xcb:EventMask:StructureNotify
- xcb:EventMask:SubstructureRedirect)))
+ :event-mask (eval-when-compile
+ (logior xcb:EventMask:SubstructureRedirect
+ xcb:EventMask:StructureNotify))))
(xcb:flush exwm--connection))
(defconst exwm--client-event-mask
- (logior xcb:EventMask:StructureNotify xcb:EventMask:PropertyChange)
+ (eval-when-compile
+ (logior xcb:EventMask:StructureNotify xcb:EventMask:PropertyChange))
"Event mask set on all managed windows.")
;; Internal variables
diff --git a/exwm-floating.el b/exwm-floating.el
index 0994cb9..59b4e44 100644
--- a/exwm-floating.el
+++ b/exwm-floating.el
@@ -247,9 +247,10 @@ are provided. You should call `xcb:flush' and restore the
value of
:window (or frame-outer-id
(frame-parameter exwm--floating-frame
'exwm-outer-id))
- :value-mask (logior xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height
- xcb:ConfigWindow:StackMode)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height
+ xcb:ConfigWindow:StackMode))
:width (+ width (* 2 exwm-floating-border-width))
:height (+ height (* 2 exwm-floating-border-width)
(window-mode-line-height)
@@ -336,18 +337,20 @@ are provided. You should call `xcb:flush' and restore the
value of
exwm-floating--moveresize-calculate
`(lambda (x y)
(vector ,frame-id
- ,(logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y)
+ ,(eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y))
(- x ,win-x) (- y ,win-y) 0 0))))
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPLEFT)
(setq cursor exwm-floating--cursor-top-left
exwm-floating--moveresize-calculate
`(lambda (x y)
(vector ,frame-id
- ,(logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y
- xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ ,(eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
(- x ,win-x) (- y ,win-y)
(- ,(+ root-x width) x)
(- ,(+ root-y height) y)))))
@@ -356,17 +359,19 @@ are provided. You should call `xcb:flush' and restore the
value of
exwm-floating--moveresize-calculate
`(lambda (x y)
(vector ,frame-id
- ,(logior xcb:ConfigWindow:Y
- xcb:ConfigWindow:Height)
+ ,(eval-when-compile
+ (logior xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Height))
0 (- y ,win-y) 0 (- ,(+ root-y height) y)))))
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPRIGHT)
(setq cursor exwm-floating--cursor-top-right
exwm-floating--moveresize-calculate
`(lambda (x y)
(vector ,frame-id
- ,(logior xcb:ConfigWindow:Y
- xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ ,(eval-when-compile
+ (logior xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
0 (- y ,win-y) (- x ,(- root-x width))
(- ,(+ root-y height) y)))))
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_RIGHT)
@@ -380,8 +385,9 @@ are provided. You should call `xcb:flush' and restore the
value of
exwm-floating--moveresize-calculate
`(lambda (x y)
(vector ,frame-id
- ,(logior xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ ,(eval-when-compile
+ (logior xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
0 0 (- x ,(- root-x width))
(- y ,(- root-y height))))))
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOM)
@@ -396,9 +402,10 @@ are provided. You should call `xcb:flush' and restore the
value of
exwm-floating--moveresize-calculate
`(lambda (x y)
(vector ,frame-id
- ,(logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ ,(eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
(- x ,win-x)
0
(- ,(+ root-x width) x)
@@ -408,15 +415,17 @@ are provided. You should call `xcb:flush' and restore the
value of
exwm-floating--moveresize-calculate
`(lambda (x y)
(vector ,frame-id
- ,(logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Width)
+ ,(eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Width))
(- x ,win-x) 0 (- ,(+ root-x width) x) 0)))))
;; Select events and change cursor (should always succeed)
(xcb:+request-unchecked+reply exwm--connection
(make-instance 'xcb:GrabPointer
:owner-events 0 :grab-window frame-id
- :event-mask (logior xcb:EventMask:ButtonRelease
- xcb:EventMask:ButtonMotion)
+ :event-mask (eval-when-compile
+ (logior xcb:EventMask:ButtonRelease
+ xcb:EventMask:ButtonMotion))
:pointer-mode xcb:GrabMode:Async
:keyboard-mode xcb:GrabMode:Async
:confine-to xcb:Window:None
@@ -472,7 +481,7 @@ are provided. You should call `xcb:flush' and restore the
value of
(make-instance 'xcb:ConfigureWindow
:window (elt result 0) :value-mask (elt result 1)
:x (- (elt result 2) frame-x)
- :y (- (elt result 3) frame-y)
+ :y (- (elt result 3) frame-y)
:width (elt result 4) :height (elt result 5)))
(xcb:flush exwm--connection))))
@@ -492,8 +501,9 @@ Both DELTA-X and DELTA-Y default to 1. This command should
be bound locally."
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window id
- :value-mask (logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y))
:x (+ (slot-value geometry 'x) delta-x)
:y (+ (slot-value geometry 'y) delta-y)))
;; Inform the X window that its absolute position is changed
diff --git a/exwm-layout.el b/exwm-layout.el
index 4ccaef7..1d11dbc 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -56,11 +56,12 @@
(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
- xcb:ConfigWindow:StackMode)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height
+ xcb:ConfigWindow:StackMode))
:x x :y y :width width :height height
;; In order to put non-floating window at bottom
:stack-mode xcb:StackMode:Below))
@@ -122,10 +123,11 @@
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window outer-id
- :value-mask (logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y
- xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
:x 0 :y 0
:width (frame-pixel-width exwm-workspace--current)
:height (frame-pixel-height
@@ -134,10 +136,11 @@
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window exwm--id
- :value-mask (logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y
- xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
:x 0 :y 0
:width (frame-pixel-width exwm-workspace--current)
:height (frame-pixel-height exwm-workspace--current)))
@@ -161,10 +164,11 @@
(make-instance 'xcb:ConfigureWindow
:window (frame-parameter exwm--floating-frame
'exwm-outer-id)
- :value-mask (logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y
- xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
:x (elt exwm--floating-frame-geometry 0)
:y (elt exwm--floating-frame-geometry 1)
:width (elt exwm--floating-frame-geometry 2)
@@ -194,10 +198,11 @@
(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)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
:x x :y y
:width width
:height height))
diff --git a/exwm-manage.el b/exwm-manage.el
index d83fc44..ae707f7 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -124,8 +124,9 @@ corresponding buffer.")
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window id
- :value-mask (logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y))
:x (/ (- (frame-pixel-width
exwm-workspace--current)
width)
diff --git a/exwm-randr.el b/exwm-randr.el
index fc8477d..26d15dc 100644
--- a/exwm-randr.el
+++ b/exwm-randr.el
@@ -90,10 +90,11 @@
(xcb:+request exwm--connection
(make-instance 'xcb:ConfigureWindow
:window (frame-parameter frame 'exwm-outer-id)
- :value-mask (logior xcb:ConfigWindow:X
- xcb:ConfigWindow:Y
- xcb:ConfigWindow:Width
- xcb:ConfigWindow:Height)
+ :value-mask (eval-when-compile
+ (logior xcb:ConfigWindow:X
+ xcb:ConfigWindow:Y
+ xcb:ConfigWindow:Width
+ xcb:ConfigWindow:Height))
:x x :y y :width width :height height))
(setq workareas (nconc workareas (list x y width height))
viewports (nconc viewports (list x y))))))
@@ -133,11 +134,12 @@
(make-instance 'xcb:randr:SelectInput
:window exwm--root
:enable xcb:randr:NotifyMask:ScreenChange
- ;; :enable (logior
- ;; xcb:randr:NotifyMask:ScreenChange
- ;; xcb:randr:NotifyMask:OutputChange
- ;; xcb:randr:NotifyMask:OutputProperty
- ;; xcb:randr:NotifyMask:CrtcChange)
+ ;; :enable (eval-when-compile
+ ;; (logior
+ ;; xcb:randr:NotifyMask:ScreenChange
+ ;; xcb:randr:NotifyMask:OutputChange
+ ;; xcb:randr:NotifyMask:OutputProperty
+ ;; xcb:randr:NotifyMask:CrtcChange))
))
(xcb:flush exwm--connection)))))
diff --git a/exwm.el b/exwm.el
index d2a0ecf..b5d246e 100644
--- a/exwm.el
+++ b/exwm.el
@@ -5,7 +5,7 @@
;; Author: Chris Feng <address@hidden>
;; Maintainer: Chris Feng <address@hidden>
;; Version: 0
-;; Package-Requires: ((xelb "0.1"))
+;; Package-Requires: ((xelb "0.3"))
;; Keywords: unix
;; URL: https://github.com/ch11ng/exwm
@@ -74,6 +74,7 @@
;;; Code:
+(require 'server)
(require 'exwm-core)
(require 'exwm-workspace)
(require 'exwm-layout)
@@ -526,14 +527,78 @@
(exwm-manage--scan)
(run-hooks 'exwm-init-hook)))))
+(defvar exwm-blocking-subrs '(x-file-dialog x-popup-dialog x-select-font)
+ "Subrs (primitives) that would normally block EXWM.")
+
(defun exwm-enable (&optional undo)
"Enable/Disable EXWM."
- (if (eq undo 'undo)
- (progn (remove-hook 'window-setup-hook #'exwm-init)
- (remove-hook 'after-make-frame-functions #'exwm-init))
- (setq frame-resize-pixelwise t) ;mandatory; before init
- (add-hook 'window-setup-hook #'exwm-init t) ;for Emacs
- (add-hook 'after-make-frame-functions #'exwm-init t))) ;for Emacs Client
+ (pcase undo
+ (`undo ;prevent reinitialization
+ (remove-hook 'window-setup-hook #'exwm-init)
+ (remove-hook 'after-make-frame-functions #'exwm-init))
+ (`undo-all ;attempt to revert everything
+ (remove-hook 'window-setup-hook #'exwm-init)
+ (remove-hook 'after-make-frame-functions #'exwm-init)
+ (remove-hook 'kill-emacs-hook #'exwm--server-stop)
+ (dolist (i exwm-blocking-subrs)
+ (advice-remove i #'exwm--server-eval-at)))
+ (_ ;enable EXWM
+ (setq frame-resize-pixelwise t) ;mandatory; before init
+ (add-hook 'window-setup-hook #'exwm-init t) ;for Emacs
+ (add-hook 'after-make-frame-functions #'exwm-init t) ;for Emacs Client
+ (add-hook 'kill-emacs-hook #'exwm--server-stop)
+ (dolist (i exwm-blocking-subrs)
+ (advice-add i :around #'exwm--server-eval-at)))))
+
+(defconst exwm--server-name "server-exwm"
+ "Name of the subordinate Emacs server.")
+(defvar exwm--server-process nil "Process of the subordinate Emacs server.")
+
+(defun exwm--server-stop ()
+ "Stop the subordinate Emacs server."
+ (server-force-delete exwm--server-name)
+ (when exwm--server-process
+ (delete-process exwm--server-process)
+ (setq exwm--server-process nil)))
+
+(defun exwm--server-eval-at (&rest args)
+ "Wrapper of `server-eval-at' used to advice subrs."
+ ;; Start the subordinate Emacs server if it's not alive
+ (unless (server-running-p exwm--server-name)
+ (when exwm--server-process (delete-process exwm--server-process))
+ (setq exwm--server-process
+ (start-process exwm--server-name
+ nil
+ (car command-line-args) ;The executable file
+ "-d" x-display-name
+ "-Q"
+ (concat "--daemon=" exwm--server-name)
+ "--eval"
+ ;; Create an invisible frame
+ "(make-frame '((window-system . x) (visibility)))"))
+ (while (not (server-running-p exwm--server-name))
+ (sit-for 0.001)))
+ (server-eval-at
+ exwm--server-name
+ `(progn (select-frame (car (frame-list)))
+ (let ((result ,(nconc (list (make-symbol (subr-name (car args))))
+ (cdr args))))
+ (pcase (type-of result)
+ ;; Return the name of a buffer
+ (`buffer (buffer-name result))
+ ;; We blindly convert all font objects to their XLFD names. This
+ ;; might cause problems of course, but it still has a chance to
+ ;; work (whereas directly passing font objects would merely
+ ;; raise errors).
+ ((or `font-entity `font-object `font-spec)
+ (font-xlfd-name result))
+ ;; Passing following types makes little sense
+ ((or `compiled-function `finalizer `frame `hash-table `marker
+ `overlay `process `window `window-configuration))
+ ;; Passing the name of a subr
+ (`subr (make-symbol (subr-name result)))
+ ;; For other types, return the value as-is.
+ (t result))))))
(defun exwm--ido-buffer-window-other-frame (orig-fun buffer)
"Wrapper for `ido-buffer-window-other-frame' to exclude invisible windows."
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [elpa] externals/exwm 5184f0d: Work around subrs that block EXWM; other minor fixes,
Chris Feng <=