]> code.delx.au - gnu-emacs/blobdiff - lisp/scroll-bar.el
Prefer 'frame-parameter' where it is expected to be a bit faster
[gnu-emacs] / lisp / scroll-bar.el
index 739670cb1c93437acaf193562f828aa3317799de..e5fe31675da3c199c037a80e614f4ae8b1de7214 100644 (file)
@@ -1,6 +1,6 @@
 ;;; scroll-bar.el --- window system-independent scroll bar support
 
-;; Copyright (C) 1993-1995, 1999-2014 Free Software Foundation, Inc.
+;; Copyright (C) 1993-1995, 1999-2016 Free Software Foundation, Inc.
 
 ;; Maintainer: emacs-devel@gnu.org
 ;; Keywords: hardware
@@ -79,7 +79,7 @@ SIDE must be the symbol `left' or `right'."
      (htype lines)
      ((frame-parameter nil 'horizontal-scroll-bars)
       ;; nil means it's a non-toolkit scroll bar (which is currently
-      ;; impossible), and its width in columns is 14 pixels rounded up.
+      ;; impossible), and its height in lines is 14 pixels rounded up.
       (ceiling (or (frame-parameter nil 'scroll-bar-height) 14)
                (frame-char-width)))
      (0))))
@@ -90,16 +90,11 @@ SIDE must be the symbol `left' or `right'."
 (defvar scroll-bar-mode)
 (defvar horizontal-scroll-bar-mode)
 (defvar previous-scroll-bar-mode nil)
-(defvar previous-horizontal-scroll-bar-mode nil)
 
 (defvar scroll-bar-mode-explicit nil
   "Non-nil means `set-scroll-bar-mode' should really do something.
 This is nil while loading `scroll-bar.el', and t afterward.")
 
-(defvar horizontal-scroll-bar-mode-explicit nil
-  "Non-nil means `set-horizontal-scroll-bar-mode' should really do something.
-This is nil while loading `scroll-bar.el', and t afterward.")
-
 (defun set-scroll-bar-mode (value)
   "Set the scroll bar mode to VALUE and put the new value into effect.
 See the `scroll-bar-mode' variable for possible values to use."
@@ -112,18 +107,6 @@ See the `scroll-bar-mode' variable for possible values to use."
     (modify-all-frames-parameters (list (cons 'vertical-scroll-bars
                                              scroll-bar-mode)))))
 
-(defun set-horizontal-scroll-bar-mode (value)
-  "Set the horizontal scroll bar mode to VALUE and put the new value into effect.
-See the `horizontal-scroll-bar-mode' variable for possible values to use."
-  (if horizontal-scroll-bar-mode
-      (setq previous-horizontal-scroll-bar-mode horizontal-scroll-bar-mode))
-
-  (setq horizontal-scroll-bar-mode value)
-
-  (when horizontal-scroll-bar-mode-explicit
-    (modify-all-frames-parameters (list (cons 'horizontal-scroll-bars
-                                             horizontal-scroll-bar-mode)))))
-
 (defcustom scroll-bar-mode default-frame-scroll-bars
   "Specify whether to have vertical scroll bars, and on which side.
 Possible values are nil (no scroll bars), `left' (scroll bars on left)
@@ -140,32 +123,14 @@ Setting the variable with a customization buffer also takes effect."
   :initialize 'custom-initialize-default
   :set (lambda (_sym val) (set-scroll-bar-mode val)))
 
-(defcustom horizontal-scroll-bar-mode default-frame-horizontal-scroll-bars
-  "Specify whether to have horizontal scroll bars, and on which side.
-To set this variable in a Lisp program, use `set-horizontal-scroll-bar-mode'
-to make it take real effect.
-Setting the variable with a customization buffer also takes effect."
-  :type '(choice (const :tag "none (nil)" nil)
-                (const t))
-  :group 'frames
-  ;; The default value for :initialize would try to use :set
-  ;; when processing the file in cus-dep.el.
-  :initialize 'custom-initialize-default
-  :set (lambda (_sym val) (set-horizontal-scroll-bar-mode val)))
-
 ;; We just set scroll-bar-mode, but that was the default.
 ;; If it is set again, that is for real.
 (setq scroll-bar-mode-explicit t)
-(setq horizontal-scroll-bar-mode-explicit t)
 
 (defun get-scroll-bar-mode ()
   (declare (gv-setter set-scroll-bar-mode))
   scroll-bar-mode)
 
-(defun get-horizontal-scroll-bar-mode ()
-  (declare (gv-setter set-horizontal-scroll-bar-mode))
-  horizontal-scroll-bar-mode)
-
 (define-minor-mode scroll-bar-mode
   "Toggle vertical scroll bars on all frames (Scroll Bar mode).
 With a prefix argument ARG, enable Scroll Bar mode if ARG is
@@ -179,6 +144,12 @@ created in the future."
                            (if v (or previous-scroll-bar-mode
                                      default-frame-scroll-bars))))))
 
