unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* mwheel scroll horizontally
@ 2010-10-04 22:50 Juri Linkov
  2010-10-04 23:21 ` Drew Adams
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Juri Linkov @ 2010-10-04 22:50 UTC (permalink / raw)
  To: emacs-devel

Why mwheel.el doesn't allow horizontal scrolling?
The mouse wheel is indispensable for efficient scrolling
around large images like maps in image-mode.

For instance, Gimp allows the Shift modifier to change
the direction of scrolling from vertical to horizontal.
Shift and Control are already in use in mouse-wheel-scroll-amount,
but Meta is available.  What about using Meta for horizontal
scrolling?  The following patch does this.  One problem is that
a new format complicates the defcustom type definition.  Maybe a separate
customizable variable for horizontal scroll definition (e.g.
`mouse-wheel-hscroll-amount') with exactly the same format as
`mouse-wheel-scroll-amount' would be better?

=== modified file 'lisp/mwheel.el'
--- lisp/mwheel.el	2010-08-30 18:48:02 +0000
+++ lisp/mwheel.el	2010-10-04 22:44:45 +0000
@@ -99,7 +99,10 @@ (defcustom mouse-wheel-inhibit-click-tim
   :group 'mouse
   :type 'number)
 
-(defcustom mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control) . nil))
+(defcustom mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control) . nil)
+					 ((meta) . (hscroll . 5))
+					 ((meta shift) . (hscroll . 1))
+					 ((meta control) . (hscroll . nil)))
   "Amount to scroll windows by when spinning the mouse wheel.
 This is an alist mapping the modifier key to the amount to scroll when
 the wheel is moved with the modifier key depressed.
@@ -123,7 +126,13 @@ (defcustom mouse-wheel-scroll-amount '(5
 		   (choice :tag "scroll amount"
 			   (const :tag "Full screen" :value nil)
 			   (integer :tag "Specific # of lines")
-			   (float :tag "Fraction of window"))))
+			   (float :tag "Fraction of window")
+			   (cons
+			    (const :tag "Horizontal scroll" :value hscroll)
+			    (choice :tag "scroll amount"
+				    (const :tag "Full screen" :value nil)
+				    (integer :tag "Specific # of lines")
+				    (float :tag "Fraction of window"))))))
           (repeat
            (cons
             (repeat (choice :tag "modifier"
@@ -132,7 +141,13 @@ (defcustom mouse-wheel-scroll-amount '(5
             (choice :tag "scroll amount"
                     (const :tag "Full screen" :value nil)
                     (integer :tag "Specific # of lines")
-                    (float :tag "Fraction of window")))))
+                    (float :tag "Fraction of window")
+		    (cons
+		     (const :tag "Horizontal scroll" :value hscroll)
+		     (choice :tag "scroll amount"
+			     (const :tag "Full screen" :value nil)
+			     (integer :tag "Specific # of lines")
+			     (float :tag "Fraction of window")))))))
   :set 'mouse-wheel-change-button)
 
 (defcustom mouse-wheel-progressive-speed t
@@ -186,6 +201,12 @@ (defvar mwheel-scroll-up-function 'scrol
 (defvar mwheel-scroll-down-function 'scroll-down
   "Function that does the job of scrolling downward.")
 
+(defvar mwheel-scroll-left-function 'scroll-left
+  "Function that does the job of scrolling left.")
+
+(defvar mwheel-scroll-right-function 'scroll-right
+  "Function that does the job of scrolling right.")
+
 (defun mwheel-scroll (event)
   "Scroll up or down according to the EVENT.
 This should only be bound to mouse buttons 4 and 5."
@@ -200,9 +221,16 @@ (defun mwheel-scroll (event)
 		     (point))))
          (mods
 	  (delq 'click (delq 'double (delq 'triple (event-modifiers event)))))
-         (amt (assoc mods mouse-wheel-scroll-amount)))
-    ;; Extract the actual amount or find the element that has no modifiers.
-    (if amt (setq amt (cdr amt))
+         (amt (assoc mods mouse-wheel-scroll-amount))
+	 hscroll)
+    (if amt
+	;; Extract the actual amount.
+	(progn
+	  (setq amt (cdr amt))
+	  ;; Set hscroll for horizontal scroll.
+	  (when (eq (car-safe amt) 'hscroll)
+	    (setq hscroll t amt (cdr amt))))
+      ;; Else find the element that has no modifiers.
       (let ((list-elt mouse-wheel-scroll-amount))
 	(while (consp (setq amt (pop list-elt))))))
     (if (floatp amt) (setq amt (1+ (truncate (* amt (window-height))))))
@@ -212,7 +240,12 @@ (defun mwheel-scroll (event)
       (setq amt (* amt (event-click-count event))))
     (unwind-protect
 	(let ((button (mwheel-event-button event)))
-	  (cond ((eq button mouse-wheel-down-event)
+	  (cond (hscroll
+		 (cond ((eq button mouse-wheel-down-event)
+			(funcall mwheel-scroll-right-function amt))
+		       ((eq button mouse-wheel-up-event)
+			(funcall mwheel-scroll-left-function amt))))
+		((eq button mouse-wheel-down-event)
                  (condition-case nil (funcall mwheel-scroll-down-function amt)
                    ;; Make sure we do indeed scroll to the beginning of
                    ;; the buffer.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: mwheel scroll horizontally
  2010-10-04 22:50 mwheel scroll horizontally Juri Linkov
@ 2010-10-04 23:21 ` Drew Adams
  2010-10-04 23:39   ` Juri Linkov
  2010-10-05  4:29   ` Stephen J. Turnbull
  2010-10-04 23:32 ` Juri Linkov
  2010-10-07  9:18 ` Stefan Monnier
  2 siblings, 2 replies; 10+ messages in thread
