Improve accessibility of window dividers. (Bug#20183)
* lisp/faces.el (window-divider) (window-divider-first-pixel, window-divider-last-pixel): Change membership from `frames' to `window-divider' customization group. * lisp/frame.el (window-divider): New customization group. (window-divider-mode): New minor mode. (window-divider-default-bottom-width) (window-divider-default-right-width): New options. (frame--window-divider-previous-mode): New variable. (frame-window-divider-width-valid-p) (frame--window-divider-mode-apply) (frame--window-divider-mode-set-and-apply): New functions. * lisp/menu-bar.el (menu-bar-options-save): Save window-divider-mode settings. (menu-bar-window-divider-customize) (menu-bar-bottom-and-right-window-divider) (menu-bar-right-window-divider, menu-bar-bottom-window-divider) (menu-bar-no-window-divider): New functions. (menu-bar-showhide-window-divider-menu): New variable. (menu-bar-showhide-menu): Show/hide window divider menu. * lisp/mouse.el (mouse-split-window-vertically) (mouse-split-window-horizontally): Replace `error' by `user-error'. Bind `window-combination-resize' to nil. (top-level): Add/reorder mouse key bindings on mode- and vertical-line.
This commit is contained in:
parent
bb35a21c0e
commit
0245cc3740
4 changed files with 245 additions and 16 deletions
|
@ -2506,7 +2506,7 @@ is used for the inner part while the first pixel line/column is
|
|||
drawn with the `window-divider-first-pixel' face and the last
|
||||
pixel line/column with the `window-divider-last-pixel' face."
|
||||
:version "24.4"
|
||||
:group 'frames
|
||||
:group 'window-divider
|
||||
:group 'basic-faces)
|
||||
|
||||
(defface window-divider-first-pixel
|
||||
|
@ -2517,7 +2517,7 @@ line/column is drawn with the foreground of this face. If you do
|
|||
not want to accentuate the first pixel line/column, set this to
|
||||
the same as `window-divider' face."
|
||||
:version "24.4"
|
||||
:group 'frames
|
||||
:group 'window-divider
|
||||
:group 'basic-faces)
|
||||
|
||||
(defface window-divider-last-pixel
|
||||
|
@ -2528,7 +2528,7 @@ line/column is drawn with the foreground of this face. If you do
|
|||
not want to accentuate the last pixel line/column, set this to
|
||||
the same as `window-divider' face."
|
||||
:version "24.4"
|
||||
:group 'frames
|
||||
:group 'window-divider
|
||||
:group 'basic-faces)
|
||||
|
||||
(defface minibuffer-prompt
|
||||
|
|
128
lisp/frame.el
128
lisp/frame.el
|
@ -1749,6 +1749,134 @@ left untouched. FRAME nil or omitted means use the selected frame."
|
|||
'delete-frame-functions "22.1")
|
||||
|
||||
|
||||
;;; Window dividers.
|
||||
(defgroup window-divider nil
|
||||
"Window dividers."
|
||||
:version "25.1"
|
||||
:group 'frames
|
||||
:group 'windows)
|
||||
|
||||
(defvar frame--window-divider-previous-mode nil
|
||||
"Previous value of `window-divider-mode'.
|
||||
This is the value seen when `window-divider-mode' was switched
|
||||
off the last time. It's reused when `window-divider-mode' is
|
||||
switched on again.")
|
||||
|
||||
(defcustom window-divider-mode nil
|
||||
"Specify whether to display window dividers and where.
|
||||
Possible values are nil (no dividers), `bottom-only' (dividers on
|
||||
the bottom of each window only), `right-only' (dividers on the
|
||||
right of each window only), and t (dividers on the bottom and on
|
||||
the right of each window)."
|
||||
:type '(choice (const :tag "None (nil)" nil)
|
||||
(const :tag "Bottom only" bottom-only)
|
||||
(const :tag "Right only" right-only)
|
||||
(const :tag "Bottom and right" t))
|
||||
:initialize 'custom-initialize-default
|
||||
:set (lambda (_symbol value)
|
||||
(frame--window-divider-mode-set-and-apply value))
|
||||
:group 'window-divider
|
||||
:version "25.1")
|
||||
|
||||
(define-minor-mode window-divider-mode
|
||||
"Display dividers between windows (Window Divider mode).
|
||||
With a prefix argument ARG, enable Window Divider mode if ARG is
|
||||
positive, and disable it otherwise. If called from Lisp, enable
|
||||
the mode if ARG is omitted or nil.
|
||||
|
||||
The option `window-divider-default-width' allows to customize the
|
||||
width of dividers displayed by this mode."
|
||||
:group 'window-divider
|
||||
:global t
|
||||
:variable (window-divider-mode
|
||||
. (lambda (value)
|
||||
(frame--window-divider-mode-set-and-apply
|
||||
(and value
|
||||
(or frame--window-divider-previous-mode
|
||||
(default-value 'window-divider-mode)
|
||||
'right-only))))))
|
||||
|
||||
(defun frame-window-divider-width-valid-p (value)
|
||||
"Return non-nil if VALUE is a positive number."
|
||||
(and (numberp value) (> value 0)))
|
||||
|
||||
(defcustom window-divider-default-bottom-width 6
|
||||
"Default width of dividers on bottom of windows.
|
||||
The value must be a positive integer and takes effect when bottom
|
||||
dividers are displayed by `window-divider-mode'.
|
||||
|
||||
To adjust bottom dividers for frames individually, use the frame
|
||||
parameter `bottom-divider-width'."
|
||||
:type '(restricted-sexp
|
||||
:tag "Default bottom divider width"
|
||||
:match-alternatives (frame-window-divider-width-valid-p))
|
||||
:group 'window-divider
|
||||
:initialize 'custom-initialize-default
|
||||
:set (lambda (symbol value)
|
||||
(set-default symbol value)
|
||||
(when window-divider-mode
|
||||
(frame--window-divider-mode-apply)))
|
||||
:version "25.1")
|
||||
|
||||
(defcustom window-divider-default-right-width 6
|
||||
"Default width of dividers on the right of windows.
|
||||
The value must be a positive integer and takes effect when right
|
||||
dividers are displayed by `window-divider-mode'.
|
||||
|
||||
To adjust right dividers for frames individually, use the frame
|
||||
parameter `right-divider-width'."
|
||||
:type '(restricted-sexp
|
||||
:tag "Default right divider width"
|
||||
:match-alternatives (frame-window-divider-width-valid-p))
|
||||
:group 'window-divider
|
||||
:initialize 'custom-initialize-default
|
||||
:set (lambda (symbol value)
|
||||
(set-default symbol value)
|
||||
(when window-divider-mode
|
||||
(frame--window-divider-mode-apply)))
|
||||
:version "25.1")
|
||||
|
||||
(defun frame--window-divider-mode-apply ()
|
||||
"Apply window divider widths."
|
||||
(let ((bottom (if (memq window-divider-mode '(bottom-only t))
|
||||
window-divider-default-bottom-width
|
||||
0))
|
||||
(right (if (memq window-divider-mode '(right-only t))
|
||||
window-divider-default-right-width
|
||||
0)))
|
||||
(modify-all-frames-parameters
|
||||
(list (cons 'bottom-divider-width bottom)
|
||||
(cons 'right-divider-width right)))
|
||||
(setq default-frame-alist
|
||||
(assq-delete-all
|
||||
'bottom-divider-width default-frame-alist))
|
||||
(setq default-frame-alist
|
||||
(assq-delete-all
|
||||
'right-divider-width default-frame-alist))
|
||||
(when (> bottom 0)
|
||||
(setq default-frame-alist
|
||||
(cons
|
||||
(cons 'bottom-divider-width bottom)
|
||||
default-frame-alist)))
|
||||
(when (> right 0)
|
||||
(setq default-frame-alist
|
||||
(cons
|
||||
(cons 'right-divider-width right)
|
||||
default-frame-alist)))))
|
||||
|
||||
(defun frame--window-divider-mode-set-and-apply (value)
|
||||
"Set window divider mode to VALUE and apply widths."
|
||||
(unless value
|
||||
;; Remember current mode.
|
||||
(setq frame--window-divider-previous-mode window-divider-mode))
|
||||
(set-default 'window-divider-mode value)
|
||||
;; Pacify customize rigmarole.
|
||||
(put 'window-divider-mode 'customized-value
|
||||
(if (memq value '(nil t))
|
||||
(list value)
|
||||
(list (list 'quote value))))
|
||||
(frame--window-divider-mode-apply))
|
||||
|
||||
;; Blinking cursor
|
||||
|
||||
(defgroup cursor nil
|
||||
|
|
|
@ -683,7 +683,7 @@ by \"Save Options\" in Custom buffers.")
|
|||
(dolist (elt '(scroll-bar-mode
|
||||
debug-on-quit debug-on-error
|
||||
;; Somehow this works, when tool-bar and menu-bar don't.
|
||||
tooltip-mode
|
||||
tooltip-mode window-divider-mode
|
||||
save-place uniquify-buffer-name-style fringe-mode
|
||||
indicate-empty-lines indicate-buffer-boundaries
|
||||
case-fold-search font-use-system-font
|
||||
|
@ -711,6 +711,92 @@ by \"Save Options\" in Custom buffers.")
|
|||
|
||||
;; The "Show/Hide" submenu of menu "Options"
|
||||
|
||||
(defun menu-bar-window-divider-customize ()
|
||||
"Show customization buffer for `window-divider' group."
|
||||
(interactive)
|
||||
(customize-group 'window-divider))
|
||||
|
||||
(defun menu-bar-bottom-and-right-window-divider ()
|
||||
"Display dividers on the bottom and right of each window."
|
||||
(interactive)
|
||||
(customize-set-variable 'window-divider-mode t))
|
||||
|
||||
(defun menu-bar-right-window-divider ()
|
||||
"Display dividers only on the right of each window."
|
||||
(interactive)
|
||||
(customize-set-variable 'window-divider-mode 'right-only))
|
||||
|
||||
(defun menu-bar-bottom-window-divider ()
|
||||
"Display dividers only at the bottom of each window."
|
||||
(interactive)
|
||||
(customize-set-variable 'window-divider-mode 'bottom-only))
|
||||
|
||||
(defun menu-bar-no-window-divider ()
|
||||
"Do not display window dividers."
|
||||
(interactive)
|
||||
(customize-set-variable 'window-divider-mode nil))
|
||||
|
||||
;; For the radio buttons below we check whether the respective dividers
|
||||
;; are displayed on the selected frame. This is not fully congruent
|
||||
;; with `window-divder-mode' but makes the menu entries work also when
|
||||
;; dividers are displayed by manipulating frame parameters directly.
|
||||
(defvar menu-bar-showhide-window-divider-menu
|
||||
(let ((menu (make-sparse-keymap "Window Divider")))
|
||||
(bindings--define-key menu [customize]
|
||||
'(menu-item "Customize" menu-bar-window-divider-customize
|
||||
:help "Customize window dividers"
|
||||
:visible (memq (window-system) '(x w32))))
|
||||
|
||||
(bindings--define-key menu [bottom-and-right]
|
||||
'(menu-item "Bottom and Right"
|
||||
menu-bar-bottom-and-right-window-divider
|
||||
:help "Display window divider on the bottom and right of each window"
|
||||
:visible (memq (window-system) '(x w32))
|
||||
:button (:radio
|
||||
. (and (frame-window-divider-width-valid-p
|
||||
(cdr (assq 'bottom-divider-width
|
||||
(frame-parameters))))
|
||||
(frame-window-divider-width-valid-p
|
||||
(cdr (assq 'right-divider-width
|
||||
(frame-parameters))))))))
|
||||
(bindings--define-key menu [right-only]
|
||||
'(menu-item "Right Only"
|
||||
menu-bar-right-window-divider
|
||||
:help "Display window divider on the right of each window only"
|
||||
:visible (memq (window-system) '(x w32))
|
||||
:button (:radio
|
||||
. (and (not (frame-window-divider-width-valid-p
|
||||
(cdr (assq 'bottom-divider-width
|
||||
(frame-parameters)))))
|
||||
(frame-window-divider-width-valid-p
|
||||
(cdr (assq 'right-divider-width
|
||||
(frame-parameters))))))))
|
||||
(bindings--define-key menu [bottom-only]
|
||||
'(menu-item "Bottom Only"
|
||||
menu-bar-bottom-window-divider
|
||||
:help "Display window divider on the bottom of each window only"
|
||||
:visible (memq (window-system) '(x w32))
|
||||
:button (:radio
|
||||
. (and (frame-window-divider-width-valid-p
|
||||
(cdr (assq 'bottom-divider-width
|
||||
(frame-parameters))))
|
||||
(not (frame-window-divider-width-valid-p
|
||||
(cdr (assq 'right-divider-width
|
||||
(frame-parameters)))))))))
|
||||
(bindings--define-key menu [no-divider]
|
||||
'(menu-item "None"
|
||||
menu-bar-no-window-divider
|
||||
:help "Do not display window dividers"
|
||||
:visible (memq (window-system) '(x w32))
|
||||
:button (:radio
|
||||
. (and (not (frame-window-divider-width-valid-p
|
||||
(cdr (assq 'bottom-divider-width
|
||||
(frame-parameters)))))
|
||||
(not (frame-window-divider-width-valid-p
|
||||
(cdr (assq 'right-divider-width
|
||||
(frame-parameters)))))))))
|
||||
menu))
|
||||
|
||||
(defun menu-bar-showhide-fringe-ind-customize ()
|
||||
"Show customization buffer for `indicate-buffer-boundaries'."
|
||||
(interactive)
|
||||
|
@ -1072,6 +1158,10 @@ mail status in mode line"))
|
|||
(frame-visible-p
|
||||
(symbol-value 'speedbar-frame))))))
|
||||
|
||||
(bindings--define-key menu [showhide-window-divider]
|
||||
`(menu-item "Window Divider" ,menu-bar-showhide-window-divider-menu
|
||||
:visible (memq (window-system) '(x w32))))
|
||||
|
||||
(bindings--define-key menu [showhide-fringe]
|
||||
`(menu-item "Fringe" ,menu-bar-showhide-fringe-menu
|
||||
:visible (display-graphic-p)))
|
||||
|
|
|
@ -338,9 +338,12 @@ This command must be bound to a mouse click."
|
|||
(first-line window-min-height)
|
||||
(last-line (- (window-height) window-min-height)))
|
||||
(if (< last-line first-line)
|
||||
(error "Window too short to split")
|
||||
(split-window-vertically
|
||||
(min (max new-height first-line) last-line))))))
|
||||
(user-error "Window too short to split")
|
||||
;; Bind `window-combination-resize' to nil so we are sure to get
|
||||
;; the split right at the line clicked on.
|
||||
(let (window-combination-resize)
|
||||
(split-window-vertically
|
||||
(min (max new-height first-line) last-line)))))))
|
||||
|
||||
(defun mouse-split-window-horizontally (click)
|
||||
"Select Emacs window mouse is on, then split it horizontally in half.
|
||||
|
@ -354,9 +357,12 @@ This command must be bound to a mouse click."
|
|||
(first-col window-min-width)
|
||||
(last-col (- (window-width) window-min-width)))
|
||||
(if (< last-col first-col)
|
||||
(error "Window too narrow to split")
|
||||
(split-window-horizontally
|
||||
(min (max new-width first-col) last-col))))))
|
||||
(user-error "Window too narrow to split")
|
||||
;; Bind `window-combination-resize' to nil so we are sure to get
|
||||
;; the split right at the column clicked on.
|
||||
(let (window-combination-resize)
|
||||
(split-window-horizontally
|
||||
(min (max new-width first-col) last-col)))))))
|
||||
|
||||
(defun mouse-drag-line (start-event line)
|
||||
"Drag a mode line, header line, or vertical line with the mouse.
|
||||
|
@ -1915,20 +1921,25 @@ choose a font."
|
|||
;; vertical-line prevents Emacs from signaling an error when the mouse
|
||||
;; button is released after dragging these lines, on non-toolkit
|
||||
;; versions.
|
||||
(global-set-key [mode-line mouse-1] 'mouse-select-window)
|
||||
(global-set-key [mode-line drag-mouse-1] 'mouse-select-window)
|
||||
(global-set-key [mode-line down-mouse-1] 'mouse-drag-mode-line)
|
||||
(global-set-key [header-line down-mouse-1] 'mouse-drag-header-line)
|
||||
(global-set-key [header-line mouse-1] 'mouse-select-window)
|
||||
;; (global-set-key [mode-line drag-mouse-1] 'mouse-select-window)
|
||||
(global-set-key [mode-line down-mouse-1] 'mouse-drag-mode-line)
|
||||
(global-set-key [mode-line mouse-1] 'mouse-select-window)
|
||||
(global-set-key [mode-line mouse-2] 'mouse-delete-other-windows)
|
||||
(global-set-key [mode-line mouse-3] 'mouse-delete-window)
|
||||
(global-set-key [mode-line C-mouse-2] 'mouse-split-window-horizontally)
|
||||
(global-set-key [vertical-scroll-bar C-mouse-2] 'mouse-split-window-vertically)
|
||||
(global-set-key [vertical-line C-mouse-2] 'mouse-split-window-vertically)
|
||||
(global-set-key [horizontal-scroll-bar C-mouse-2] 'mouse-split-window-horizontally)
|
||||
(global-set-key [vertical-line down-mouse-1] 'mouse-drag-vertical-line)
|
||||
(global-set-key [right-divider down-mouse-1] 'mouse-drag-vertical-line)
|
||||
(global-set-key [bottom-divider down-mouse-1] 'mouse-drag-mode-line)
|
||||
(global-set-key [vertical-line mouse-1] 'mouse-select-window)
|
||||
(global-set-key [vertical-line C-mouse-2] 'mouse-split-window-vertically)
|
||||
(global-set-key [right-divider down-mouse-1] 'mouse-drag-vertical-line)
|
||||
(global-set-key [right-divider mouse-1] 'ignore)
|
||||
(global-set-key [right-divider C-mouse-2] 'mouse-split-window-vertically)
|
||||
(global-set-key [bottom-divider down-mouse-1] 'mouse-drag-mode-line)
|
||||
(global-set-key [bottom-divider mouse-1] 'ignore)
|
||||
(global-set-key [bottom-divider C-mouse-2] 'mouse-split-window-horizontally)
|
||||
|
||||
(provide 'mouse)
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue