INTELLIGENTLY HANDLE FIREFOX WINDOWS

This commit is contained in:
Benson Chu 2023-09-01 07:05:36 +08:00
parent 5e24cc2b8e
commit afbacc8952
3 changed files with 184 additions and 75 deletions

View file

@ -1,17 +1,8 @@
(:command "firefox" :alias "Navigator" :pretty-name "firefox3" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "8ae6552419703180476fa4387f9cf8b9")
(:command "steam" :alias "steamwebhelper" :pretty-name "steam" :paste-key "C-v" :class "steam" :instance "steamwebhelper" :title "Steam" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "5cae6843e6081ff23f80b1a7c8821595")
(:command "pcmanfm" :alias "pcmanfm" :pretty-name "pcmanfm" :paste-key "C-v" :class "Pcmanfm" :instance "pcmanfm" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "50e978cd291dcc11f145ca5835193ae1")
(:command "firefox" :alias "Navigator" :pretty-name "firefox" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c2bee0373d986f9561845a4e1ae0374d")
(:command "firefox" :alias "Navigator" :pretty-name "firefox1" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "15f370a4572c4a0b89c8146f0c6c5ffe")
(:command firefox :alias "Navigator" :pretty-name "firefox" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c2bee0373d986f9561845a4e1ae0374d")
(:command "discord" :alias "discord" :pretty-name "discord" :paste-key "C-v" :class "discord" :instance "discord" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "4ad4943e4fc9da6b8421dbd655ac09ec")
(:command "clementine" :alias "clementine" :pretty-name "clementine" :paste-key "C-v" :class "Clementine" :instance "clementine" :title "Takeshi Abo - First leap" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "6d1a0cd2fd349b32c844ad096ceaa529")
(:command "VirtualBox Machine" :alias "VirtualBox Machine" :pretty-name "VirtualBox Machine" :paste-key "C-v" :class "VirtualBox Machine" :instance "VirtualBox Machine" :title "Windows 7 [Running] - Oracle VM VirtualBox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "9032cdf6364297438c1892d892122db3")
(:command "qutebrowser" :alias "qutebrowser" :pretty-name "qutebrowser" :paste-key "C-v" :class "qutebrowser" :instance "qutebrowser" :title "DuckDuckGo — Privacy, simplified. - qutebrowser" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "5a90ddb8976a59d030137fc4414e2918")
(:command "emacs" :alias "emacs" :pretty-name "emacs" :paste-key "C-v" :class "Emacs" :instance "emacs" :title "emacs@ArchLinuvo" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys t :ignore-simulation-keys nil :eval nil :key "d174de6e20bb093cb298146666b92ac1")
(:command "Navigator" :alias "Navigator" :pretty-name "Navigator" :paste-key "C-v" :class "Firefox" :instance "Navigator" :title "mkropat/jumpapp: A run-or-raise application switcher for any X11 desktop - Mozilla Firefox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "b5686ca42c47fd5dec0b9efe8739ce94")
(:command "work" :alias "work" :pretty-name "work" :paste-key "C-v" :class "Firefox" :instance "work" :title "Pocket: Log In - Mozilla Firefox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "ca58c8720d794df8d0b88c6dceea8c69")
(:command "steam" :alias "Steam" :pretty-name "Steam" :paste-key "C-v" :class "Steam" :instance "Steam" :title "Steam" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "a68f5a036e9cd3dd4c8ae09a73f8d3db")
(:command "mgtv" :alias "mgtv" :pretty-name "mgtv" :paste-key "C-v" :class "mgtv" :instance "mgtv" :title "哆啦A梦第二季 第70集 - 视频在线观看 - 哆啦A梦 第二季 - 芒果TV - Mozilla Firefox" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "618647de63882e1c4e7209cd22bea289")
(:command "lutris" :alias "lutris" :pretty-name "lutris" :paste-key "C-v" :class "Lutris" :instance "lutris" :title "Lutris" :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "d5f5f739289cc9c6286881ecd659d2a5")
(:command "pcmanfm" :alias nil :pretty-name "pcmanfm" :paste-key "C-v" :class "Pcmanfm" :instance "pcmanfm" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "50e978cd291dcc11f145ca5835193ae1")
(:command "firefox" :alias "Navigator" :pretty-name "firefox" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "61fd33ff3615b1e582accf4eba6ff1ee")
(:command firefox :alias "Navigator" :pretty-name "youtube" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c1d685634c050571eb12fba803934e74")
(:command "firefox" :alias "Navigator" :pretty-name "firefox2" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "83cf4fcff6f07dd334aabe6207f087b0")
(:command "firefox" :alias "Navigator" :pretty-name "firefox2" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "61fd33ff3615b1e582accf4eba6ff1ee")
(:command "firefox" :alias "Navigator" :pretty-name "firefox3" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "8ae6552419703180476fa4387f9cf8b9")
(:command "firefox" :alias "Navigator" :pretty-name "youtube" :paste-key "C-v" :class "firefox" :instance "Navigator" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "c1d685634c050571eb12fba803934e74")
(:command "discord" :alias "discord" :pretty-name "discord" :paste-key "C-v" :class "discord" :instance "discord" :title nil :floating nil :size-and-position default :workspace current-workspace :add-prefix-keys nil :remove-prefix-keys nil :ignore-simulation-keys nil :eval nil :key "08b13f35d50cd2e97ed836ad38b6bead")

View file

@ -32,30 +32,40 @@
(interactive)
(shell-command "~/Github/my-projects/i3lock-fancy/i3lock-fancy & disown"))
(defun exwmx-name-buffer (name)
(interactive
(list
(completing-read "Name: "
(mapcar (lambda (a) (plist-get a :pretty-name))
(exwmx-appconfig--get-all-appconfigs)))))
(cl-labels ((name-pretty (buffer name)
(with-current-buffer buffer
(exwm-workspace-rename-buffer name)
(setq-local exwmx-pretty-name name))))
(if (equal name (buffer-name))
(setq-local exwmx-pretty-name name)
(let ((obuffer (get-buffer name)))
(if (not obuffer)
(name-pretty (current-buffer) name)
(when (y-or-n-p (format "Already a buffer named \"%s\". Would you like to swap?" name))
(let ((oname (completing-read "Name of other buffer: "
(mapcar (lambda (a) (plist-get a :instance))
(exwmx-appconfig--get-all-appconfigs)))))
(name-pretty (current-buffer)
"This is a stupid name that no one would ever choose for a buffer, hopefully")
(name-pretty obuffer oname)
(name-pretty (current-buffer)
name))))))))
(defun exwmx-prompt-pretty-name (prompt appconfigs)
(completing-read
prompt
(mapcar (lambda (a) (plist-get a :pretty-name))
appconfigs)))
(defun exwmx-name-buffer (&optional name buffer appconfigs)
(interactive)
(setq appconfigs (or appconfigs (exwmx-appconfig--get-all-appconfigs))
buffer (or buffer (current-buffer))
name (or name (exwmx-prompt-pretty-name "Name: " appconfigs)))
(with-current-buffer buffer
(cl-labels ((name-pretty (buffer name)
(with-current-buffer buffer
(exwm-workspace-rename-buffer name)
(setq-local exwmx-pretty-name name))
name))
(if (equal name (buffer-name))
(setq-local exwmx-pretty-name name)
(let ((obuffer (get-buffer name)))
(if (not obuffer)
(name-pretty (current-buffer) name)
(if (not (y-or-n-p (format "Already a buffer named \"%s\". Would you like to swap?" name)))
exwmx-pretty-name
(let ((oname (exwmx-prompt-pretty-name
"Name of other buffer: "
(remove-if #'(lambda (x)
(string= name (plist-get x :pretty-name)))
appconfigs))))
(name-pretty (current-buffer)
"This is a stupid name that no one would ever choose for a buffer, hopefully")
(name-pretty obuffer oname)
(name-pretty (current-buffer)
name)))))))))
;; Add these hooks in a suitable place (e.g., as done in exwm-config-default)
@ -91,16 +101,25 @@
(define-prefix-command '*firefox-map*)
(define-key *root-map* (kbd "f") '*firefox-map*)
(defmacro quickrun-firefox (command tag)
(let ((name-gensym (intern (format "quickrun-comm-%s"
(or tag command)))))
`(defun ,name-gensym ()
(interactive)
(if (zerop (length (exwmx-find-buffers '(:class "firefox"))))
(exwmx/launch-firefox-windows)
(my/exwmx-quickrun ,command nil '(:pretty-name ,tag))))))
(define-key *firefox-map* (kbd "c") (quickrun-lambda "google-chrome-stable" "chrome"))
(define-key *firefox-map* (kbd "f") (quickrun-lambda "firefox" "firefox"))
(define-key *firefox-map* (kbd "1") (quickrun-lambda "firefox" "firefox1"))
(define-key *firefox-map* (kbd "2") (quickrun-lambda "firefox" "firefox2"))
(define-key *firefox-map* (kbd "3") (quickrun-lambda "firefox" "firefox3"))
(define-key *firefox-map* (kbd "4") (quickrun-lambda "firefox" "firefox4"))
(define-key *firefox-map* (kbd "d") (quickrun-lambda "firefox" "development"))
(define-key *firefox-map* (kbd "s") (quickrun-lambda "firefox" "school"))
(define-key *firefox-map* (kbd "w") (quickrun-lambda "firefox" "work"))
(define-key *firefox-map* (kbd "y") (quickrun-lambda "firefox" "youtube"))
(define-key *firefox-map* (kbd "f") (quickrun-firefox "firefox" "firefox"))
(define-key *firefox-map* (kbd "1") (quickrun-firefox "firefox" "firefox1"))
(define-key *firefox-map* (kbd "2") (quickrun-firefox "firefox" "firefox2"))
(define-key *firefox-map* (kbd "3") (quickrun-firefox "firefox" "firefox3"))
(define-key *firefox-map* (kbd "4") (quickrun-firefox "firefox" "firefox4"))
(define-key *firefox-map* (kbd "d") (quickrun-firefox "firefox" "development"))
(define-key *firefox-map* (kbd "s") (quickrun-firefox "firefox" "school"))
(define-key *firefox-map* (kbd "w") (quickrun-firefox "firefox" "work"))
(define-key *firefox-map* (kbd "y") (quickrun-firefox "firefox" "youtube"))
;; Musics
(define-prefix-command '*music-map*)

View file

@ -101,7 +101,28 @@ or use `exwmx-appconfig-ignore' ignore."
(or (not title) (exwmx--string-match-p instance exwm-title))
(or (not pretty) (exwmx--string-match-p (format "^%s$" pretty) exwmx-pretty-name))))))
(defun exwmx-find-buffer (appconfig)
(defun exwmx-buffer-match-alist (alist buffer)
(cl-assert
(eq 'exwm-mode
(with-current-buffer buffer
major-mode)))
(with-current-buffer buffer
(-every
(lambda (rule)
(let* ((key (nth 0 rule))
(search-string (nth 1 rule))
(test-function (or (nth 2 rule) #'equal))
(prop-value
(pcase key
(:class exwm-class-name)
(:instance exwm-instance-name)
(:title exwm-title)
(:pretty-name exwmx-pretty-name))))
(and (functionp test-function)
(funcall test-function search-string prop-value))))
alist)))
(defun exwmx-find-buffer (appconfig &optional alist)
(let ((current (current-buffer))
(buffers (buffer-list))
(result '()))
@ -109,7 +130,9 @@ or use `exwmx-appconfig-ignore' ignore."
(let ((buffer (pop buffers)))
(when (and (eq 'exwm-mode (with-current-buffer buffer
major-mode))
(exwmx-buffer-match-p appconfig buffer))
(if alist
(exwmx-buffer-match-alist appconfig buffer)
(exwmx-buffer-match-p appconfig buffer)))
(push buffer result))))
(setq result (reverse result))
;; If two more buffers are found, switch between these buffer.
@ -118,7 +141,19 @@ or use `exwmx-appconfig-ignore' ignore."
(cadr result)
(car result))))
(exwmx-find-buffer '(:pretty-name "firefox"))
(defun exwmx-find-buffers (appconfig &optional alist)
(let ((current (current-buffer))
(buffers (buffer-list))
(result '()))
(while buffers
(let ((buffer (pop buffers)))
(when (and (eq 'exwm-mode (with-current-buffer buffer
major-mode))
(if alist
(exwmx-buffer-match-alist appconfig buffer)
(exwmx-buffer-match-p appconfig buffer)))
(push buffer result))))
(reverse result)))
(defun exwmx-select-window ()
(if (= 1 (length (window-list)))
@ -129,7 +164,7 @@ or use `exwmx-appconfig-ignore' ignore."
until (= c index)
finally return win))))
(defun my/exwmx-quickrun (command &optional search-alias ruler)
(defun my/exwmx-quickrun (command &optional search-alias ruler no-manage)
"Run `command' to launch an application, if application's window is found,
just switch to this window, when `search-alias' is t, `command' will be regard
as an appconfig alias and search it from `exwmx-appconfig-file', by default,
@ -171,8 +206,9 @@ and :title or just a key list."
(let ((exwm-layout-show-all-buffers nil))
(exwm-workspace-switch-to-buffer buffer))
(when cmd
(exwmx-register-x-window
matched-appconfig (exwmx-select-window))
(when (not no-manage)
(exwmx-register-x-window
matched-appconfig (exwmx-select-window)))
(exwmx-shell-command cmd)))))
(defmacro quickrun-lambda (cmd name)
@ -252,26 +288,89 @@ and :title or just a key list."
`((:class ,exwm-class-name))))
(defun exwmx-manage-x-window ()
(if-let* ((appconfigs (exwmx-appconfig-candidates))
(matched-config
(-any (lambda (c) (and (gethash c exwmx/destination-windows)
c))
appconfigs))
(name (plist-get matched-config :pretty-name))
(window (gethash matched-config exwmx/destination-windows)))
(unwind-protect
(progn
(exwm-workspace-rename-buffer name)
(when (and (window-live-p window)
(not (eq window (selected-window))))
(let ((curr (current-buffer)))
(save-selected-window
(previous-buffer)
(window--display-buffer curr window 'reuse nil)))))
(setq-local exwmx-pretty-name name)
(remhash matched-config exwmx/destination-windows))
(exwm-workspace-rename-buffer
(or exwm-class-name exwm-instance-name exwm-title))))
(when (not (member #'exwmx/add-firefox-buffers exwm-manage-finish-hook))
(if-let* ((appconfigs (exwmx-appconfig-candidates))
(matched-config
(-any (lambda (c) (and (gethash c exwmx/destination-windows)
c))
appconfigs))
(name (plist-get matched-config :pretty-name))
(window (gethash matched-config exwmx/destination-windows)))
(unwind-protect
(progn
(exwm-workspace-rename-buffer name)
(when (and (window-live-p window)
(not (eq window (selected-window))))
(let ((curr (current-buffer)))
(save-selected-window
(previous-buffer)
(window--display-buffer curr window 'reuse nil)))))
(setq-local exwmx-pretty-name name)
(remhash matched-config exwmx/destination-windows))
(exwm-workspace-rename-buffer
(or exwm-class-name exwm-instance-name exwm-title)))))
(defvar exwmx/firefox-buffers nil)
(defvar exwmx/buffer-name-timer nil)
(defun exwmx/launch-firefox-windows ()
(interactive)
(unless (zerop (length (exwmx-find-buffers '(:class "firefox"))))
(user-error "Firefox already launched"))
(add-hook 'exwm-manage-finish-hook #'exwmx/add-firefox-buffers)
(my/exwmx-quickrun "firefox" nil nil t))
(defun exwmx/add-firefox-buffers ()
(push (current-buffer) exwmx/firefox-buffers)
(when (timerp exwmx/buffer-name-timer)
(cancel-timer exwmx/buffer-name-timer))
(setq exwmx/buffer-name-timer
(run-at-time 3 nil #'exwmx/rename-firefox-windows)))
;; (setq exwm-manage-finish-hook
;; (delq #'exwmx/add-firefox-buffers exwm-manage-finish-hook))
(defun display-buffers-split-vertically (lob)
(delete-other-windows)
(let ((last (car (last lob))))
(dolist (b lob)
(display-buffer-same-window b nil)
(unless (eq b last)
(select-window (split-window-vertically)))))
(balance-windows))
(defun exwmx/rename-firefox-windows ()
(unwind-protect
(save-window-excursion
(let ((appconfigs (exwmx-appconfig--search-all '((:class "firefox")))))
(when-let ((b (exwmx-find-buffer '((:title "YouTube" string-match-p)) t)))
(when (member b exwmx/firefox-buffers)
(exwmx-name-buffer "youtube" b )
(setq exwmx/firefox-buffers
(delete b exwmx/firefox-buffers))
(setq appconfigs
(remove-if #'(lambda (x)
(string= "youtube" (plist-get x :pretty-name)))
appconfigs))))
(if (= 1 (length exwmx/firefox-buffers))
(exwmx-name-buffer "firefox" (car exwmx/firefox-buffers))
(delete-other-windows)
(let ((last (car (last exwmx/firefox-buffers))))
(display-buffers-split-vertically exwmx/firefox-buffers)
(dolist (b exwmx/firefox-buffers)
(let ((win (get-buffer-window b)))
(select-window win)
(-->
(funcall-interactively #'exwmx-name-buffer nil b appconfigs)
(setq appconfigs
(remove-if #'(lambda (x)
(string= it
(plist-get x :pretty-name)))
appconfigs)))
(unless (eq b last)
(delete-window win))))))))
(remove-hook 'exwm-manage-finish-hook #'exwmx/add-firefox-buffers)
(setq exwmx/firefox-buffers nil)))
(add-hook 'exwm-manage-finish-hook 'exwmx-manage-x-window)