From: Drew Adams @ 2010-10-04 23:21 UTC (permalink / raw)
  To: 'Juri Linkov', emacs-devel

> Why mwheel.el doesn't allow horizontal scrolling?
> The mouse wheel is indispensable for efficient scrolling
> around large images like maps in image-mode.

Agreed.

> For instance, Gimp allows the Shift modifier to change
> the direction of scrolling from vertical to horizontal.

Google Chrome does likewise, for page scrolling.

(But IE uses Shift-wheel to cycle the history list (URLs).  It doesn't seem to
have a wheel modifier for horizontal scrolling.)

> Shift and Control are already in use in mouse-wheel-scroll-amount,

That's the wrong place for such control, IMO.  I mean that it shouldn't be
hard-coded like that.  We should leave S- and C- open for use with the wheel,
and not hard-code them to representing a scroll amount.

> but Meta is available.  What about using Meta for horizontal
> scrolling?  

That just compounds the problem.

S-, C-, and M- should be left open wrt the mouse wheel.

In effect, you are describing _one_ possible option value:

bind S- to vertical-scroll   by amount P
bind C- to vertical-scroll   by amount Q
bind M- to horizontal-scroll by amount R

We should have a more general option whose values let the user choose any
scrolling combinations s?he wants.  We have 3 modifiers, 2 scrolling directions,
and the possibility of different scrolling amounts.  Let the user mix and match,
deciding what's important.

E.g. Some user might want horizontal and vertical, and give two amount settings
to horizontal (i.e. similar to what you proposed, but privileging horizontal,
not vertical).  Another user might want to not bind horizontal at all and just
give 3 amount-settings to vertical.  Etc.

What we should not do is decide once and for all that modifier X is for
direction A or that direction A gets two scroll amounts but direction B gets
only one.  Whatever we might choose at design time for this can instead be
chosen by the user.

And, as always, we should make it clear that such bindings of the wheel to
scrolling actions are only a convenience (default behavior) and the user and
3rd-party libraries are free to bind the wheel to any other commands, anywhere.

