Author: Arjen Markus <[email protected]>
Author: Jan Nijtmans <[email protected]>
State: Final
Type: Project
Vote: Done
Vote-Summary: Accepted 7/0/2
Votes-For: BG, DKF, FV, JN, KW, MC, SL
Votes-Against: none
Votes-Present: DGP, KBK
Created: 25-Aug-2017
Post-history: PM
Tcl-Version: 8.7
Keywords: Tk, events
Tk-Branch: tip474
Abstract
This TIP proposes to treat the mouse wheel events on all platforms in the same way. Currently, a program running on Windows binds to "MouseWheel" events, whereas a program running on Linux binds to "ButtonPress-4" and "ButtonPress-5" commands. This makes it somewhat awkward to support both types of platforms having identical behaviour.
Rationale
Tk provides a means to define user-interfaces using code that is almost perfectly independent of the platform that the program should run on. It therefore makes sense that the treatment of user actions, such as mouse clicks and the use of the mouse wheel should be independent of the platform as well. Currently, however, "Windows-type" and OSX platforms support the "MouseWheel" event, whereas for "Linux-type" platforms the program binds to "ButtonPress-4" and "ButtonPress-5" events. This is in contrast to almost all other events and event bindings.
The documentation in its present form only describes the "MouseWheel" form.
Current behaviour
The code fragment below illustrates the behaviour: run it under various platforms and use the mouse wheel in the canvas window to see which bindings fired.
pack [canvas .c]
catch {console show}
bind .c <Button> [list puts "Button %W %b"]
bind .c <Shift-Button> [list puts "Shift-Button %W %b"]
bind .c <Control-Button> [list puts "Control-Button %W %b"]
bind .c <MouseWheel> [list puts "MouseWheel %W %D"]
bind .c <Shift-MouseWheel> [list puts "Shift-MouseWheel %W %D"]
bind .c <Control-MouseWheel> [list puts "Control-MouseWheel %W %D"]
Specification
This TIP proposes to extend the bindings for the mouse wheel in such a way that it does not matter which platform the program runs on. On X11, the "Button 4" up to "Button 7" events will be translated internally to equivalent "MouseWheel" events. The modifiers "Option" and "Shift" will be supported analogously.
The "xview scroll" and "yview scroll" commands are modified to accept floats in stead of integers. This doesn't mean that we can scroll for 0.5 units or pages now, the numbers are rounded up when positive and rounded down when negative. So ".w yview scroll -0.1 units" will have the same effect as ".w yview scroll -1 units". This way, the bindings don't have to do this special rounding any more, as they are doing now.
A new helper function tk::MouseWheel
is implemented. The
disadvantage of the current bindings is that the expr
expression
needs to be parsed for every mouse move. The tk::MouseWheel
function contains the same expression, but is compiled only once.
So, this is purely an optimization. With that, the text widget bindings
become:
bind Text <MouseWheel> {
tk::MouseWheel %W y %D -3.0 pixels
}
bind Text <Option-MouseWheel> {
tk::MouseWheel %W y %D -0.3 pixels
}
bind Text <Shift-MouseWheel> {
tk::MouseWheel %W x %D -3.0 pixels
}
bind Text <Shift-Option-MouseWheel> {
tk::MouseWheel %W x %D -0.3 pixels
}
On all platforms, button 1 will be the left mouse button, button 2 the middle mouse button and button 3 the right mouse button. In Tk 8.6 and earlier, MacOS always defined buttons 2 and 3 differently. In Tk 8.7, Tk will do the swapping for us.
Considerations regarding the incompatibility
The physical buttons 4 up to 9 on Windows or MacOS, will be translated to X11 buttons 8 up to 13. From the script level nothing changes: The buttons still can be accessed from scripts as being buttons 4 up to 9. This means that X11 buttons 4 to 7 are not accessible through script any more, the only way to access those are through the translated MouseWheel events. On X11, buttons 4 up to 9 in scripts will handle the X11 buttons numbered 8 up to 13.
On macOS, the scaling for MouseWheel buttons has always
been different from those on Windows, with a factor of 120.
This means that applications assuming Tk 8.6 <MouseWheel>
events will need to be modified to the new behaviour,
otherwise the screen movements will be far too much.
On Windows, everything works as before, no incompatibility
there. Many applications already define the <MouseWheel>
binding on X11, even though in Tk 8.6 they are not
used. Such applications will work on X11 in Tk 8.7 the
same as in Tk 8.6
If the application needs to support Tcl/Tk 8.6, an extra check is required to decide which events to listen to. An example can be found in the "cscroll" demo.
This seems a minor inconvenience for gaining further platform-independence.
Reference Implementation
In Tk branch tip474
.
Copyright
This document is placed in public domain.