|
Quick Lists
|
|
Bug ID:
|
6522725
|
|
Votes
|
0
|
|
Synopsis
|
Component in a minimized Frame has focus and receives key events
|
|
Category
|
java:classes_awt
|
|
Reported Against
|
|
|
Release Fixed
|
7(b27)
|
|
State
|
10-Fix Delivered,
bug
|
|
Priority:
|
3-Medium
|
|
Related Bugs
|
|
|
Submit Date
|
08-FEB-2007
|
|
Description
|
This behavior is reproducable starting 5.0 on Linux and Solaris. It is not reproducable on Windows
I've a FocusListener added to a button in a frame. When FOCUS_LOST is triggered for the button, I'm calling requestFocus on the button to return the focus to the button. Even if I minimize the frame, focus stays on the button and pressing enter key triggers ActionEvent for the button
To reproduce:
1. Run the code below
2. When the Frames come up, notice that the focus is on the 'Click me' button.
3. Minimize the Frame, see that FocusOwner is still the button on minimized Frame (see the console output)
4. Press the space bar and it could be seen that action event is triggered for button (see the console output)
import java.awt.*;
import java.awt.event.*;
public class Test {
private Button b1, b2;
public static void main(String[] args) {
new Test();
new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("Focus Owner: " +
KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner());
try { Thread.sleep(5000); } catch (Exception e) {}
}
}
}).start();
}
public Test() {
Frame f = new Frame("F1");
Frame f2 = new Frame("F2");
f2.setLayout(new FlowLayout());
f2.add(new Button("Sample"));
f.setLayout(new FlowLayout());
b1 = new Button("Click me");
b1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
System.out.println("Action performed");
}
});
b2 = new Button("Second Button");
b1.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent event) {
System.out.println("Button focus gained");
}
public void focusLost(FocusEvent event) {
System.out.println("Button focus lost");
b1.requestFocus();
}
});
f.add(b1);
f.add(b2);
f2.setLocation(0, 200);
f2.setSize(150, 150);
f2.setVisible(true);
f.setSize(150, 150);
f.setVisible(true);
}
}
Posted Date : 2007-02-08 06:14:22.0
|
|
Work Around
|
N/A
|
|
Evaluation
|
Reproducibility:
| 1.4.2 | 1.5 | 1.6 | 1.7
---------------------------------------------------------
WinXP | - | - | - | -
----------------------------------------------------------
Linux | - | + | + | +
metacity 2.16 | b25 | | |
----------------------------------------------------------
Solaris | - | - | + | +
metacity 2.16 | | | b24 |
Posted Date : 2007-02-16 10:19:49.0
The focus isn't switched and stays on the "Click Me" button in three cases:
1. Minimizing F1 (F2 gets hightlighted).
2. Clicking on F2 (F2 gets hightlighted).
3. Clicking on some native window.
The reason is that there are three different states of the focused window:
1. native focused window
2. peer focused window
3. java focused window
When the focus is requested on the ClickMe button in the FOCUS_LOST listener,
after another toplevel has been clicked, then at that time the values of focused
window are as follows:
1. native focused window = clicked toplevel
2. peer focused window = null
3. java focused window = F1
As the java focused window is not yet changed, the reaction on the focus request
(see XComponentPeer.requestFocus) is just to post FOCUS_GAINED event. By the time
when this event has reached DKFM, F1 window has already got WINDOW_LOST_FOCUS.
DKFM detects that current java focused window differs from the parent of the
ClickMe button (i.e. F1) and it simply synchronously sends WINDOW_GAINED_FOCUS
on F1.
I've considered 3 solutions:
1. On native level, when the focus is requested in window that is not native
focused window but is still java focused window, I'm requesting focus in it
instead of posting FOCUS_GAINED.
With this fix, when I click in F2 a focus flicker happens b/w F1 & F2.
(see webrev6522725_1.tgz attached)
2. The same as 1st, but I'm requesting focus via posting it to EDT (that is I'm
postponing the request).
This fix breaks many focus regression tests.
(see webrev6522725_2.tgz attached)
3. Forbid synchronously sending WINDOW_GAINED_FOCUS when we receive FOCUS_GAINED
on a window that is not java focused window.
Actually I this this was originally wrong decision. Synthesizing WINDOW_GAINED_FOCUS
does nothing without focusing the toplevel on native level. So I'm staying on this
variant so far.
Posted Date : 2007-07-27 14:31:32.0
I faced with some problem investigating the 3rd suggestion above. On MS Windows
when one switches focus b/w an owned window and the owner, the latter is not
sent WM_ACTIVATE (as the native focus is on the proxy, that belongs to the owner).
The only event posted to Java is FOCUS_GAINED. Thus it's assumed that DKFM will
synthesize WINDOW_GAINED_FOCUS itself. It's excatly that code I thought to remove...
On XAWT, a frame is always sent WINDOW_GAINED_FOCUS as it receives WM_TAKE_FOCUS
on native level every time user clicks in it.
Probably we can do something similar in MS Windows. Investigating it.
Posted Date : 2007-08-09 07:51:50.0
I made a fix that disallows posting FOCUS_GAINED ahead of WINDOW_GAINED_FOCUS in case
of requesting focus in an active owner when its owned window is currently focused.
Looks like it works good (see attached webrev6522725-3.tgz).
However I discovered some doc snipped in The Focus Spec:
A KeyboardFocusManager must ensure proper event ordering, and a 1-to-1 correspondence
between an event and its opposite event type. The peer layer does not make any of these
guarantees. For example, it is possible for the peer layer to send a FOCUS_GAINED event
before a WINDOW_GAINED_FOCUS event. The KeyboardFocusManager is responsible for
ensuring that the WINDOW_GAINED_FOCUS event is dispatched before the FOCUS_GAINED
event.
It means that we can't remove synthesizing WINDOW_GAINED_FOCUS without modifying
this text. And I guess that we should try to avoid doing the latter... =(
The idea is to leave that code in the DKFM, but restrict it only to cases when
focus is switched b/w windows of the same decorated owner (i.e. when native focus
is set on a proxy that belongs to the owner).
- - -
Also. The reason of reg test failures with the 2nd fix (see above entries) is
that I didn't detect focus switches b/w an owner and an owned windows. This should
have been specially processed. Though, I consider this fix still not the safest.
Posted Date : 2007-08-09 13:57:37.0
|
|
Comments
|
PLEASE NOTE: JDK6 is formerly known as Project Mustang
|
|
|
 |