TIP 158: Distinguish the two 'Enter' keys on Windows

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Author:         Wolfgang Großbauer <Go2DevNull@magro-soft.com>
Author:         Kevin Kenny <kennykb@acm.org>
State:          Final
Type:           Project
Vote:           Done
Created:        20-Sep-2003
Post-History:   
Discussions-To: news:comp.lang.tcl
Tcl-Version:    8.5

Abstract

This TIP proposes that the "extended keys" on a Windows keyboard be labeled with so that they can be distinguished from their counterparts on the main keyboard.

Rationale

Most US keyboards on Windows systems have two keys bearing the label, 'Enter'. The Tk system generates the events, and for both of them; the two keys are indistinguishable. While this behavior is in keeping with the "Microsoft Windows User Experience Guidelines," which explicitly state that the two keys should command identical functionality, it is inconvenient for developers who wish to port Unix applications that already have different actions bound to the and events.

Specification

The solution that has been chosen supports the greatest possible backward compatibility. What is proposed is that 'tkWinX.c' will examine the KF_EXTENDED bit in the keyboard state (passed as lParam to the GetState function) and map it as modifier 4. (Modifiers 1 through 3, respectively, refer to the Num Lock, Alt, and Scroll Lock keys.) An alias shall be added so that Extended may be used in place of Mod4.

This change has little if any impact on existing Windows code, since modifier 4 is not generated on Windows today. A binding to will continue to fire for the numeric Enter key, unless there is also a binding to which will then take precedence.

Existing Unix code that binds and to identical functionality (and does not bind ) will also not need to change. Again, the existing binding will fire for the Enter keys on both the main keyboard and the numeric pad.

Unix code that has distinct bindings for and does not function correctly on Windows today - and cannot be made to do so without changing its specification. To port such code to Windows once this change is in place, a developer will have to add bindings to that mirror those for . Once the developer has done this, the application will distinguish the two keys and fire the appropriate binding for each.

Although the immediate purpose of the change is to deal with the numeric Enter key, the effect of the change will be to deal with the rest of the numeric pad the same way; rather than generating events such as or , the system will generate events representing the corresponding keys on the main keyboard, with modifier 4 set to distinguish them. These events are less likely to need to be rebound, since they correspond to printing characters and seldom if ever have different bindings between the numeric pad and the main keyboard.

Reference Implementation

The changes require to implement an earlier version of this proposal can be obtained from SourceForge as Tk Patch #797404.

Summary of Discussion

This change has been discussed extensively on the tcl-core mailing list (http://aspn.activestate.com/ASPN/Mail/Message/tcl-core/1791694 and several following threads) and the comp.lang.tcl newsgroup http://groups.google.com/groups?threadm=3F520749.8080808@acm.org .

The chief proposed alternative to the use of modifier 4 was to modify tkWinX.c so that the Enter key on the numeric pad would generate the same event that it does on Unix. The drawback to this proposal, making it unacceptable to the authors of this TIP, is that existing user code on Windows that establishes bindings to but not would no longer recognize the numeric Enter key. This problem was seen as a far greater drawback than the need for those porting Unix applications (and wishing to continue to operate inconsistently with the Microsoft guidelines) to add an additional binding, particularly in light of the fact that those applications today can't implement the desired functionality on Windows at all.

One proposed workaround was to have a default all binding for events on Windows fire the corresponding binding for a non-KP keysym. Unfortunately, this solution introduces even worse surprising behavior. A conventional binding to the KP_* keysym will have to include a break or return -code break in order to avoid having this all binding fire - and making it appear as if both keys had been pressed or released.

The open issue of what to do about the problem on the Macintosh platform remains. The authors of this TIP are too ignorant of Macintosh programming to address it.

This proposal has engendered a fair amount of controversy, as may be seen in the two threads of messages beginning from http://aspn.activestate.com/ASPN/Mail/Message/1811543 and http://aspn.activestate.com/ASPN/Mail/Message/1820298 .

More recent additional discussion is archived at http://aspn.activestate.com/ASPN/Mail/Message/2032516 . Vince Darley summarizes it:

For example, there is Benny's suggestion to your all counterexample that the counterexample really contains a bug, since any key-binding ought to have ;break to prevent exactly that problem. Do we guarantee backwards compatibility even with buggy code?

Second there is the suggestion that if you really don't want the all binding to fire if another binding has triggered, you could actually check for that manually (scan the bindtags list, etc). This would reduce the backwards incompatibility of an overall cleaner solution to effectively nothing.

Third, the TIP contains no mention of what the result of this TIP is on the x-platform Tk developer. That they must now have this:

 bind ... <Return>  "pressReturn"
 bind ... <KP_Enter>  "pressEnter" ; # only useful on Unix
 bind ... <Extended-Return>  "pressEnter" ; # only useful on Windows

i.e. rather than making their life easier, it has been made more complex! (In fact the TIP as a whole seems to have a bias against anyone even considering writing the same application on multiple platforms, which seems v. odd for Tk)

Copyright

Copyright © 2003, 2004 by Kevin B. Kenny. All rights reserved.

Permission to use this document in accordance with the terms of Open Publication License http://www.opencontent.org/openpub/ is herewith granted.

History