Christopher James Hayward
4 years ago
2 changed files with 150 additions and 117 deletions
-
117README.org
-
150modules/desktop.org
@ -0,0 +1,150 @@ |
|||
#+TITLE: Desktop |
|||
#+AUTHOR: Christopher James Hayward |
|||
#+EMAIL: chris@chrishayward.xyz |
|||
|
|||
#+PROPERTY: header-args:emacs-lisp :tangle desktop.el :comments org |
|||
#+PROPERTY: header-args :results silent :eval no-export :comments org |
|||
|
|||
#+OPTIONS: num:nil toc:nil todo:nil tasks:nil tags:nil |
|||
#+OPTIONS: skip:nil author:nil email:nil creator:nil timestamp:nil |
|||
|
|||
I use Emacs as a Desktop Environment with the *EXWM*[fn:1] https://github.com/ch11ng/exwm package. It allows Emacs to function as a complete tiling window manager for *X11*[fn:2]. |
|||
|
|||
* Startup |
|||
:PROPERTIES: |
|||
:header-args: :tangle ../config/xinitrc :comments org |
|||
:END: |
|||
|
|||
My workflow includes launching the window manager with *Xinit*[fn:3], without the use of a display manager, controlling *everything* within Emacs. |
|||
|
|||
#+begin_src conf |
|||
exec dbus-launch --exit-with-session emacs -mm --debug-init |
|||
#+end_src |
|||
|
|||
* Profile |
|||
:PROPERTIES: |
|||
:header-args: :tangle ../config/profile :comments org |
|||
:END: |
|||
|
|||
Ensure that ~~/.local/bin~ is added to the =$PATH= variable. |
|||
|
|||
#+begin_src shell |
|||
PATH=$PATH:~/.local/bin |
|||
export PATH |
|||
#+end_src |
|||
|
|||
When launching into a new session on ~TTY1~, if the display server is not running, run *StartX*[fn:3]. This will launch the window manager. |
|||
|
|||
#+begin_src shell |
|||
if [ -z "${DISPLAY}" ] && [ "${XDG_VTNR}" -eq 1 ]; then |
|||
exec startx |
|||
fi |
|||
#+end_src |
|||
|
|||
* Browser |
|||
|
|||
Write out the ~$BROWSER~ variable so other applications can pick up the custom browser. |
|||
|
|||
#+begin_src emacs-lisp |
|||
(setenv "BROWSER" dotfiles/browser) |
|||
#+end_src |
|||
|
|||
* Displays |
|||
|
|||
When the window manager first launches the ~init-hook~ executes, allowing us to define some custom logic. |
|||
|
|||
+ Display time and date |
|||
+ Display battery info (if available) |
|||
|
|||
In my personal configuration, I do not want the battery or time displayed within Emacs when it's not running as desktop environment because that information is typically already available. |
|||
|
|||
#+begin_src emacs-lisp |
|||
(defun dotfiles/init-hook () |
|||
(exwm-workspace-switch-create 1) |
|||
(setq display-time-and-date t) |
|||
(display-battery-mode 1) |
|||
(display-time-mode 1)) |
|||
#+end_src |
|||
|
|||
Using =autorandr= with pre configured profiles, switching screens (AKA hot plugging) is also handled through a hook. |
|||
|
|||
#+begin_src emacs-lisp |
|||
(defun dotfiles/update-display () |
|||
"Update the displays by forcing a change through autorandr." |
|||
(dotfiles/run-in-background "autorandr --change --force")) |
|||
#+end_src |
|||
|
|||
* Methods |
|||
|
|||
Define a method to run an external process, allowing us to launch any application on a new process without interferring with Emacs. |
|||
|
|||
#+begin_src emacs-lisp |
|||
(defun dotfiles/run (command) |
|||
"Run an external process." |
|||
(interactive (list (read-shell-command "λ "))) |
|||
(start-process-shell-command command nil command)) |
|||
#+end_src |
|||
|
|||
Apply methods to the current call process to avoid issues with hooks. |
|||
|
|||
#+begin_src emacs-lisp |
|||
(defun dotfiles/run-in-background (command) |
|||
(let ((command-parts (split-string command "[ ]+"))) |
|||
(apply #'call-process `(,(car command-parts) nil 0 nil ,@(cdr command-parts))))) |
|||
#+end_src |
|||
|
|||
Place keybindings for executing shell commands behind =SPC x=. |
|||
|
|||
+ Run shell commands with =x= |
|||
+ Run async shell commands with =z= |
|||
|
|||
#+begin_src emacs-lisp |
|||
(dotfiles/leader |
|||
"x" '(:ignore t :which-key "Run") |
|||
"xx" '(dotfiles/run :which-key "Run") |
|||
"xz" '(async-shell-command :which-key "Async")) |
|||
#+end_src |
|||
|
|||
* Initialization |
|||
|
|||
Connect our custom hooks and configure the input keys, a custom layer for key capture layers. |
|||
|
|||
+ Enable =randr= support |
|||
+ Pass through to Emacs |
|||
+ =M-x= to Emacs |
|||
+ =C-g= to Emacs |
|||
+ =C-SPC= to Emacs |
|||
+ Bindings with =S= (Super / Win) |
|||
+ Reset =S-r= |
|||
+ Launch =S-&= |
|||
+ Workspace =S-[1..9]= |
|||
|
|||
#+begin_src emacs-lisp |
|||
(use-package exwm |
|||
:custom (exwm-workspace-show-all-buffers t) |
|||
(exwm-input-prefix-keys |
|||
'(?\M-x |
|||
?\C-c |
|||
?\C-g |
|||
?\C-\ )) |
|||
(exwm-input-global-keys |
|||
`(([?\s-r] . exwm-reset) |
|||
,@(mapcar (lambda (i) |
|||
`(,(kbd (format "s-%d" i)) . |
|||
(lambda () |
|||
(interactive) |
|||
(exwm-workspace-switch-create ,i)))) |
|||
(number-sequence 1 9)))) |
|||
:config (require 'exwm-randr) |
|||
(exwm-randr-enable) |
|||
(add-hook 'exwm-init-hook #'dotfiles/init-hook) |
|||
(add-hook 'exwm-randr-screen-change-hook #'dotfiles/update-display) |
|||
(dotfiles/update-display) |
|||
(exwm-enable)) |
|||
#+end_src |
|||
|
|||
* Resources |
|||
|
|||
[fn:1] https://github.com/ch11ng/exwm |
|||
[fn:2] https://en.wikipedia.org/wiki/X_Window_System |
|||
[fn:3] https://en.wikipedia.org/wiki/Xinit |
Write
Preview
Loading…
Cancel
Save
Reference in new issue