From 50ca6a3d2a0242016747053b1f08ce4c0ddaee3c Mon Sep 17 00:00:00 2001 From: marc_culler Date: Sun, 19 Nov 2023 23:02:15 +0000 Subject: Restore low-res scrollwheel behavior; insert a placeholder for sending touchpad events. --- library/demos/cscroll.tcl | 86 +++++++++++++++++++++++---------------------- library/scrlbar.tcl | 36 +++++-------------- library/text.tcl | 25 +++---------- library/tk.tcl | 24 ------------- macosx/tkMacOSXMouseEvent.c | 48 ++++++++++--------------- win/tkWinX.c | 70 +++++++++++++++++------------------- 6 files changed, 109 insertions(+), 180 deletions(-) diff --git a/library/demos/cscroll.tcl b/library/demos/cscroll.tcl index 54d98e0..98a4be2 100644 --- a/library/demos/cscroll.tcl +++ b/library/demos/cscroll.tcl @@ -17,7 +17,7 @@ wm iconname $w "cscroll" positionWindow $w set c $w.c -label $w.msg -font $font -wraplength 4i -justify left -text "This window displays a canvas widget that can be scrolled either using the scrollbars or by dragging with either shift-button 1 or button 2 in the canvas. If you click button 1 on one of the rectangles, its indices will be printed on stdout." +label $w.msg -font $font -wraplength 4i -justify left -text "This window displays a canvas widget that can be scrolled either using the scrollbars or by dragging with button 2 in the canvas. If you click button 1 on one of the rectangles, its indices will be printed on stdout." pack $w.msg -side top ## See Code / Dismiss buttons @@ -25,27 +25,8 @@ set btns [addSeeDismiss $w.buttons $w] pack $btns -side bottom -fill x frame $w.grid -ttk::scrollbar $w.hscroll -orient horizontal -command "$c xview" -ttk::scrollbar $w.vscroll -command "$c yview" -# Override the scrollbar's mousewheel binding to speed it up: -set fastwheel { - set HiresScrollMask 512 - set ShiftMask 1 - if {[expr {%s & $ShiftMask}]} { - set orientation "h"; - } else { - set orientation "v"; - } - if {[expr {%s & $HiresScrollMask}]} { - tk::ScrollByUnits %W $orientation %D -1.0 - } else { - tk::ScrollByUnits %W $orientation %D -30.0 - } - break -} -bind $w.vscroll $fastwheel -bind $w.hscroll $fastwheel - +scrollbar $w.hscroll -orient horizontal -command "$c xview" +scrollbar $w.vscroll -command "$c yview" canvas $c -relief sunken -borderwidth 2 -scrollregion {-11c -11c 50c 20c} \ -xscrollcommand "$w.hscroll set" \ -yscrollcommand "$w.vscroll set" @@ -75,40 +56,61 @@ for {set i 0} {$i < 20} {incr i} { $c bind all "scrollEnter $c" $c bind all "scrollLeave $c" $c bind all "scrollButton $c" - -bind $c "$c scan mark %x %y" -bind $c "$c scan dragto %x %y" -bind $c "$c scan mark %x %y" -bind $c "$c scan dragto %x %y" - -if {[package vsatisfies [package provide Tk] 8.7-]} { - # Bindings for 8.7 and up - $c configure -yscrollincrement 1 -xscrollincrement 1 +if {([tk windowingsystem] eq "aqua") && ![package vsatisfies [package provide Tk] 8.7-]} { + bind $c "$c scan mark %x %y" + bind $c "$c scan dragto %x %y" bind $c { - tk::MouseWheel %W y %D -1.0 - } - bind $c { - tk::MouseWheel %W x %D -1.0 + %W yview scroll [expr {-%D}] units } bind $c { - tk::MouseWheel %W y %D -0.3 + %W yview scroll [expr {-10*%D}] units } - bind $c { - tk::MouseWheel %W x %D -0.3 + bind $c { + %W xview scroll [expr {-%D}] units + } + bind $c { + %W xview scroll [expr {-10*%D}] units } } else { + bind $c "$c scan mark %x %y" + bind $c "$c scan dragto %x %y" + # We must make sure that positive and negative movements are rounded + # equally to integers, avoiding the problem that + # (int)1/-30 = -1, + # but + # (int)-1/-30 = 0 + # The following code ensure equal +/- behaviour. bind $c { - %W yview scroll [expr {-%D}] units + if {%D >= 0} { + %W yview scroll [expr {%D/-30}] units + } else { + %W yview scroll [expr {(%D-29)/-30}] units + } } bind $c { - %W yview scroll [expr {-10*%D}] units + if {%D >= 0} { + %W yview scroll [expr {%D/-3}] units + } else { + %W yview scroll [expr {(%D-2)/-3}] units + } } bind $c { - %W xview scroll [expr {-%D}] units + if {%D >= 0} { + %W xview scroll [expr {%D/-30}] units + } else { + %W xview scroll [expr {(%D-29)/-30}] units + } } bind $c { - %W xview scroll [expr {-10*%D}] units + if {%D >= 0} { + %W xview scroll [expr {%D/-3}] units + } else { + %W xview scroll [expr {(%D-2)/-3}] units + } } +} + +if {[tk windowingsystem] eq "x11" && ![package vsatisfies [package provide Tk] 8.7-]} { # Support for mousewheels on Linux/Unix commonly comes through mapping # the wheel to the extended buttons. If you have a mousewheel, find # Linux configuration info at: diff --git a/library/scrlbar.tcl b/library/scrlbar.tcl index 0a0c2c6..c18d4a8 100644 --- a/library/scrlbar.tcl +++ b/library/scrlbar.tcl @@ -130,20 +130,10 @@ bind Scrollbar <> { } bind Scrollbar { - set direction [tk::ScrollDirection %s] - if {[tk::IsHiResScroll %s]} { - tk::ScrollByUnits %W $direction %D -10.0 - } else { - tk::ScrollByUnits %W $direction [tk::ScaleNum %D] -30.0 - } + tk::ScrollByUnits %W hv %D -40.0 } bind Scrollbar { - set direction [tk::ScrollDirection %s] - if {[tk::IsHiResScroll %s]} { - tk::ScrollByUnits %W $direction %D -1.0 - } else { - tk::ScrollByUnits %W $direction [tk::ScaleNum %D] -3.0 - } + tk::ScrollByUnits %W hv %D -12.0 } # tk::ScrollButtonDown -- @@ -318,24 +308,16 @@ proc ::tk::ScrollEndDrag {w x y} { proc ::tk::ScrollByUnits {w orient amount {factor 1.0}} { set cmd [$w cget -command] - if {$cmd eq ""} { + if {$cmd eq "" || ([string first \ + [string index [$w cget -orient] 0] $orient] < 0)} { return } - set xyview [lindex [split $cmd] end] - if {$orient eq "v"} { - if {$xyview eq "xview"} { - return - } - set size [winfo height $w] - } - if {$orient eq "h"} { - if {$xyview eq "yview"} { - return - } - set size [winfo width $w] + set info [$w get] + if {[llength $info] == 2} { + uplevel #0 $cmd scroll [expr {$amount/$factor}] units + } else { + uplevel #0 $cmd [expr {[lindex $info 2] + [expr {$amount/$factor}]}] } - set scale [expr {[$w delta 1.0 1.0] * $size}] - uplevel #0 $cmd scroll [expr {$amount * $scale / $factor}] units } # ::tk::ScrollByPages -- diff --git a/library/text.tcl b/library/text.tcl index 631759d..eb73db0 100644 --- a/library/text.tcl +++ b/library/text.tcl @@ -455,33 +455,18 @@ bind Text { } } set ::tk::Priv(prevPos) {} + bind Text { - if {[tk::IsHiResScroll %s]} { - tk::MouseWheel %W y %D -1.0 pixels - } else { - tk::MouseWheel %W y [tk::ScaleNum %D] -4.0 pixels - } + tk::MouseWheel %W y %D -4.0 pixels } bind Text { - if {[tk::IsHiResScroll %s]} { - tk::MouseWheel %W y %D -0.3 pixels - } else { - tk::MouseWheel %W y [tk::ScaleNum %D] -1.2 pixels - } + tk::MouseWheel %W y %D -1.2 pixels } bind Text { - if {[tk::IsHiResScroll %s]} { - tk::MouseWheel %W x %D -1.0 pixels - } else { - tk::MouseWheel %W x [tk::ScaleNum %D] -4.0 pixels - } + tk::MouseWheel %W x %D -4.0 pixels } bind Text { - if {[tk::IsHiResScroll %s]} { - tk::MouseWheel %W x %D -0.3 pixels - } else { - tk::MouseWheel %W x [tk::ScaleNum %D] -1.2 pixels - } + tk::MouseWheel %W x %D -1.2 pixels } # ::tk::TextClosestGap -- diff --git a/library/tk.tcl b/library/tk.tcl index 74942cb..a6dc37c 100644 --- a/library/tk.tcl +++ b/library/tk.tcl @@ -543,30 +543,6 @@ proc ::tk::CancelRepeat {} { set Priv(afterId) {} } - -# ::tk::IsHiResScroll $state -- -# Checks whether the HiResScrollMask bit is set in the state. - -proc ::tk::IsHiResScroll state { - if {[expr {$state & 512}]} { - return 1 - } else { - return 0 - } -} - -# ::tk::ScrollDirection $state -- -# Checks if ShiftMask is set in the MouseWheelEvent state. -# Returns h for a horizontal scroll, v for a vertical scroll - -proc ::tk::ScrollDirection state { - if {[expr {$state & 1}]} { - return "h" - } else { - return "v" - } -} - ## ::tk::MouseWheel $w $dir $amount $factor $units proc ::tk::MouseWheel {w dir amount {factor -120.0} {units units}} { diff --git a/macosx/tkMacOSXMouseEvent.c b/macosx/tkMacOSXMouseEvent.c index bb6e1a8..2d4432b 100644 --- a/macosx/tkMacOSXMouseEvent.c +++ b/macosx/tkMacOSXMouseEvent.c @@ -543,17 +543,8 @@ enum { Tk_UpdatePointer(target, global.x, global.y, state); } } else { - - /* - * This state bit means that the delta should be interpreted - * as a number of pixels. It is chosen to not conflict with - * any modifier bits. - */ - -#define HiresScrollMask (1 << 9) - - Bool deltaIsPrecise = [theEvent hasPreciseScrollingDeltas]; CGFloat delta; + Bool deltaIsPrecise = [theEvent hasPreciseScrollingDeltas]; XEvent xEvent = {0}; xEvent.type = MouseWheelEvent; xEvent.xbutton.x = win_x; @@ -563,25 +554,24 @@ enum { xEvent.xany.send_event = false; xEvent.xany.display = Tk_Display(target); xEvent.xany.window = Tk_WindowId(target); - delta = [theEvent scrollingDeltaY]; - if (! deltaIsPrecise) { - delta = delta > 0 ? ceil(10.0 * delta) : - ceil(-10.0 * delta); - } - if (delta != 0.0) { - xEvent.xbutton.state = state | HiresScrollMask; - xEvent.xkey.keycode = (unsigned int)(int)delta; - xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); - Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); - } - delta = [theEvent scrollingDeltaX]; - if (! deltaIsPrecise) { - delta = delta > 0 ? ceil(10.0 * delta) : - ceil(-10.0 * delta); - } - if (delta != 0.0) { - xEvent.xbutton.state = state | ShiftMask | HiresScrollMask; - xEvent.xkey.keycode = (unsigned int)(int)delta; - xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); - Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); + if (!deltaIsPrecise) { + delta = [theEvent scrollingDeltaY]; + if (delta != 0.0) { + xEvent.xbutton.state = state; + xEvent.xkey.keycode = delta > 0 ? 120 : -120; + xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); + Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); + } + delta = [theEvent scrollingDeltaX]; + if (delta != 0.0) { + xEvent.xbutton.state = state | ShiftMask; + xEvent.xkey.keycode = delta > 0 ? 120 : -120; + xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); + Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); + } + } + else { + printf("Touchpad scroll.\n"); } } diff --git a/win/tkWinX.c b/win/tkWinX.c index c1c6815..f73c739 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -36,20 +36,12 @@ #define WM_MOUSEHWHEEL 0x020E #endif -/* This flag is set in the state of the MouseWheelEvent to indicate - * that the value stored in the keycode field should be interpreted - * as the number of pixels to scroll. A WM_MOUSEWHEEL message sent - * by a trackpad contains the number of pixels as the delta value, - * while low precision scrollwheels always send an integer multiple - * of WHEELDELTA (= 120) as the delta value. We set this flag - * whenever the WM_MOUSEWHEEL delta is not a multiple of 120. This - * ignores the (rare) possibility that a trackpad might generate - * a message with delta a multiple of 120, intended to be interpreted - * as pixels. If that proves annoying it will need to be addressed. +/* A WM_MOUSEWHEEL message sent by a trackpad contains the number of pixels as + * the delta value, while low precision scrollwheels always send an integer + * multiple of WHEELDELTA (= 120) as the delta value. */ #define WHEELDELTA 120 -#define HiresScrollMask (1 << 9) /* * Our heuristic for deciding whether a WM_MOUSEWHEEL message @@ -1153,21 +1145,22 @@ GenerateXEvent( int delta = (short) HIWORD(wParam); int mod = delta % WHEELDELTA; + if ( mod != 0 || lastMod != 0) { + printf("Trackpad scroll\n"); + } else { - /* - * We have invented a new X event type to handle this event. It - * still uses the KeyPress struct. However, the keycode field has - * been overloaded to hold the zDelta of the wheel. Set nbytes to - * 0 to prevent conversion of the keycode to a keysym in - * TkpGetString. [Bug 1118340]. - */ + /* + * We have invented a new X event type to handle this + * event. It still uses the KeyPress struct. However, the + * keycode field has been overloaded to hold the zDelta of the + * wheel. Set nbytes to 0 to prevent conversion of the keycode + * to a keysym in TkpGetString. [Bug 1118340]. + */ - event.x.type = MouseWheelEvent; - event.x.xany.send_event = -1; - event.key.nbytes = 0; - event.x.xkey.keycode = (unsigned int)delta; - if ( mod != 0 || lastMod != 0) { - event.x.xkey.state |= HiresScrollMask; + event.x.type = MouseWheelEvent; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.keycode = (unsigned int)delta; } lastMod = mod; break; @@ -1179,22 +1172,23 @@ GenerateXEvent( int delta = (short) HIWORD(wParam); int mod = delta % WHEELDELTA; + if ( mod != 0 || lastMod != 0) { + printf("Trackpad scroll\n"); + } else { - /* - * We have invented a new X event type to handle this event. It - * still uses the KeyPress struct. However, the keycode field has - * been overloaded to hold the zDelta of the wheel. Set nbytes to - * 0 to prevent conversion of the keycode to a keysym in - * TkpGetString. [Bug 1118340]. - */ + /* + * We have invented a new X event type to handle this event. It + * still uses the KeyPress struct. However, the keycode field has + * been overloaded to hold the zDelta of the wheel. Set nbytes to + * 0 to prevent conversion of the keycode to a keysym in + * TkpGetString. [Bug 1118340]. + */ - event.x.type = MouseWheelEvent; - event.x.xany.send_event = -1; - event.key.nbytes = 0; - event.x.xkey.state |= ShiftMask; - event.x.xkey.keycode = delta; - if ( mod != 0 || lastMod != 0) { - event.x.xkey.state |= HiresScrollMask; + event.x.type = MouseWheelEvent; + event.x.xany.send_event = -1; + event.key.nbytes = 0; + event.x.xkey.state |= ShiftMask; + event.x.xkey.keycode = delta; } lastMod = mod; break; -- cgit v0.12