I mention that because too often we give the impression that because some keys
are already bound they are off limits for users/libraries.  We should make it
clear that this is just a default binding.  There is nothing sacred about window
scrolling - a mouse wheel can do lots more interesting things in Emacs than
scroll a window.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: mwheel scroll horizontally
  2010-10-04 22:50 mwheel scroll horizontally Juri Linkov
  2010-10-04 23:21 ` Drew Adams
@ 2010-10-04 23:32 ` Juri Linkov
  2010-10-07  9:18 ` Stefan Monnier
  2 siblings, 0 replies; 10+ messages in thread
From: Juri Linkov @ 2010-10-04 23:32 UTC (permalink / raw)
  To: emacs-devel

A related patch.  While scrolling using the mouse with modifiers pressed,
the mouse pointer jumps off the frame (in mouse-avoidance-mode).
This patch adds these modifiers to ignore while using the mouse:

=== modified file 'lisp/avoid.el'
--- lisp/avoid.el	2010-01-13 08:35:10 +0000
+++ lisp/avoid.el	2010-10-04 23:28:49 +0000
@@ -294,7 +294,13 @@ (defun mouse-avoidance-ignore-p ()
 		   (memq 'double modifiers)
 		   (memq 'triple modifiers)
 		   (memq 'drag modifiers)
-		   (memq 'down modifiers)))))))
+		   (memq 'down modifiers)
+		   (memq 'meta modifiers)
+		   (memq 'control modifiers)
+		   (memq 'shift modifiers)
+		   (memq 'hyper modifiers)
+		   (memq 'super modifiers)
+		   (memq 'alt modifiers)))))))
 
 (defun mouse-avoidance-banish ()
   (if (not (mouse-avoidance-ignore-p))



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: mwheel scroll horizontally
  2010-10-04 23:21 ` Drew Adams
@ 2010-10-04 23:39   ` Juri Linkov
  2010-10-05  0:01     ` Drew Adams
  2010-10-05  4:29   ` Stephen J. Turnbull
  1 sibling, 1 reply; 10+ messages in thread
From: Juri Linkov @ 2010-10-04 23:39 UTC (permalink / raw)
  To: Drew Adams; +Cc: emacs-devel

> That's the wrong place for such control, IMO.  I mean that it shouldn't be
> hard-coded like that.  We should leave S- and C- open for use with the wheel,
> and not hard-code them to representing a scroll amount.

The Commentary in mwheel.el says:

  ;; I for one would prefer some way of converting the button4/button5
  ;; events into different event types, like 'mwheel-up' or
  ;; 'mwheel-down', but I cannot find a way to do this very easily (or
  ;; portably), so for now I just live with it.

Is it what you mean?

> There is nothing sacred about window scrolling - a mouse wheel can do
> lots more interesting things in Emacs than scroll a window.

Yes, they are not just about scrolling.  For instance, in Gimp/Chrome
C-mwheel zooms in/out (like `C-x C-+' `C-x C--' `text-scale-adjust' in Emacs).



^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: mwheel scroll horizontally
  2010-10-04 23:39   ` Juri Linkov
@ 2010-10-05  0:01     ` Drew Adams
  0 siblings, 0 replies; 10+ messages in thread
From: Drew Adams @ 2010-10-05  0:01 UTC (permalink / raw)
  To: 'Juri Linkov'; +Cc: emacs-devel

> > That's the wrong place for such control, IMO.  I mean that 
> > it shouldn't be hard-coded like that.  We should leave S-
> > and C- open for use with the wheel, and not hard-code them
> > to representing a scroll amount.
> 
> The Commentary in mwheel.el says:
> 
>   ;; I for one would prefer some way of converting the button4/button5
>   ;; events into different event types, like 'mwheel-up' or
>   ;; 'mwheel-down', but I cannot find a way to do this very easily (or
>   ;; portably), so for now I just live with it.
> 
> Is it what you mean?

No. I think that's something different.

I just meant that the option in question (whatever it's called) should not
decide once and for all, by the values it offers, that users can use S- and C-
for vertical scrolling and M- for horizontal scrolling, and it should not decide
once and for all that users can choose two scroll amounts for vertical scrolling
but only one amount for horizontal scrolling.  All possibilities should be open
to users.

My point was only that the user option should let users pick any combination of
modifiers and amounts for vertical and horizontal.  Choose a default
combination, OK, but don't hem in the user wrt the modifiers, scroll directions,
amounts (or even wheel direction: which wheel direction (up/down) maps to which
scroll direction (up/down - or left/right)).

Make the option as general as possible, while still making it easy to choose a
value.

> > There is nothing sacred about window scrolling - a mouse 
> > wheel can do lots more interesting things in Emacs than
> > scroll a window.
> 
> Yes, they are not just about scrolling.  For instance, in Gimp/Chrome
> C-mwheel zooms in/out (like `C-x C-+' `C-x C--' 
> `text-scale-adjust' in Emacs).

Yes.  My only point there was that sometimes users and library writers can
mistakenly get the impression that bindings we provide by default (e.g. the
wheel is bound for scrolling) are not to be overridden.  Anything we can do to
dispel such an impression helps.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: mwheel scroll horizontally
  2010-10-04 23:21 ` Drew Adams
  2010-10-04 23:39   ` Juri Linkov
@ 2010-10-05  4:29   ` Stephen J. Turnbull
  1 sibling, 0 replies; 10+ messages in thread
