158.tip at [c7fc73b883]

Login

File tip/158.tip artifact df76d4b2db part of check-in c7fc73b883


TIP:            158
Title:          Distinguish the two 'Enter' keys on Windows
Version:        $Revision: 1.9 $
Author:         Wolfgang Gro�bauer <[email protected]>
Author:         Kevin Kenny <[email protected]>
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 <Mod4> 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, ''<KeyPress-Return>''
and ''<KeyRelease-Return>'' 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 ''<KeyPress-Return>'' and
''<KeyPress-KP_Enter>'' 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
''<Return>'' will continue to fire for the numeric ''Enter'' key,
unless there is also a binding to ''<Extended-Return>'' which will then
take precedence.

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

Unix code that has distinct bindings for ''<Return>'' and
''<KP_Enter>'' 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 ''<Extended-Return>'' that mirror those for
''<KP_Enter>''. 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 ''<KeyPress-KP_0>'' or ''<Keypress-KP_Multiply>'',
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/[email protected]].

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 ''<KP_Enter>'' 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 ''<Return>'' but not ''<KP_Enter>'' 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
''<KP_*>'' 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.