mirror of
https://github.com/ch11ng/exwm.git
synced 2024-11-27 13:07:59 +01:00
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.
This commit is contained in:
parent
f685de12d4
commit
5184f0d7c1
7 changed files with 158 additions and 72 deletions
|
@ -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
|
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:
|
It features:
|
||||||
+ Fully keyboard-driven operation
|
+ Fully keyboard-driven operation
|
||||||
+ Hybrid layout modes (tiling & stacking)
|
+ Hybrid layout modes (tiling & stacking)
|
||||||
|
@ -9,7 +9,8 @@ It features:
|
||||||
+ ICCCM/EWMH compliance
|
+ ICCCM/EWMH compliance
|
||||||
+ Basic RandR support (optional)
|
+ 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).
|
(either from source or GNU ELPA).
|
|
@ -69,12 +69,14 @@
|
||||||
(make-instance 'xcb:ChangeWindowAttributes
|
(make-instance 'xcb:ChangeWindowAttributes
|
||||||
:window exwm--root
|
:window exwm--root
|
||||||
:value-mask xcb:CW:EventMask
|
:value-mask xcb:CW:EventMask
|
||||||
:event-mask (logior xcb:EventMask:StructureNotify
|
:event-mask (eval-when-compile
|
||||||
xcb:EventMask:SubstructureRedirect)))
|
(logior xcb:EventMask:SubstructureRedirect
|
||||||
|
xcb:EventMask:StructureNotify))))
|
||||||
(xcb:flush exwm--connection))
|
(xcb:flush exwm--connection))
|
||||||
|
|
||||||
(defconst exwm--client-event-mask
|
(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.")
|
"Event mask set on all managed windows.")
|
||||||
|
|
||||||
;; Internal variables
|
;; Internal variables
|
||||||
|
|
|
@ -247,9 +247,10 @@ are provided. You should call `xcb:flush' and restore the value of
|
||||||
:window (or frame-outer-id
|
:window (or frame-outer-id
|
||||||
(frame-parameter exwm--floating-frame
|
(frame-parameter exwm--floating-frame
|
||||||
'exwm-outer-id))
|
'exwm-outer-id))
|
||||||
:value-mask (logior xcb:ConfigWindow:Width
|
:value-mask (eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height
|
xcb:ConfigWindow:Height
|
||||||
xcb:ConfigWindow:StackMode)
|
xcb:ConfigWindow:StackMode))
|
||||||
:width (+ width (* 2 exwm-floating-border-width))
|
:width (+ width (* 2 exwm-floating-border-width))
|
||||||
:height (+ height (* 2 exwm-floating-border-width)
|
:height (+ height (* 2 exwm-floating-border-width)
|
||||||
(window-mode-line-height)
|
(window-mode-line-height)
|
||||||
|
@ -336,18 +337,20 @@ are provided. You should call `xcb:flush' and restore the value of
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,frame-id
|
(vector ,frame-id
|
||||||
,(logior xcb:ConfigWindow:X
|
,(eval-when-compile
|
||||||
xcb:ConfigWindow:Y)
|
(logior xcb:ConfigWindow:X
|
||||||
|
xcb:ConfigWindow:Y))
|
||||||
(- x ,win-x) (- y ,win-y) 0 0))))
|
(- x ,win-x) (- y ,win-y) 0 0))))
|
||||||
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPLEFT)
|
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPLEFT)
|
||||||
(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 ,frame-id
|
(vector ,frame-id
|
||||||
,(logior xcb:ConfigWindow:X
|
,(eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
(- x ,win-x) (- y ,win-y)
|
(- x ,win-x) (- y ,win-y)
|
||||||
(- ,(+ root-x width) x)
|
(- ,(+ root-x width) x)
|
||||||
(- ,(+ root-y height) y)))))
|
(- ,(+ root-y height) y)))))
|
||||||
|
@ -356,17 +359,19 @@ are provided. You should call `xcb:flush' and restore the value of
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,frame-id
|
(vector ,frame-id
|
||||||
,(logior xcb:ConfigWindow:Y
|
,(eval-when-compile
|
||||||
xcb:ConfigWindow:Height)
|
(logior xcb:ConfigWindow:Y
|
||||||
|
xcb:ConfigWindow:Height))
|
||||||
0 (- y ,win-y) 0 (- ,(+ root-y height) y)))))
|
0 (- y ,win-y) 0 (- ,(+ root-y height) y)))))
|
||||||
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPRIGHT)
|
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_TOPRIGHT)
|
||||||
(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 ,frame-id
|
(vector ,frame-id
|
||||||
,(logior xcb:ConfigWindow:Y
|
,(eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
0 (- y ,win-y) (- x ,(- root-x width))
|
0 (- y ,win-y) (- x ,(- root-x width))
|
||||||
(- ,(+ root-y height) y)))))
|
(- ,(+ root-y height) y)))))
|
||||||
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_RIGHT)
|
((= 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
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,frame-id
|
(vector ,frame-id
|
||||||
,(logior xcb:ConfigWindow:Width
|
,(eval-when-compile
|
||||||
xcb:ConfigWindow:Height)
|
(logior xcb:ConfigWindow:Width
|
||||||
|
xcb:ConfigWindow:Height))
|
||||||
0 0 (- x ,(- root-x width))
|
0 0 (- x ,(- root-x width))
|
||||||
(- y ,(- root-y height))))))
|
(- y ,(- root-y height))))))
|
||||||
((= type xcb:ewmh:_NET_WM_MOVERESIZE_SIZE_BOTTOM)
|
((= 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
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,frame-id
|
(vector ,frame-id
|
||||||
,(logior xcb:ConfigWindow:X
|
,(eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
(- x ,win-x)
|
(- x ,win-x)
|
||||||
0
|
0
|
||||||
(- ,(+ root-x width) x)
|
(- ,(+ root-x width) x)
|
||||||
|
@ -408,15 +415,17 @@ are provided. You should call `xcb:flush' and restore the value of
|
||||||
exwm-floating--moveresize-calculate
|
exwm-floating--moveresize-calculate
|
||||||
`(lambda (x y)
|
`(lambda (x y)
|
||||||
(vector ,frame-id
|
(vector ,frame-id
|
||||||
,(logior xcb:ConfigWindow:X
|
,(eval-when-compile
|
||||||
xcb:ConfigWindow:Width)
|
(logior xcb:ConfigWindow:X
|
||||||
|
xcb:ConfigWindow:Width))
|
||||||
(- x ,win-x) 0 (- ,(+ root-x width) x) 0)))))
|
(- x ,win-x) 0 (- ,(+ root-x width) x) 0)))))
|
||||||
;; 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 frame-id
|
:owner-events 0 :grab-window frame-id
|
||||||
:event-mask (logior xcb:EventMask:ButtonRelease
|
:event-mask (eval-when-compile
|
||||||
xcb:EventMask:ButtonMotion)
|
(logior xcb:EventMask:ButtonRelease
|
||||||
|
xcb:EventMask:ButtonMotion))
|
||||||
:pointer-mode xcb:GrabMode:Async
|
:pointer-mode xcb:GrabMode:Async
|
||||||
:keyboard-mode xcb:GrabMode:Async
|
:keyboard-mode xcb:GrabMode:Async
|
||||||
:confine-to xcb:Window:None
|
:confine-to xcb:Window:None
|
||||||
|
@ -492,8 +501,9 @@ Both DELTA-X and DELTA-Y default to 1. This command should be bound locally."
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window id
|
:window id
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
xcb:ConfigWindow:Y)
|
(logior xcb:ConfigWindow:X
|
||||||
|
xcb:ConfigWindow:Y))
|
||||||
:x (+ (slot-value geometry 'x) delta-x)
|
:x (+ (slot-value geometry 'x) delta-x)
|
||||||
:y (+ (slot-value geometry 'y) delta-y)))
|
:y (+ (slot-value geometry 'y) delta-y)))
|
||||||
;; Inform the X window that its absolute position is changed
|
;; Inform the X window that its absolute position is changed
|
||||||
|
|
|
@ -56,11 +56,12 @@
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window id
|
:window id
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height
|
xcb:ConfigWindow:Height
|
||||||
xcb:ConfigWindow:StackMode)
|
xcb:ConfigWindow:StackMode))
|
||||||
:x x :y y :width width :height height
|
:x x :y y :width width :height height
|
||||||
;; In order to put non-floating window at bottom
|
;; In order to put non-floating window at bottom
|
||||||
:stack-mode xcb:StackMode:Below))
|
:stack-mode xcb:StackMode:Below))
|
||||||
|
@ -122,10 +123,11 @@
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window outer-id
|
:window outer-id
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
:x 0 :y 0
|
:x 0 :y 0
|
||||||
:width (frame-pixel-width exwm-workspace--current)
|
:width (frame-pixel-width exwm-workspace--current)
|
||||||
:height (frame-pixel-height
|
:height (frame-pixel-height
|
||||||
|
@ -134,10 +136,11 @@
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window exwm--id
|
:window exwm--id
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
:x 0 :y 0
|
:x 0 :y 0
|
||||||
:width (frame-pixel-width exwm-workspace--current)
|
:width (frame-pixel-width exwm-workspace--current)
|
||||||
:height (frame-pixel-height exwm-workspace--current)))
|
:height (frame-pixel-height exwm-workspace--current)))
|
||||||
|
@ -161,10 +164,11 @@
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window (frame-parameter exwm--floating-frame
|
:window (frame-parameter exwm--floating-frame
|
||||||
'exwm-outer-id)
|
'exwm-outer-id)
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
:x (elt exwm--floating-frame-geometry 0)
|
:x (elt exwm--floating-frame-geometry 0)
|
||||||
:y (elt exwm--floating-frame-geometry 1)
|
:y (elt exwm--floating-frame-geometry 1)
|
||||||
:width (elt exwm--floating-frame-geometry 2)
|
:width (elt exwm--floating-frame-geometry 2)
|
||||||
|
@ -194,10 +198,11 @@
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window id
|
:window id
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
:x x :y y
|
:x x :y y
|
||||||
:width width
|
:width width
|
||||||
:height height))
|
:height height))
|
||||||
|
|
|
@ -124,8 +124,9 @@ corresponding buffer.")
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window id
|
:window id
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
xcb:ConfigWindow:Y)
|
(logior xcb:ConfigWindow:X
|
||||||
|
xcb:ConfigWindow:Y))
|
||||||
:x (/ (- (frame-pixel-width
|
:x (/ (- (frame-pixel-width
|
||||||
exwm-workspace--current)
|
exwm-workspace--current)
|
||||||
width)
|
width)
|
||||||
|
|
|
@ -90,10 +90,11 @@
|
||||||
(xcb:+request exwm--connection
|
(xcb:+request exwm--connection
|
||||||
(make-instance 'xcb:ConfigureWindow
|
(make-instance 'xcb:ConfigureWindow
|
||||||
:window (frame-parameter frame 'exwm-outer-id)
|
:window (frame-parameter frame 'exwm-outer-id)
|
||||||
:value-mask (logior xcb:ConfigWindow:X
|
:value-mask (eval-when-compile
|
||||||
|
(logior xcb:ConfigWindow:X
|
||||||
xcb:ConfigWindow:Y
|
xcb:ConfigWindow:Y
|
||||||
xcb:ConfigWindow:Width
|
xcb:ConfigWindow:Width
|
||||||
xcb:ConfigWindow:Height)
|
xcb:ConfigWindow:Height))
|
||||||
:x x :y y :width width :height height))
|
:x x :y y :width width :height height))
|
||||||
(setq workareas (nconc workareas (list x y width height))
|
(setq workareas (nconc workareas (list x y width height))
|
||||||
viewports (nconc viewports (list x y))))))
|
viewports (nconc viewports (list x y))))))
|
||||||
|
@ -133,11 +134,12 @@
|
||||||
(make-instance 'xcb:randr:SelectInput
|
(make-instance 'xcb:randr:SelectInput
|
||||||
:window exwm--root
|
:window exwm--root
|
||||||
:enable xcb:randr:NotifyMask:ScreenChange
|
:enable xcb:randr:NotifyMask:ScreenChange
|
||||||
;; :enable (logior
|
;; :enable (eval-when-compile
|
||||||
|
;; (logior
|
||||||
;; xcb:randr:NotifyMask:ScreenChange
|
;; xcb:randr:NotifyMask:ScreenChange
|
||||||
;; xcb:randr:NotifyMask:OutputChange
|
;; xcb:randr:NotifyMask:OutputChange
|
||||||
;; xcb:randr:NotifyMask:OutputProperty
|
;; xcb:randr:NotifyMask:OutputProperty
|
||||||
;; xcb:randr:NotifyMask:CrtcChange)
|
;; xcb:randr:NotifyMask:CrtcChange))
|
||||||
))
|
))
|
||||||
(xcb:flush exwm--connection)))))
|
(xcb:flush exwm--connection)))))
|
||||||
|
|
||||||
|
|
73
exwm.el
73
exwm.el
|
@ -5,7 +5,7 @@
|
||||||
;; Author: Chris Feng <chris.w.feng@gmail.com>
|
;; Author: Chris Feng <chris.w.feng@gmail.com>
|
||||||
;; Maintainer: Chris Feng <chris.w.feng@gmail.com>
|
;; Maintainer: Chris Feng <chris.w.feng@gmail.com>
|
||||||
;; Version: 0
|
;; Version: 0
|
||||||
;; Package-Requires: ((xelb "0.1"))
|
;; Package-Requires: ((xelb "0.3"))
|
||||||
;; Keywords: unix
|
;; Keywords: unix
|
||||||
;; URL: https://github.com/ch11ng/exwm
|
;; URL: https://github.com/ch11ng/exwm
|
||||||
|
|
||||||
|
@ -74,6 +74,7 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
|
(require 'server)
|
||||||
(require 'exwm-core)
|
(require 'exwm-core)
|
||||||
(require 'exwm-workspace)
|
(require 'exwm-workspace)
|
||||||
(require 'exwm-layout)
|
(require 'exwm-layout)
|
||||||
|
@ -526,14 +527,78 @@
|
||||||
(exwm-manage--scan)
|
(exwm-manage--scan)
|
||||||
(run-hooks 'exwm-init-hook)))))
|
(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)
|
(defun exwm-enable (&optional undo)
|
||||||
"Enable/Disable EXWM."
|
"Enable/Disable EXWM."
|
||||||
(if (eq undo 'undo)
|
(pcase undo
|
||||||
(progn (remove-hook 'window-setup-hook #'exwm-init)
|
(`undo ;prevent reinitialization
|
||||||
|
(remove-hook 'window-setup-hook #'exwm-init)
|
||||||
(remove-hook 'after-make-frame-functions #'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
|
(setq frame-resize-pixelwise t) ;mandatory; before init
|
||||||
(add-hook 'window-setup-hook #'exwm-init t) ;for Emacs
|
(add-hook 'window-setup-hook #'exwm-init t) ;for Emacs
|
||||||
(add-hook 'after-make-frame-functions #'exwm-init t))) ;for Emacs Client
|
(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)
|
(defun exwm--ido-buffer-window-other-frame (orig-fun buffer)
|
||||||
"Wrapper for `ido-buffer-window-other-frame' to exclude invisible windows."
|
"Wrapper for `ido-buffer-window-other-frame' to exclude invisible windows."
|
||||||
|
|
Loading…
Reference in a new issue