Commands Related to Mouse Wheel Event Handling

For Scrollutil Version 1.4

by

Csaba Nemethi

csaba.nemethi@t-online.de

Contents

Start page


The scrollutil::addMouseWheelSupport Command

NAME
scrollutil::addMouseWheelSupport – Add mouse wheel support
SYNOPSIS
scrollutil::addMouseWheelSupport tag ?axes?
DESCRIPTION
Adds mouse wheel support to the widgets having the specified binding tag by creating bindings for the mouse wheel events along the axes given by the optional axes argument, which must be xy (the default, meaning both the x and y axis), x (meaning the x axis only), or y (meaning the y axis only).  The binding scripts created by this command will scroll the window given by the %W event field with the aid of the  xview scroll number units  and  yview scroll number units  subcommands of the associated Tcl command.
REMARK 1:  If tag is the path name of a window then the binding scripts created by this command are terminated by an invocation of the break command, in order to prevent the processing of the mouse wheel events by further binding scripts.  For example, if tag is the path name of a text widget then the terminating break command makes sure that the mouse wheel events will not additionally be processed by the class bindings (associated with the binding tag Text), which in Tk 8.5 and later trigger a scrolling by pixels, unlike the bindings created by this command, which scroll the widget by units (i.e., lines and characters).
REMARK 2:  The canvas widget has no built-in bindings, but you can use this command to add mouse wheel support to the widget class Canvas or individual canvas widgets.
REMARK 3:  The mouse wheel events along the vertical axis are <MouseWheel> on Windows, <MouseWheel> and <Option-MouseWheel> on Mac OS X, and <MouseWheel>, <Button-4> and <Button-5> on X11 (where <MouseWheel> is not triggered by the X server, but can be produced using  event generate).  The mouse wheel events along the horizontal axis are <Shift-MouseWheel> on Windows, <Shift-MouseWheel> and <Shift-Option-MouseWheel> on Mac OS X, and <Shift-MouseWheel>, <Shift-Button-4> and <Shift-Button-5> on X11 (where <Shift-MouseWheel> is not triggered by the X server, but can be produced using  event generate).  On X11, when using Tk 8.7a3 or later, there are two more mouse wheel events along the horizontal axis: <Button-6> and <Button-7>, which are handled just like <Shift-Button-4> and <Shift-Button-5>, respectively.  These events are commonly triggered by left/right tilting the scroll wheel of a mouse having one or two additional (thumb) buttons.  (In Tk versions 8.6.x, with x >= 10, left/right tilting the scroll wheel of such a mouse gives rise to <Shift-MouseWheel> events on Windows and Mac OS X Aqua, and to <Shift-Button-4> and <Shift-Button-5> events on X11.)
KEYWORDS
mouse wheel event, binding, scrolling

Contents     Start page


The scrollutil::createWheelEventBindings Command

