-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use wmctrl to re-pop-up frames which are only visible on other virtua…
…l desktops Fixes #2
- Loading branch information
1 parent
eb5bdb7
commit cbce743
Showing
5 changed files
with
151 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,7 @@ | |
|
||
;; Author: David Shepherd <[email protected]> | ||
;; Version: 1.0.0 | ||
;; Package-Requires: ((emacs "24.4") (dash "2.13.0")) | ||
;; Package-Requires: ((emacs "24.4") (dash "2.13.0") (s "1.11.0")) | ||
;; Keywords: frames, windows | ||
;; URL: https://github.com/davidshepherd7/frames-only-mode | ||
|
||
|
@@ -14,6 +14,7 @@ | |
;;; Code: | ||
|
||
(require 'dash) | ||
(require 's) | ||
|
||
|
||
|
||
|
@@ -99,6 +100,20 @@ mode please open an issue at https://github.com/davidshepherd7/frames-only-mode/ | |
to let me know." | ||
:group 'frames-only-mode) | ||
|
||
(defcustom frames-only-mode-reopen-frames-from-hidden-x11-virtual-desktops | ||
;; TODO: enable by default when this has had a bit more testing | ||
;; (not (null (and (eq window-system 'x) | ||
;; (executable-find "wmctrl")))) | ||
nil | ||
"When a frame is visible on a hidden virtual desktop, open a new copy of the frame. | ||
This will only work under X11 and when you have the wmctrl binary | ||
available on your path (you can probably install wmctrl from your | ||
operating system's package manager). | ||
It's a bit of a hack, so there may be some issues." | ||
:group 'frames-only-mode) | ||
|
||
|
||
|
||
(defun frames-only-mode-revertable-set (var-vals) | ||
|
@@ -198,6 +213,46 @@ Only if there are no other windows in the frame, and if the buffer is in frames- | |
(defun frames-only-mode-flycheck-display-errors (errors) | ||
(message "%s" (mapcar 'flycheck-error-format-message-and-id errors))) | ||
|
||
|
||
|
||
|
||
;;; Interactions with wmctrl | ||
|
||
(defun frames-only-mode--call-process (process &rest args) | ||
"Call a process with sensible error handling and output to a string" | ||
(with-output-to-string | ||
(let* ((exit-code (apply #'call-process process nil standard-output nil args))) | ||
(when (not (equal exit-code 0)) | ||
(error "Process %s %s exited with error code %s" process args exit-code))))) | ||
|
||
(defun frames-only-mode--x-current-desktop () | ||
"Get the number of the X11 desktop which is visible" | ||
(--> (frames-only-mode--call-process "wmctrl" "-d") | ||
(s-split "\n" it) | ||
(--map (split-string it "\\s-+") it) | ||
(--first (equal (nth 1 it) "*") it) | ||
(car it))) | ||
|
||
(defun frames-only-mode--x-visible-window-names () | ||
"Get a list of X11 windows which are on the visible desktop." | ||
(let ((current-desktop (frames-only-mode--x-current-desktop))) | ||
(--> (frames-only-mode--call-process "wmctrl" "-l") | ||
(s-split "\n" it) | ||
(--map (s-split-up-to "\\s-+" it 3) it) | ||
(--filter (equal (nth 1 it) current-desktop) it) | ||
(--map (nth 3 it) it)))) | ||
|
||
(defun frames-only-mode--x-buffer-window-visible (buffer-name) | ||
"Check buffer is currently displayed on a visible X11 virtual desktop." | ||
(--some (equal it buffer-name) | ||
(frames-only-mode--x-visible-window-names))) | ||
|
||
(defun frames-only-mode--display-buffer-fn (buffer property-alist) | ||
"See `frames-only-mode-reopen-frames-from-hidden-x11-virtual-desktops'." | ||
(when (and frames-only-mode-reopen-frames-from-hidden-x11-virtual-desktops | ||
(not (frames-only-mode--x-buffer-window-visible (buffer-name buffer)))) | ||
(display-buffer-pop-up-frame buffer property-alist))) | ||
|
||
|
||
|
||
(defvar frames-only-mode-mode-map | ||
|
@@ -243,7 +298,16 @@ Only if there are no other windows in the frame, and if the buffer is in frames- | |
;; Make sure completions buffer is buried after we are done with the minibuffer | ||
(if frames-only-mode | ||
(add-hook 'minibuffer-exit-hook #'frames-only-mode-bury-completions) | ||
(remove-hook 'minibuffer-exit-hook #'frames-only-mode-bury-completions))) | ||
(remove-hook 'minibuffer-exit-hook #'frames-only-mode-bury-completions)) | ||
|
||
;; Set up hacks to pop up new frames for buffers when they are displayed on a | ||
;; virtual desktop which is not currently visible (X11 only). | ||
(if frames-only-mode | ||
(add-to-list 'display-buffer-alist | ||
(cons "\*compilation\*" (cons #'frames-only-mode--display-buffer-fn nil))) | ||
(setq display-buffer-alist | ||
(--remove (equal (car (cdr it)) #'frames-only-mode--display-buffer-fn) | ||
display-buffer-alist)))) | ||
|
||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,16 @@ | ||
(require 'f) | ||
|
||
(require 'frames-only-mode (f-expand "frames-only-mode.el" (f-parent (f-dirname (f-this-file))))) | ||
|
||
;; For el-mock | ||
(eval-when-compile | ||
(require 'cl)) | ||
|
||
(require 'el-mock) | ||
|
||
(defmacro with-frames-only-mode (&rest body) | ||
`(unwind-protect | ||
(progn | ||
(frames-only-mode 1) | ||
,@body) | ||
(frames-only-mode 0))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
|
||
(ert-deftest current-desktop () | ||
(with-mock | ||
(mock (frames-only-mode--call-process "wmctrl" "-d") => " | ||
0 - DG: N/A VP: N/A WA: N/A 1 | ||
1 * DG: N/A VP: N/A WA: 1920,0 1920x1200 2 | ||
2 - DG: N/A VP: N/A WA: N/A 3 | ||
3 - DG: N/A VP: N/A WA: N/A dump | ||
") | ||
(should (equal (frames-only-mode--x-current-desktop) "1")))) | ||
|
||
|
||
(ert-deftest visible-windows () | ||
(with-mock | ||
(mock (frames-only-mode--x-current-desktop) => "1") | ||
(mock (frames-only-mode--call-process "wmctrl" "-l") => " | ||
0x0200013c 1 cantor Extended Window Manager Hints - Mozilla Firefox | ||
0x01c08469 1 cantor frames-only-mode.el | ||
0x01c0867d 1 cantor *compilation* | ||
0x01c06151 1 cantor wmctrl-interactions-test.el | ||
0x01c0548c 1 cantor *scratch* | ||
0x04000009 1 cantor x-terminal-emulator | ||
0x0200001e 3 cantor Nowena - Amenra - Google Play Music - Mozilla Firefox | ||
0x01c05f98 3 cantor main.c | ||
") | ||
(should (equal (frames-only-mode--x-visible-window-names) | ||
'("Extended Window Manager Hints - Mozilla Firefox" | ||
"frames-only-mode.el" | ||
"*compilation*" | ||
"wmctrl-interactions-test.el" | ||
"*scratch*" | ||
"x-terminal-emulator" | ||
))) | ||
)) | ||
|
||
|
||
(ert-deftest compilation-window-display () | ||
(with-frames-only-mode | ||
|
||
;; This is not running graphically, so we need to override the usual | ||
;; frames-only-mode setting of 'graphic-only and set pop-up-frames to true. | ||
(let ((pop-up-frames t) | ||
(frames-only-mode-reopen-frames-from-hidden-x11-virtual-desktops t)) | ||
|
||
(get-buffer-create "*compilation*") | ||
|
||
;; When the compilation buffer is visible | ||
(with-mock | ||
(mock (frames-only-mode--x-buffer-window-visible "*compilation*") => t) | ||
(mock (make-frame *)) | ||
(display-buffer "*compilation*")) | ||
|
||
;; When the compilation buffer is not currently visible | ||
(with-mock | ||
(mock (frames-only-mode--x-buffer-window-visible "*compilation*") => nil) | ||
(mock (make-frame *)) | ||
(display-buffer "*compilation*"))))) | ||
|
||
|
||
(defun fom/display-buffer-alist-contains-settings () | ||
(--find (equal (car (cdr it)) | ||
#'frames-only-mode--display-buffer-fn) | ||
display-buffer-alist)) | ||
|
||
(ert-deftest settings-reverted-for-compilation-window-display () | ||
(should (not (fom/display-buffer-alist-contains-settings))) | ||
|
||
(with-frames-only-mode | ||
(should (fom/display-buffer-alist-contains-settings))) | ||
|
||
(should (not (fom/display-buffer-alist-contains-settings)))) |