Support focusing EXWM X-application buffers

Press `<M-escape.` to display a list of buffers hosting X applications. Use
`completing-read` to select and focus one of these.

See the function docs and TODOs for more information.
This commit is contained in:
William Carroll 2020-02-02 13:20:55 +00:00
parent 2e76601f70
commit 2cfcb1c34d
2 changed files with 31 additions and 5 deletions

View file

@ -17,6 +17,7 @@
(require 'ivy-clipmenu)
(require 'term-switcher)
(require 'general)
(require 'window-manager)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Configuration
@ -44,6 +45,8 @@
;; super. Remove this once I fix my Ergodox.
(keybinding/exwm "C-S-s-s" #'scrot/select)
(keybinding/exwm "<C-M-tab>" #'exwm/switch-to-exwm-buffer)
(general-define-key (kbd/raw 'x11 "t") #'ts/switch-to-terminal)
(provide 'keybindings)

View file

@ -27,6 +27,8 @@
(require 'dotfiles)
(require 'org-helpers)
(require 'vterm)
(require 'dash)
(require 'evil)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Library
@ -202,8 +204,6 @@
(:key "<M-tab>" :fn exwm/next-workspace)
(:key "<M-S-iso-lefttab>" :fn exwm/prev-workspace)
(:key "<M-iso-lefttab>" :fn exwm/prev-workspace)
;; <M-escape> doesn't work in X11 windows.
(:key "<M-escape>" :fn exwm/ivy-switch)
(:key "C-M-\\" :fn ivy-pass)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -331,8 +331,7 @@
"google-chrome --new-window --app=https://teknql.slack.com"
"google-chrome --new-window --app=https://web.whatsapp.com"
"google-chrome --new-window --app=https://irccloud.com"
exwm/preferred-browser
exwm/preferred-terminal)
exwm/preferred-browser)
"Applications that I commonly use.
These are the types of items that would usually appear in dmenu.")
@ -457,7 +456,7 @@ Currently using super- as the prefix for switching workspaces."
(interactive)
(exwm/change-workspace (cycle/focus-previous! exwm/workspaces)))
(defun exwm/ivy-switch ()
(defun exwm/switch-to-exwm-workspace ()
"Use ivy to switched between named workspaces."
(interactive)
(ivy-read
@ -466,6 +465,30 @@ Currently using super- as the prefix for switching workspaces."
(list/map #'exwm/named-workspace-label))
:action #'exwm/switch))
(defun exwm/exwm-buffer? (x)
"Return t if buffer X is an EXWM buffer."
(equal 'exwm-mode (buffer-local-value 'major-mode x)))
(defun exwm/application-name (buffer)
"Return the name of the application running in the EXWM BUFFER.
This function asssumes that BUFFER passes the `exwm/exwm-buffer?' predicate."
(with-current-buffer buffer exwm-class-name))
;; TODO: Support disambiguating between two or more instances of the same
;; application. For instance if two `exwm-class-name' values are
;; "Google-chrome", find a encode this information in the `buffer-alist'.
(defun exwm/switch-to-exwm-buffer ()
"Use `completing-read' to focus an EXWM buffer."
(interactive)
(let* ((buffer-alist (->> (buffer-list)
(-filter #'exwm/exwm-buffer?)
(-map (lambda (buffer)
(cons (exwm/application-name buffer)
buffer)))))
(label (completing-read "Switch to EXWM buffer: " buffer-alist)))
(exwm-workspace-switch-to-buffer
(alist-get label buffer-alist nil nil #'string=))))
(when exwm/install-workspace-kbds?
(progn
(->> exwm/named-workspaces