Closed
Bug 295228
Opened 20 years ago
Closed 19 years ago
Make sure keypress handlers do not expect lowercase letters when Alt/Ctrl is down and are not affected by Caps Lock state
Categories
(Core :: DOM: UI Events & Focus Handling, defect)
Core
DOM: UI Events & Focus Handling
Tracking
()
RESOLVED
FIXED
People
(Reporter: jonitis, Assigned: jonitis)
References
Details
Attachments
(1 file, 3 obsolete files)
(deleted),
patch
|
Details | Diff | Splinter Review |
This is required to fix bug 287179.
This is cross platform fix for bugs like bug 178110, bug 138475, bug 6135, bug
158679 etc.
The idea is to change all consumers of "keypress" to not expect that lowercase
"charCode" will be returned by platform specific Widget code, if Alt/Ctrl
modifier keys are pressed (as it was done in bug 285161).
The platform specific code should return the correct letter case, taking into
account the Shift and Caps Lock key states.
The consumers should perform case insensitive comparison for "charCode". To
distinguish between lower and upper case characters they should explicitly check
the "isShift".
Assignee | ||
Comment 1•20 years ago
|
||
The only consumer that was not upper/lower case ready was:
/mozilla/content/xbl/src/nsXBLPrototypeHandler.cpp
The other files are changed only to make minor cleanup by removing redundant
code, fixing broken debug code etc.
Please note that I've added the Tab as a valid separator for modifier keys in
nsXBLPrototypeHandler::ConstructPrototype (). I hope it is logical to not
distinguish between Tab and Space characters.
Assignee | ||
Comment 2•20 years ago
|
||
Comment on attachment 184318 [details] [diff] [review]
diff -d -u -15
I am not sure whether I selected correct component and even more confused about
who should review/superreview the code. Some changes are in content, other in
layout and even in extensions.
Attachment #184318 -
Flags: superreview?(bzbarsky)
Comment 3•20 years ago
|
||
I'm not sure that calling ToLowerCase on a PRUint32 is a meaningful operation...
In fact, I'm pretty sure that breaks for non-plane-0 characters.
That said, I'm not sure I can do a thorough review of this any time soon (within
a week or more).
bryner, neil, jag might be able to review changes to XBL.
Assignee | ||
Comment 4•20 years ago
|
||
Do you think that I should throw away most significant word by converting to
PRUnichar? Or should I interpret it as a nsAString and perform comparison on it
to allow non-plane-0 characters?
Assignee | ||
Updated•20 years ago
|
Attachment #184318 -
Flags: review?(neil.parkwaycc.co.uk)
Comment 5•20 years ago
|
||
Comment on attachment 184318 [details] [diff] [review]
diff -d -u -15
>- if (!(mKeyMask & cShift))
>- mKeyMask &= ~cShiftMask;
This looks as if it might break bug 104371.
Assignee | ||
Comment 6•20 years ago
|
||
Neil,
At least with patch for bug 287179 I do not see regression with bug 104371. And
even without it everything should work, because both nsHTMLEditor.cpp and
nsPlaintextEditor ignore only Alt, Ctrl and Meta modifiers, but accept the Shift
modifier.
As Boris noticed the case comparison code is not ready for higher plane Unicode
characters. The same problem is within these files:
1. nsXBLPrototypeHandler.cpp
2. nsListControlFrame.cpp
3. nsMenuBarFrame.cpp
4. nsMenuPopupFrame.cpp
I will prepare new patch that fixes all those consumers.
BTW nsImageDocument.cpp and nsIsIndexFrame.cpp do not check the modifier keys
when comparing the GetCharCode. Should not they be restricted to case when no
any modifier key is pressed?
Status: NEW → ASSIGNED
Assignee | ||
Comment 7•20 years ago
|
||
Attachment #184318 -
Attachment is obsolete: true
Assignee | ||
Updated•20 years ago
|
Attachment #184318 -
Flags: superreview?(bzbarsky)
Attachment #184318 -
Flags: review?(neil.parkwaycc.co.uk)
Assignee | ||
Updated•20 years ago
|
Attachment #184405 -
Flags: superreview?(bzbarsky)
Attachment #184405 -
Flags: review?(neil.parkwaycc.co.uk)
Comment 8•20 years ago
|
||
Erm. Why are we just casting that PRUint32* to PRUnichar*? How is that
PRUint32 produced, exactly? That is, higher-plane characters may require more
than two PRUnichars to be encoded, but they may be encoded in a single PRUint32
using UTF-32 or some such...
Assignee | ||
Comment 9•20 years ago
|
||
I am casting &PRUint32 (and not *PRUint32) to *PRUnichar in assumption that that
PRUint32 is in the same form as PRUnichar strings (but not 0 terminated) and
contains one or two UTF16 code points. If it is plane-0 character then higher
two bytes will be 0. If it is non plane-0 character then all four bytes are
significant.
I believe the DOM events specification should say how this PRUint32 is encoded.
But actually there are no other alternatives to the one described above. In
worst case it can enforce the higher two bytes to be 0 and thus limit to the
plane-0 characters, but it will still be compatible with my code, right?
Comment 10•19 years ago
|
||
> in assumption that that PRUint32 is in the same form as PRUnichar strings
I don't believe that's a correct assumption here....
> If it is plane-0 character then higher two bytes will be 0.
Independent of endianness?
Assignee | ||
Comment 11•19 years ago
|
||
> > If it is plane-0 character then higher two bytes will be 0.
>
> Independent of endianness?
At least old code relied on it - it always casted to PRUnichar to throw away the
higher two bytes. If everything worked in old version on all platforms then it
should work with this patch, too.
Example from old nsXBLPrototypeHandler.cpp:
mDetail = key[0]; // PRUint32 is initialized with first character of string
and later used:
if (code != PRUint32(mDetail)) // PRUint32 code compared with PRUnichar
If you think that these assumptions are wrong can you suggest some sample code
to look at. It was my first attempt to use Mozilla string data types and it was
best that I can think of.
Comment 12•19 years ago
|
||
> it always casted to PRUnichar to throw away the higher two bytes.
Given a PRUint32 n, (PRUnichar)n will throw away the two high bytes. On the
other hand, ((PRunichar*)&n)[0] (which is what you are saying is equivalent)
will throw away the second two bytes in the memory layout. Those may be the
high or low bytes, depending on endianness.
In particular, say we are looking at the English character 'A'. The PRUnichar
for this would be 0x41. Depending on endianness, the two bytes in it would be
[0x0 0x41] or [0x41 0x0]. Now a PRUint32 representing that same 'A' would also
be 0x41 _as a number_. The bytes in it would be, depending on endianness,
either [0x0 0x00 0x00 0x41] or [0x41 0x0 0x0 0x0].
In the latter case (little-endian), casting that byte array to PRUnichar* gives
us 0x41 as the fist PRUnichar and 0x0 as the second one. In the former case
(big-endian), you get 0x0 as the FIRST PRUnichar, and 0x41 as the second one.
In other words, it looks like the empty string on a big-endian system.
It sound like we have no clear idea (as in, no one ever stopped to think about
it) of how this PRUint32 encodes a character, so it may make the most sense to
just cast it to PRUnichar as the old code did and file a followup bug to sort
out what happens with non-plane-0 stuff. :(
Assignee | ||
Comment 13•19 years ago
|
||
Then first version of patch should be ok for this temporary solution. Should I
change the review '?' flags back to it again?
About this followup bug. In which component should it be? DOM events?
Comment 14•19 years ago
|
||
Yeah, if the first patch version does the right thing there, just switch the
flags to it... And yes, DOM events.
Assignee | ||
Comment 15•19 years ago
|
||
Then I think the best solution is to add the new
GetCharCode (nsAString& aCharCodeString);
method to the nsDOMKeyboardEvent class in nsDOMKeyboardEvent.cpp.
It will be the same helper method as GetWhich ().
It will allow to hide all endianness details within this method.
What do you think? If you agree with solution should I still do it in a separate
bug?
Comment 16•19 years ago
|
||
Exposed on what interface?
Assignee | ||
Comment 17•19 years ago
|
||
Initially I thought not to expose it to any of interfaces, so that callers
should explicitly cast nsIDOMKeyEvent* to nsDOMKeyboardEvent* before accessing it.
But it could be much more convenient to expose it to the nsIDOMKeyEvent
interface to avoid significant changes in callers.
nsIDOMKeyEvent.idl does not contain FROZEN keyword.
1. Does it mean that I can add extra
readonly attribute string charCode
to this file?
2. Should it be the last line to preserve binary compatibility?
3. Should I change the GUID of interface anyway?
Sorry for too much questions - it's all new for me...
Comment 18•19 years ago
|
||
> so that callers should explicitly cast nsIDOMKeyEvent* to nsDOMKeyboardEvent*
> before accessing it.
That's really not a good solution, imo.
> But it could be much more convenient to expose it to the nsIDOMKeyEvent
Unfortunately, that's not a great solution either. Changes to that interface
need to be pretty carefully thought about (and shouldn't be happening before
1.9, imo, whereas I got the impression that we want this patch for 1.8).
So I'd just file that separate DOM Events bug...
Assignee | ||
Comment 19•19 years ago
|
||
After more investigation seems that GetWhich () is exposed on nsIDOMNSUIEvent
interface. I can expose this new function on this interface then, too. It will
not have sense for Mouse events, but I can add assert for this case.
Comment 20•19 years ago
|
||
The problem is that all the interfaces you're talking about are exposed to
content script; adding new things on them should be done with some care.
Assignee | ||
Comment 21•19 years ago
|
||
Comment on attachment 184318 [details] [diff] [review]
diff -d -u -15
Back to revision 1 of patch.
I will open a followup bug to handle the non-plane-0 characters.
Attachment #184318 -
Attachment is obsolete: false
Attachment #184318 -
Flags: superreview?(bzbarsky)
Attachment #184318 -
Flags: review?(neil.parkwaycc.co.uk)
Assignee | ||
Updated•19 years ago
|
Attachment #184405 -
Attachment is obsolete: true
Attachment #184405 -
Flags: superreview?(bzbarsky)
Attachment #184405 -
Flags: review?(neil.parkwaycc.co.uk)
Comment 22•19 years ago
|
||
Comment on attachment 184318 [details] [diff] [review]
diff -d -u -15
>Index: content/xbl/src/nsXBLPrototypeHandler.cpp
> if (mMisc)
>+ {
Bracing style for this file is:
if () {
}
else {
}
Please follow that?
>+ match = (ToLowerCase(code) == mDetail);
How about ToLowerCase(PRUnichar(code)) to make it clear what's going on?
sr=bzbarsky with those nits picked.
Attachment #184318 -
Flags: superreview?(bzbarsky) → superreview+
Assignee | ||
Comment 23•19 years ago
|
||
Attachment #184318 -
Attachment is obsolete: true
Comment 24•19 years ago
|
||
Dainis, has this landed? Does this need to land for 1.8? If so, this should
probably get into 1.8b4 asap....
Assignee | ||
Comment 25•19 years ago
|
||
No, it still waits for review from Neil and is very far in his review queue.
Comment 26•19 years ago
|
||
Comment on attachment 185448 [details] [diff] [review]
Same as version 1, but with Boris review notes fixed
>+ if (mMisc) {
> aKeyEvent->GetCharCode(&code);
>+ match = (ToLowerCase(PRUnichar(code)) == mDetail);
>+ } else {
> aKeyEvent->GetKeyCode(&code);
>+ match = (code == PRUint32(mDetail));
>+ }
>
>+ if (!match)
> return PR_FALSE;
It seems to me that this can be simplified as follows:
if (!match) =>
if (mMisc ? (ToLowerCase(PRUnichar(code)) != mDetail) : (code !=
PRUint32(mDetail))) =>
if (mMisc ? (PRUint32(ToLowerCase(PRUnichar(code))) != PRUint32(mDetail)) :
(code != PRUint32(mDetail))) =>
if ((mMisc ? PRUint32(ToLowerCase(PRUnichar(code))) : code) !=
PRUint32(mDetail)) =>
if (mMisc)
code = ToLowerCase(PRUnichar(code));
if (code != PRUint32(mDetail))
which can then be merged back in to the existing block. r=me with this fixed. I
tried this on Windows and was glad to see Caps Lock didn't affect j/J keys for
junk mail :-)
Attachment #185448 -
Flags: review+
Assignee | ||
Comment 27•19 years ago
|
||
Neil,
You mean something like this:
PRBool
nsXBLPrototypeHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent)
{
if (mDetail == -1)
return PR_TRUE; // No filters set up. It's generic.
// Get the keycode or charcode of the key event.
PRUint32 code;
if (mMisc) {
aKeyEvent->GetCharCode(&code);
code = ToLowerCase(PRUnichar(code));
}
else
aKeyEvent->GetKeyCode(&code);
if (code != PRUint32(mDetail))
return PR_FALSE;
return ModifiersMatchMask(aKeyEvent);
}
Should be ok. Probably even more readable.
Can you then please check in these changes? I do not have CVS access rights. If
you want new patch then let me know.
Thanks in advance!
Assignee | ||
Comment 28•19 years ago
|
||
Attachment #185448 -
Attachment is obsolete: true
Assignee | ||
Comment 29•19 years ago
|
||
Neil was not in CC list, thus I decided to prepare new patch.
Boris, probably you can check this in?
Once this will be checked in, I will open the followup bug that fixes the non
plane-0 characters in endian independent way.
Comment 30•19 years ago
|
||
I can check this in on trunk tonight or tomorrow; do you want to try to get this
into 1.8? Is it safe enough?
Assignee | ||
Comment 31•19 years ago
|
||
It will be great if you check it on trunk. I think it is safe enough for 1.8,
but you better ask Neil.
Comment 32•19 years ago
|
||
Neil, does that last patch address your comments?
And do you think this is 1.8 material?
Comment 33•19 years ago
|
||
(In reply to comment #32)
>Neil, does that last patch address your comments?
Seems to.
>And do you think this is 1.8 material?
Safe, useful, but not essential.
Comment 34•19 years ago
|
||
Fixed on trunk. If people want this on branch, please request approval.
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
Assignee | ||
Comment 35•19 years ago
|
||
Opened follow-up bug 306627 to fix non 0-plane character problem.
Comment 36•19 years ago
|
||
This caused regression bug 306686 (fixed) and regression bug 307423 (needs fixing).
Assignee | ||
Comment 37•19 years ago
|
||
Probably it is worth to add "any" keyword support for "modifiers" for XUL "key",
like XBL.
Comment 38•19 years ago
|
||
Note that that also involves making the shortcuts display correctly in menus
(I guess that means changes to nsMenuX.cpp and nsMenuFrame.cpp).
Assignee | ||
Updated•19 years ago
|
Attachment #184318 -
Flags: review?(neil.parkwaycc.co.uk)
Comment 39•19 years ago
|
||
Can we turn off the warning?
NS_WARNING("GetCharCode used for wrong key event; should use onkeypress.");
This case is common, a lot of code call it and compare output with 0.
Annoying while debugging.
Assignee | ||
Comment 40•19 years ago
|
||
Sure. Go ahead and comment it out.
Comment 41•19 years ago
|
||
Done.
Comment 42•19 years ago
|
||
ginn.chen@sun.com: you just made a change to /content/ w/o any sign off from a content peer. that's not how things are supposed to be done.
Comment 43•19 years ago
|
||
Ginn, please undo the change you made, and do so ASAP. Checking the charcode of a key event other than keypress is a bug, since the number you get is meaningless. So if you're hitting this a lot during debugging, file bugs on the code that does it. That's why we have the warning! Removing the warning because there's a lot of buggy code that triggers it is very very backwards.
In the future, do NOT check in changes to content without content peer review. Ever. Dainis saying "go ahead" does not constitute content peer review.
Comment 44•19 years ago
|
||
Undo-ed. Sorry, all.
Assignee | ||
Comment 45•19 years ago
|
||
Most of these warnings are not from incorrectly written external callers, but from internall callers that need to get all information about key event (both keycode and charcode), like in:
1. content/xbl/src/nsXBLWindowKeyHandler.cpp, WalkHandlers()
2. extension/typeaheadfind/src/nsTypeAheadFind.cpp, KeyPress()
3.layout/forms/nsTextControlFrame.cpp, DOMEventToNativeKeyEvent()
Comment 46•19 years ago
|
||
Then we should fix said internal callers -- they're asking for the charcode in cases when the answer is meaningless.
Comment 47•19 years ago
|
||
The warnings in GTK builds are due to bug 309316, for what it's worth.
Updated•6 years ago
|
Component: Event Handling → User events and focus handling
You need to log in
before you can comment on or make changes to this bug.
Description
•