From: Stephen J. Turnbull @ 2010-10-05  4:29 UTC (permalink / raw)
  To: Drew Adams; +Cc: 'Juri Linkov', emacs-devel

Drew Adams writes:

 > And, as always, we should make it clear that such bindings of the wheel to
 > scrolling actions are only a convenience (default behavior) and the user and
 > 3rd-party libraries are free to bind the wheel to any other commands, anywhere.

That's not "as always".  In general, there are strict policies about
who may bind what, with C-c <letter> reserved to the user, C-c
<punctuation> allocated to minor modes (IIRC), and "everything else"
allocated to the global map (ie, Rule by Bikeshed on Emacs Devel).

Major modes may bind anything, of course, but ISTM that many of the
desirable behaviors described here are likely to fit minor modes
("useful in various contexts") rather than major modes ("specific
applications").  So AIUI mouse bindings *currently* are (by default
and apparently without too much thought put into the matter) part of
the global map.

I agree with you that there *should* be a thought out policy for mouse
gestures.  There are fewer of them and they are less arbitrary than
keystrokes, so the allocation will be different from keys.  I think a
reasonable policy would be to allocate:

1.  Unmodified mouse gestures to the global map; these should be
    consistent with the platform standards by default, but there
    should be emulation minor modes so that multiplatform users can
    have a consistent environment (eg, on Mac OS X by default you drag
    to select text, then drag and drop that selection to copy it; but
    it should be easy to invoke an X emulation mode where you drag to
    select text, then middle click to insert the selection at the
    mouse cursor).

2.  One modifier to be reserved to the user (eg, C-<mouse gesture>
    should never be bound by Emacs or any library -- of course, which
    modifier is open to bikeshedding, er, discussion).

3.  One modifier reserved for use of the current major mode (eg,
    Shift-<mouse gesture>; same bikeshedding caveat).

4.  The remaining <modifier>-<mouse gesture>s may be bound by minor
    modes, and for most such modes the user should be able to
    configure the mouse modifier used by the minor mode.

I'm not a big rodent rider, so the concrete suggestions above should
be taken with a grain of salt.  Maybe the framework is useful, though.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: mwheel scroll horizontally
  2010-10-04 22:50 mwheel scroll horizontally Juri Linkov
  2010-10-04 23:21 ` Drew Adams
  2010-10-04 23:32 ` Juri Linkov
@ 2010-10-07  9:18 ` Stefan Monnier
  2010-10-07 22:05   ` Juri Linkov
  2 siblings, 1 reply; 10+ messages in thread
From: Stefan Monnier @ 2010-10-07  9:18 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

> Why mwheel.el doesn't allow horizontal scrolling?

You mean: why doesn't it *support* horizontal scrolling?
Lack of a corresponding patch, I guess ;-)

> For instance, Gimp allows the Shift modifier to change
> the direction of scrolling from vertical to horizontal.

There are also various situations where the user has access to "real"
horizontal scrolling.  So rather than a modifier, it might be that
horizontal scrolling is specified by mouse-6 and mouse-7 or yet
something else.

> Shift and Control are already in use in mouse-wheel-scroll-amount,
> but Meta is available.  What about using Meta for horizontal

Doing it via global-map key bindings doesn't sound quite right.
Instead, we want to have mwheel understand wheel-left and wheel-right
events, and then (if/when needed) remap (via function-key-map) other
events to those ones.


        Stefan



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: mwheel scroll horizontally
  2010-10-07  9:18 ` Stefan Monnier
@ 2010-10-07 22:05   ` Juri Linkov
  2010-10-08 10:58     ` Jason Rumney
  2010-10-08 23:56     ` Stefan Monnier
  0 siblings, 2 replies; 10+ messages in thread
From: Juri Linkov @ 2010-10-07 22:05 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