NAME
scrollutil::createWheelEventBindings – Create mouse wheel event bindings
SYNOPSIS
scrollutil::createWheelEventBindings ?tag tag ...?
DESCRIPTION
Creates mouse wheel event bindings for the specified binding tags such that if the widget under the pointer is (a descendant of) one of the scrollable widget containers having the same toplevel as the widget and registered via scrollutil::enableScrollingByWheel then these events will trigger a scrolling of that widget container.  In case of several nested registered scrollable widget containers fulfilling these conditions the innermost one will be scrolled.  Each tag argument must be all or the path name of an existing toplevel widget (including .).
REMARK:  The reason for restricting the tag arguments to all and path names of existing toplevel widgets rather than supporting also tags like "Scrollableframe" (for scrollutil::scrollableframe), "BwScrollableFrame" (for BWidget ScrollableFrame) or "Scrolledframe" (for iwidgets::scrolledframe) is that the mouse wheel events should trigger a scrolling of the widget container under the pointer not only if the widget under the pointer is the widget container itself but also if it is a descendant of the latter (recall that for each window, the path name of its nearest toplevel ancestor and the tag all are contained in the window's default list of binding tags).
KEYWORDS
mouse wheel event, binding, scrolling, scrollable widget container

Contents     Start page


The scrollutil::enableScrollingByWheel Command

NAME
scrollutil::enableScrollingByWheel – Register scrollable widget containers for scrolling by the mouse wheel
SYNOPSIS
scrollutil::enableScrollingByWheel ?scrollableWidgetContainer scrollableWidgetContainer ...?
DESCRIPTION
Adds the specified scrollable widget containers to the internal list of widget containers that are registered for scrolling by the mouse wheel event bindings created by the scrollutil::createWheelEventBindings command.
REMARK:  When a scrollable widget container whose path name was passed to this command gets destroyed, it is automatically removed from the above-mentioned internal list of registered widget containers.
KEYWORDS
mouse wheel event, binding, scrolling, scrollable widget container

Contents     Start page


The scrollutil::adaptWheelEventHandling Command

NAME
scrollutil::adaptWheelEventHandling – Adapt mouse wheel event handling
SYNOPSIS
scrollutil::adaptWheelEventHandling ?widget widget ...?
DESCRIPTION
For each widget argument, the command performs the following actions:
REMARK 1:  This command is designed to be invoked for widgets that have mouse wheel event bindings and are descendants of a scrollable widget container (although it does no harm if it is called for other widgets, too).  The Tk and tile widgets having class bindings for mouse wheel events are: listbox, text, Tk core scrollbar, ttk::scrollbar, ttk::combobox, ttk::spinbox, and ttk::treeview.  Note that the ttk::scrollbar widget has no built-in class bindings for the mouse wheel events, but Scrollutil automatically creates the missing bindings by copying the mouse wheel event bindings of the widget class Scrollbar to the binding tag TScrollbar.  Examples of widgets with binding tags other than their class names that have mouse wheel event bindings are tablelist widgets as well as the entry components of mentry widgets of type "Date", "Time", "DateTime", "IPAddr", and "IPv6Addr" (for Mentry versions 3.2 and above).
REMARK 2:  As mentioned above, Tk core scrollbar and ttk::scrollbar widgets have class bindings for mouse wheel events, hence this command should be invoked for them in case they are descendants of a scrollable widget container.  Since this task can become tedious, Scrollutil makes sure that if you pass a widget to this command and that widget is embedded into a scrollarea via the latter's setwidget subcommand, then this command will automatically be invoked for the scrollbars of that scrollarea, too.
REMARK 3:  When handling a mouse wheel event sent to a Tk core or tile scrollbar whose path name was passed to this command, if the focus is on or inside the associated widget then the event will be processed by the scrollbar rather than being redirected to the containing toplevel, just as if the focus were on the scrollbar itself.
REMARK 4:  Invoking this command for widgets that have mouse wheel event bindings and are descendants of a scrollable widget container is essential for a user-friendly mouse wheel event handling in scrollable widget containers.  Without this step the mouse wheel events would scroll both the listbox, text, ttk::treeview, or tablelist widget under the pointer and the widget container to whose descendants the latter belongs, or they would select the next/previous value in the ttk::combobox or ttk::spinbox under the pointer in addition to scrolling the widget container.  After invoking this command, e.g, for a listbox within a scrollable widget container, the mouse wheel events over that widget will only scroll the listbox if it has the focus.  Likewise, after invoking this command for a ttk::combobox or ttk::spinbox within a scrollable widget container, the mouse wheel events over that widget will only select its next/previous value if it has the focus.  In both examples, if the focus is outside the widget in question then the mouse wheel events will scroll the widget container instead.
KEYWORDS
mouse wheel event, binding, event handling, scrolling, scrollable widget container, focus

Contents     Start page


The scrollutil::setFocusCheckWindow Command

NAME
scrollutil::setFocusCheckWindow – Set the "focus check window"
SYNOPSIS
scrollutil::setFocusCheckWindow widget ?widget ...? otherWidget
DESCRIPTION
For each widget argument, the command sets the associated "focus check window" to otherWidget.  This is the window to be used in the binding scripts for the tag WheeleventRedir instead of the widget when checking whether the focus is on/inside or outside that window.  For each widget argument, otherWidget must be an ancestor of or identical to widget.
REMARK 1:  When a widget whose path name was passed to this command as one of its widget arguments gets destroyed, the association between the widget and its "focus check window" is automatically removed.
REMARK 2:  This command comes in handy if for some widgets you want to make the focus check within the binding scripts for the tag WheeleventRedir less restrictive.  For example, if the widget under the pointer is an entry component of a mentry me of type "Date", "Time", "DateTime", "IPAddr", or "IPv6Addr" and the focus is on any of its siblings, then the mouse wheel events sent to this entry should be handled by the entry widget itself rather than scrolling the widget container that is an ascendant of the mentry.  You can achieve this by invoking
set entryList [$me entries]
eval scrollutil::adaptWheelEventHandling $entryList
eval scrollutil::setFocusCheckWindow     $entryList [list $me]
With Tcl/Tk 8.5 or above, you can use the more compact form
set entryList [$me entries]
scrollutil::adaptWheelEventHandling {*}$entryList
scrollutil::setFocusCheckWindow     {*}$entryList $me
REMARK 3:  As a similar example, suppose that ss is a scrollsync widget that was populated via its setwidgets subcommand with child widgets.  Then, if the widget under the pointer is one of these children and the focus is on any of the other children passed to that subcommand, then the mouse wheel events sent to the child under the pointer should be handled by that child widget itself rather than scrolling the widget container that is an ascendant of the scrollsync.  You can achieve this with the following code:
set widgetList [$ss widgets]
eval scrollutil::adaptWheelEventHandling $widgetList
eval scrollutil::setFocusCheckWindow     $widgetList [list $ss]
Again, with Tcl/Tk 8.5 or above, you can use the more compact form
set widgetList [$ss widgets]
scrollutil::adaptWheelEventHandling {*}$widgetList
scrollutil::setFocusCheckWindow     {*}$widgetList $ss
KEYWORDS
binding, focus, "focus check window"

Contents     Start page


The scrollutil::focusCheckWindow Command

NAME
scrollutil::focusCheckWindow – Query the "focus check window"
SYNOPSIS
scrollutil::focusCheckWindow widget
DESCRIPTION
Returns the path name of the "focus check window" associated with the widget argument.  This is the window that is used in the binding scripts for the tag WheeleventRedir instead of the widget when checking whether the focus is on/inside or outside that window.  If the command scrollutil::setFocusCheckWindow was not invoked for widget then the return value is widget itself.
KEYWORDS
binding, focus, "focus check window"

Contents     Start page