EVALUATION
As I found, the main cause of the bug is described here 4212563. Then several fixes were made, but it did not remove all the problems. The fix for this bug should solve them.
|
|
|
SUGGESTED FIX
webrev: http://javaweb.sfbay/jcg/7/swing/6544309/
mail-archive: http://sa.sfbay.sun.com/mail-archive/6544309
The fix for 6492266 turned out not so good. Some annoying problems weren't eliminated. The problem was in the fact, that the IM menu is handled by different EDT than it's parent. The fix made the menu always heavyweight.
I invited a new simple approach. All the problems will be solved if the menu and it's parent will be handled with the same EDT. I wrote a code, which finds EDT of the menu parent and uses it to show the menu.
Also I found and fixed a related problem, which consists in IM menu inaccessibility for keyboard input just after menu appearance.
The cause is in BasicPopupMenuUI.MenuKeyboardHelper.stateChanged() method. The method is responsible also for finding of a popup menu invoker and for assigning an input map to it. Now if the invoker is JDialog, the input map isn't assigned.
A couple of lines of code fixed the problem.
Finally, I had to cut off a part of the test case for 6492266 because, in fact, I partially rolled back the fix for 6492266.
|
|
|
WORK AROUND
Use mouse to select items from the Input Method Selection popup menu.
|
|
|
EVALUATION
It's not a regression. 'Select Input Method' menu behaves in the same wrong way even in 1.5 (I tested 1.5.0_08). The fix for 6492266 removes a regression from 6280964, but not fixes this problem. In fact, the problem appeared when menu keyboard handling had been moved to menu parent's root pane. As I found if the parent is a JDialog, a child popup menu cannot be handled with keyboard at all.
|
|
|
EVALUATION
---------
The problem of 'Select Input Method' menu inaccessibility for keyboard input just after it's appearance:
The cause is in BasicPopupMenuUI.MenuKeyboardHelper.stateChanged() method. The method is responsible also for finding of a popup menu invoker and for assigning an input map to it. Now if the invoker is JDialog, the input map isn't assigned. Look at the code:
Component c = popup.getInvoker();
if(c instanceof JFrame) {
invoker = ((JFrame)c).getRootPane();
} else if(c instanceof JApplet) {
invoker = ((JApplet)c).getRootPane();
} else {
while (!(c instanceof JComponent)) {
if (c == null) {
return;
}
c = c.getParent();
}
invoker = (JComponent)c;
}
An addition of the following two lines almost solves the problem:
} else if(c instanceof JDialog) {
invoker = ((JDialog)c).getRootPane();
Also we should ensure that keyboard events are serviced by proper EDT (see the explanation of second problem's cause below). It can be achieved by requesting focus for the popup menu window.
---------
The problem consisting in an impossibility to close 'Select Input Method' menu clicking by mouse outside the menu:
As I supposed, the problem has the same nature as 6492266. The menu and the parent dialog window are serviced by different EDTs. When user clicks somewhere inside the dialog, BasicPopupMenuUI.cancelPopupMenu() is called to close all opened popups. However the method closes only popups, which are serviced by current EDT. So the menu, belonging to the other EDT, remains opened.
I don't have an idea how to fix the problem in the general way, but for 'Select Input Method' menu it can be almost fixed with a menu's FocusListener. When the focus is gone, menu should be closed.
|
|
|
EVALUATION
Really there is the problem with 'input method selection' menu. It doesn't get the focus when it appears. All keyboard input is received by the parent window. However, you can make keyboard working in the menu. For this purpose you should place mouse cursor above the menu and keyboard will start work.
Most likely the problem with focus is not connected with 6492266, because the menu doesn't get focus even in 1.5.
There is one more problem: if you click somewhere in parent window while the menu is shown, the menu won't be closed, although it should.
I almost sure that the second problem is a regression of 6280964 when mouse grabber and keyboard helper became sored in application context.
|
|
|
|