>> Why mwheel.el doesn't allow horizontal scrolling?
>
> You mean: why doesn't it *support* horizontal scrolling?
> Lack of a corresponding patch, I guess ;-)
>
>> For instance, Gimp allows the Shift modifier to change
>> the direction of scrolling from vertical to horizontal.
>
> There are also various situations where the user has access to "real"
> horizontal scrolling.  So rather than a modifier, it might be that
> horizontal scrolling is specified by mouse-6 and mouse-7 or yet
> something else.

Yes, mwheel.el is limited in this regard too and supports only
a monowheel mouse.

>> Shift and Control are already in use in mouse-wheel-scroll-amount,
>> but Meta is available.  What about using Meta for horizontal
>
> Doing it via global-map key bindings doesn't sound quite right.
> Instead, we want to have mwheel understand wheel-left and wheel-right
> events, and then (if/when needed) remap (via function-key-map) other
> events to those ones.

Maybe something like (in bindings.el or in term/x-win.el):

  (define-key function-key-map [mouse-4]   [wheel-down])
  (define-key function-key-map [mouse-5]   [wheel-up])
  (define-key function-key-map [mouse-6]   [wheel-right])
  (define-key function-key-map [mouse-7]   [wheel-left])
  (define-key function-key-map [M-mouse-6] [wheel-right])
  (define-key function-key-map [M-mouse-7] [wheel-left])

Actually, mwheel.el contains:

  (defcustom mouse-wheel-down-event
    (if (or (featurep 'w32-win) (featurep 'ns-win))
        'wheel-up

Does this mean that w32-win and ns-win already generate
these events instead of mouse-4 and mouse-5?  Could someone
with access to these systems with a two-wheeled mouse
please tell what events they generate for the second wheel?



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: mwheel scroll horizontally
  2010-10-07 22:05   ` Juri Linkov
@ 2010-10-08 10:58     ` Jason Rumney
  2010-10-08 23:56     ` Stefan Monnier
  1 sibling, 0 replies; 10+ messages in thread
From: Jason Rumney @ 2010-10-08 10:58 UTC (permalink / raw)
  To: Juri Linkov; +Cc: Stefan Monnier, emacs-devel

Juri Linkov <juri@jurta.org> writes:

> Does this mean that w32-win and ns-win already generate
> these events instead of mouse-4 and mouse-5?  Could someone
> with access to these systems with a two-wheeled mouse
> please tell what events they generate for the second wheel?

I don't have access to a two wheel mouse, but the code in w32term.c to
handle wheel events, and in keyboard.c to map them to Emacs events seems
to suggest wheel-left and wheel-right events are supported on Windows
already.



^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: mwheel scroll horizontally
  2010-10-07 22:05   ` Juri Linkov
  2010-10-08 10:58     ` Jason Rumney
@ 2010-10-08 23:56     ` Stefan Monnier
  1 sibling, 0 replies; 10+ messages in thread
From: Stefan Monnier @ 2010-10-08 23:56 UTC (permalink / raw)
  To: Juri Linkov; +Cc: emacs-devel

> Maybe something like (in bindings.el or in term/x-win.el):

>   (define-key function-key-map [mouse-4]   [wheel-down])
>   (define-key function-key-map [mouse-5]   [wheel-up])

Of course, in general, we'll want S-mouse-4 to go to S-wheel-down, and
same thing for all other (combinations of) modifiers.  There's an entry
about this problem in etc/TODO.

>   (defcustom mouse-wheel-down-event
>     (if (or (featurep 'w32-win) (featurep 'ns-win))
>         'wheel-up

> Does this mean that w32-win and ns-win already generate
> these events instead of mouse-4 and mouse-5?

Yes.  mouse-4/5 is an X11 idiosyncrasy.

> Could someone with access to these systems with a two-wheeled mouse
> please tell what events they generate for the second wheel?

AFAIK they generate wheel-left/right.


        Stefan



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2010-10-08 23:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-04 22:50 mwheel scroll horizontally Juri Linkov
2010-10-04 23:21 ` Drew Adams
2010-10-04 23:39   ` Juri Linkov
2010-10-05  0:01     ` Drew Adams
2010-10-05  4:29   ` Stephen J. Turnbull
2010-10-04 23:32 ` Juri Linkov
2010-10-07  9:18 ` Stefan Monnier
2010-10-07 22:05   ` Juri Linkov
2010-10-08 10:58     ` Jason Rumney
2010-10-08 23:56     ` Stefan Monnier

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).