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:
Martin Rudalics 2015-07-02 09:03:45 +02:00
parent bb35a21c0e
commit 0245cc3740
4 changed files with 245 additions and 16 deletions

View file

@ -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

View file

@ -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

View file

@ -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)))

View file

@ -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)