+;; Scroll the window to the proper position for EVENT.
+(defun scroll-bar-horizontal-drag-1 (event)
+ (let* ((start-position (event-start event))
+ (window (nth 0 start-position))
+ (portion-whole (nth 2 start-position))
+ (unit (frame-char-width (window-frame window))))
+ (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.
+If you click outside the slider, the window scrolls to bring the slider there."
+ (interactive "e")
+ (let* (done
+ (echo-keystrokes 0)
+ (end-position (event-end event))
+ (window (nth 0 end-position))
+ (before-scroll))
+ (with-current-buffer (window-buffer window)
+ (setq before-scroll point-before-scroll))
+ (save-selected-window
+ (select-window window)
+ (setq before-scroll
+ (or before-scroll (point))))
+ (scroll-bar-horizontal-drag-1 event)
+ (track-mouse
+ (while (not done)
+ (setq event (read-event))
+ (if (eq (car-safe event) 'mouse-movement)
+ (setq event (read-event)))
+ (cond ((eq (car-safe event) 'scroll-bar-movement)
+ (scroll-bar-horizontal-drag-1 event))
+ (t
+ ;; Exit when we get the drag event; ignore that event.
+ (setq done t)))))
+ (sit-for 0)
+ (with-current-buffer (window-buffer window)
+ (setq point-before-scroll before-scroll))))
+