TIP #158: DISTINGUISH THE TWO 'ENTER' KEYS ON WINDOWS ======================================================= Version: $Revision: 1.9 $ Author: Wolfgang Großbauer Kevin Kenny State: Final Type: Project Tcl-Version: 8.5 Vote: Done Created: Saturday, 20 September 2003 URL: https://tip.tcl-lang.org158.html Discussions-To: news:comp.lang.tcl Post-History: ------------------------------------------------------------------------- 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 ([] and several following threads) and the comp.lang.tcl newsgroup []. 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 [] and []. More recent additional discussion is archived at []. 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 ... "pressReturn" bind ... "pressEnter" ; # only useful on Unix bind ... "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 [] is herewith granted. ------------------------------------------------------------------------- TIP AutoGenerator - written by Donal K. Fellows