Tk Source Code

Ticket Change Details
Bounty program for improvements to Tcl and certain Tcl packages.

Artifact ID: 8066a8660902cc956b3728203205c28f4e1bc523b27d4abb065113ad93ce15af
Ticket: 1fb7af623ac45badc115df0b3515a4e552400508
Add support for buttons 4 and 5 to Windows
User & Date: chrstphrchvz 2019-07-20 14:52:32

  1. Change comment to:

    The attached patch attempts to add support for mouse buttons 4 and 5 to Tk for Windows. (These buttons are called XButton1 and XButton2 in the Windows API documentation.) Currently, Tk programs on Windows do not detect these buttons at all, even with <ButtonPress>. I believe that these buttons, if not repurposed by the user, should be available to Tk programs, as they currently are on Aqua (as buttons 4 and 5) and X11 (as buttons 8 and 9). One common binding for these buttons is for back/forward navigation in browsers.

    I am not sure to what extent this functionality has been requested in the past, or whether any efforts were made to implement support for them (either in Tk or extensions). I found one discussion from 2011 on comp.lang.tcl:!msg/comp.lang.tcl/LpEULzrhjBI/gbNOyXyYMX4J. The non-functionality of buttons 4 and 5 on Windows was more recently mentioned in discussions regarding TIP #474.

    I believe support for these buttons can be added to 8.6, and not have to wait for 8.7. There is indeed a likelihood that existing programs bind to buttons 4 and 5 to allow scrolling on X11, yet fail to restrict those bindings to when [tk windowingsystem] is "x11"; however, those programs already exhibit this issue on Aqua. (I informed the author of TIP #474 that their existing implementation would exhibit this issue. Edit: maybe it doesn't affect Windows…)

    There is one detail in the implementation I am not very certain of: whether wparam should only be assigned MK_XBUTTON1 or MK_XBUTTON2, rather than MAKEWPARAM(MK_XBUTTON1, XBUTTON1) or MAKEWPARAM(MK_XBUTTON2, XBUTTON2), in the following:

    @@ -1783,6 +1787,14 @@ TkWinResendEvent(
            msg = WM_RBUTTONDOWN;
            wparam = MK_RBUTTON;
    +    case Button4:
    +       msg = WM_XBUTTONDOWN;
    +       wparam = MAKEWPARAM(MK_XBUTTON1, XBUTTON1);
    +       break;
    +    case Button5:
    +       msg = WM_XBUTTONDOWN;
    +       wparam = MAKEWPARAM(MK_XBUTTON2, XBUTTON2);
    +       break;
            return 0;

    I do not know exactly what TkWinResendEvent() is used for, but I imagine that the way I have written this allows whatever processing the event to check which button is pressed from HIWORD(wparam) (e.g. using the GET_XBUTTON_WPARAM(wparam) macro), rather than only by checking for MK_XBUTTON1 or MK_XBUTTON2.

    One script for manually testing this:

    package require Tk

    label .l -text "Click here" -height 10 -width 30 pack .l bind .l <4> {puts "Button 4 clicked"} bind .l <5> {puts "Button 5 clicked"}

    To test this without an actual 5-button mouse, a tool to emulate the button presses can be used, such as AutoHotKey with a script that maps keypresses to buttons 4 and 5:



    I have successfully tested this implementation on Windows 10 1903 x64, based on top of recent core-8-6-branch [3e5c0ebb].

  2. Change icomment to:
    I'm a bit unsure about the impact of this improvement on TIP #474, which in its implementation (in the generic code, see [77c390bae2700c72]) turns button-4 and button-5 into a <MouseWheel> event.

    Here's the thread with my feedback to the author of TIP #474, for reference:

    The issue that I predicted, and observed on Aqua when trying the TIP #474 implementation, was that <4> and <5> would be converted to <MouseWheel>, and no longer seen as <4> or <5> by the program. Essentially, clicking the extra buttons would become equivalent to rotating the scrollwheel by one or more notches on non-X11. I strongly suspected this issue also applied to Windows, but had not confirmed it; and I wasn't yet aware that I wouldn't be able to confirm it, due to support for buttons 4 and 5 not even being implemented on Windows.

    However, after properly trying both my patch and the TIP #474 implementation simultaneously, I don't observe the issue on Windows, as I had on Aqua; the program still sees <4> and <5> instead of <MouseWheel>. I guess the Windows code never gets to the part of UpdateButtonEventState() affected by TIP #474. But it's still probably clearer/safer to make sure that any <4> or <5> usage in generic code checks that the windowingsystem is X11 if those buttons are being used for scrolling.

  3. Change login to "chrstphrchvz"
  4. Change mimetype to "text/x-fossil-wiki"
  5. Change username to "chrstphrchvz"