+(defun horizontal-scroll-bars-available-p ()
+  "Return non-nil when horizontal scroll bars are available on this system."
+  (and (display-graphic-p)
+       (boundp 'x-toolkit-scroll-bars)
+       x-toolkit-scroll-bars))
+
 (define-minor-mode horizontal-scroll-bar-mode
   "Toggle horizontal scroll bars on all frames (Horizontal Scroll Bar mode).
 With a prefix argument ARG, enable Horizontal Scroll Bar mode if
@@ -187,22 +158,32 @@ enable the mode if ARG is omitted or nil.
 
 This command applies to all frames that exist and frames to be
 created in the future."
-  :variable ((get-horizontal-scroll-bar-mode)
-             . (lambda (v) (set-horizontal-scroll-bar-mode
-                           (if v (or previous-scroll-bar-mode
-                                     default-frame-horizontal-scroll-bars))))))
+  :init-value nil
+  :global t
+  :group 'frames
+  (if (and horizontal-scroll-bar-mode
+          (not (horizontal-scroll-bars-available-p)))
+      (progn
+       (setq horizontal-scroll-bar-mode nil)
+       (message "Horizontal scroll bars are not implemented on this system"))
+    (dolist (frame (frame-list))
+      (set-frame-parameter
+       frame 'horizontal-scroll-bars horizontal-scroll-bar-mode))
+    ;; Handle `default-frame-alist' entry.
+    (setq default-frame-alist
+         (cons (cons 'horizontal-scroll-bars horizontal-scroll-bar-mode)
+               (assq-delete-all 'horizontal-scroll-bars
+                                default-frame-alist)))))
 
 (defun toggle-scroll-bar (arg)
   "Toggle whether or not the selected frame has vertical scroll bars.
-With arg, turn vertical scroll bars on if and only if arg is positive.
+With ARG, turn vertical scroll bars on if and only if ARG is positive.
 The variable `scroll-bar-mode' controls which side the scroll bars are on
 when they are turned on; if it is nil, they go on the left."
   (interactive "P")
   (if (null arg)
       (setq arg
-           (if (cdr (assq 'vertical-scroll-bars
-                          (frame-parameters (selected-frame))))
-               -1 1))
+           (if (frame-parameter nil 'vertical-scroll-bars) -1 1))
     (setq arg (prefix-numeric-value arg)))
   (modify-frame-parameters
    (selected-frame)
@@ -212,19 +193,16 @@ when they are turned on; if it is nil, they go on the left."
 
 (defun toggle-horizontal-scroll-bar (arg)
   "Toggle whether or not the selected frame has horizontal scroll bars.
-With arg, turn horizontal scroll bars on if and only if arg is positive."
+With ARG, turn vertical scroll bars on if and only if ARG is positive."
   (interactive "P")
   (if (null arg)
       (setq arg
-           (if (cdr (assq 'horizontal-scroll-bars
-                          (frame-parameters (selected-frame))))
-               -1 1))
+           (if (frame-parameter nil 'horizontal-scroll-bars) -1 1))
     (setq arg (prefix-numeric-value arg)))
   (modify-frame-parameters
    (selected-frame)
    (list (cons 'horizontal-scroll-bars
-              (if (> arg 0)
-                  (or horizontal-scroll-bar-mode default-frame-horizontal-scroll-bars))))))
+              (when (> arg 0) 'bottom)))))
 \f
 ;;;; Buffer navigation using the scroll bar.
 
@@ -327,8 +305,14 @@ If you click outside the slider, the window scrolls to bring the slider there."
         (window (nth 0 start-position))
         (portion-whole (nth 2 start-position))
         (unit (frame-char-width (window-frame window))))
-    (set-window-hscroll
-     window (/ (1- (+ (car portion-whole) unit)) unit))))
+    (if (eq (current-bidi-paragraph-direction (window-buffer window))
+           'left-to-right)
+       (set-window-hscroll
+        window (/ (+ (car portion-whole) (1- unit)) unit))
+      (set-window-hscroll
+       window (/ (+ (- (cdr portion-whole) (car portion-whole))
+                   (1- unit))
+                unit)))))
 
 (defun scroll-bar-horizontal-drag (event)
   "Scroll the window horizontally by dragging the scroll bar slider.
@@ -406,6 +390,7 @@ EVENT should be a scroll bar click."
 ;;; Tookit scroll bars.
 
 (defun scroll-bar-toolkit-scroll (event)
+  "Handle event EVENT on vertical scroll bar."
   (interactive "e")
   (let* ((end-position (event-end event))
         (window (nth 0 end-position))
@@ -447,13 +432,16 @@ EVENT should be a scroll bar click."
        (setq point-before-scroll before-scroll))))))
 
 (defun scroll-bar-toolkit-horizontal-scroll (event)
+  "Handle event EVENT on horizontal scroll bar."
   (interactive "e")
   (let* ((end-position (event-end event))
         (window (nth 0 end-position))
         (part (nth 4 end-position))
-        (bidi-factor (if (eq (current-bidi-paragraph-direction) 'left-to-right)
-                         1
-                       -1))
+        (bidi-factor
+         (if (eq (current-bidi-paragraph-direction (window-buffer window))
+                 'left-to-right)
+             1
+           -1))
         before-scroll)
     (cond
      ((eq part 'end-scroll))