]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve accessibility of window dividers. (Bug#20183)
authorMartin Rudalics <rudalics@gmx.at>
Thu, 2 Jul 2015 07:03:45 +0000 (09:03 +0200)
committerMartin Rudalics <rudalics@gmx.at>
Thu, 2 Jul 2015 07:03:45 +0000 (09:03 +0200)
* 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.

lisp/faces.el
lisp/frame.el
lisp/menu-bar.el
lisp/mouse.el

index 9857a7bd4de763993e7150695e82c2a9360f9ac8..511b35412655bc485d37e02f78c76ed0a4372b15 100644 (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
index 077687eeb6672273fdcee98ab5f1c3579f07eea8..ffa01b4dcc158ae125e923e8c09f95706ac60367 100644 (file)
@@ -1749,6 +1749,134 @@ left untouched.  FRAME nil or omitted means use the selected frame."
     'delete-frame-functions "22.1")
 
 \f
+;;; 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))
+\f
 ;; Blinking cursor
 
 (defgroup cursor nil
index 22a0b8faaba3e317282e4dc45b0460587a96f3df..5a69084f98d338f62f9568e99a3d52f0a39fd71c 100644 (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)))
index 9bb00cb105e33b907e13c657b8423dda2afdefad..221d30bc3d87d4ec700a33ef05c0e25e40b07850 100644 (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 [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 [vertical-line mouse-1] 'mouse-select-window)
+(global-set-key [bottom-divider mouse-1] 'ignore)
+(global-set-key [bottom-divider C-mouse-2] 'mouse-split-window-horizontally)
 
 (provide 'mouse)