SUGGESTED FIX
------- awt_Component.cpp -------
*** /tmp/sccs.Ctayev Thu Aug 8 13:50:27 2002
--- awt_Component.cpp Thu Aug 8 13:33:48 2002
***************
*** 1141,1146 ****
--- 1141,1148 ----
LRESULT retValue = 0;
MsgRouting mr = mrDoDefault;
+ static BOOL ignoreNextLBTNUP = FALSE; //Ignore next LBUTTONUP msg?
+
lastMessage = message;
if (message == WmAwtIsComponent) {
***************
*** 1361,1369 ****
case WM_VSCROLL:
mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
break;
case WM_LBUTTONDOWN:
case WM_LBUTTONDBLCLK:
- case WM_LBUTTONUP:
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
case WM_RBUTTONUP:
--- 1363,1388 ----
case WM_VSCROLL:
mr = WmVScroll(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
break;
+ // 4664415: We're seeing a WM_LBUTTONUP when the user releases the
+ // mouse button after a WM_NCLBUTTONDBLCLK. We want to ignore this
+ // WM_LBUTTONUP, so we set a flag in WM_NCLBUTTONDBLCLK and look for the
+ // flag on a WM_LBUTTONUP. -bchristi
+ case WM_NCLBUTTONDBLCLK:
+ ignoreNextLBTNUP = TRUE;
+ break;
+ case WM_NCLBUTTONDOWN:
+ ignoreNextLBTNUP = FALSE;
+ break;
+ case WM_LBUTTONUP:
+ if (ignoreNextLBTNUP) {
+ ignoreNextLBTNUP = FALSE;
+ return mrDoDefault;
+ }
+ //fall-through
case WM_LBUTTONDOWN:
+ ignoreNextLBTNUP = FALSE;
+ //fall-through
case WM_LBUTTONDBLCLK:
case WM_RBUTTONDOWN:
case WM_RBUTTONDBLCLK:
case WM_RBUTTONUP:
###@###.### 2002-08-08
|
EVALUATION
Easily reproducible with the following little test case:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class MyTest extends JFrame implements MouseListener {
JPanel jp;
public MyTest() {
super("MyTest");
jp = new JPanel();
jp.addMouseListener(this);
jp.setBackground(Color.red);
getContentPane().add(jp);
}
public static void main(String[] args) {
MyTest mt = new MyTest();
mt.setSize(400, 400);
mt.show();
}
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed");
}
public void mouseReleased(MouseEvent e) {
System.out.println("mouseReleased");
}
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked");
}
public void mouseEntered(MouseEvent e) {
System.out.println("mouseEnter");
}
public void mouseExited(MouseEvent e) {
System.out.println("mouseExit");
}
}
One interesting behavior: if the JFrame is at the top of the screen, such that the titlebar is already at the top of the screen, the mouseReleased/mouseClicked are not sent to the JPanel. However, with the JFrame towards the bottom of the screen, the events are sent. In any case, this could be serious, and should be looked at soon.
###@###.### 2002-04-19
The problem is that when a window is maximized by double-clicking the titlebar on Windows, the window becomes maximized on the second button PRESS. This can be seen using any top-level window on Windows, such as an Explorer window - you can keep holding the second click. The window maximizes underneath the mouse cursor. This bug happens in part because this second mouse release is being delievered to the JFrame.
Spy++ has uncovered something else interesting - WM_NCLBUTTONUP events don't ever seem to occur. For the action of double-clicking a titlebar to maximize the window, you'd expect to see the following events:
WM_NCLBUTTONDOWN
WM_NCLBUTTONUP
WM_NCLBUTTONDBLCLK
WM_NCLBUTTONUP (or possibly WM_LBUTTONUP, since the window maximizes on the click)
But you get WM_LBUTTONUP messages instead of WM_NCLBUTTONUP.
The first WM_LBUTTONUP is uninteresting to AWT, as it occurs in the non-client area. The cause of this bug is the second WM_LBUTTONUP, which as of 1.4 beta, is handled as a normal MOUSE_RELEASED. I haven't determined why it is that this problem does not exist in 1.3.1 and previous, but it's clear enough that we should be ignoring this WM_LBUTTONUP. It's simple enough to remember where and when the last WM_NCLBUTTONDBLCLK happened, and if the next WM_LBUTTONUP occurs in the same place shortly after, it should be ignored.
###@###.### 2002-08-01
Name: dmR10075 Date: 08/02/2002
This is not a regression. Using the test below I was able to reproduce the bug in
JDK1.2(didn't try earlier versions though). It seems to be very general problem caused
by a Windows quirk.
import java.awt.*;
import java.awt.event.*;
public class Test extends Frame {
public Test() {
super("Test for double-click");
Panel pan;
MouseAdapter ad = new MouseAdapter() {
public void mousePressed(MouseEvent e) {
System.err.println(e);
}
public void mouseReleased(MouseEvent e) {
System.err.println(e);
}
};
add(pan = new Panel());
addMouseListener(ad);
pan.addMouseListener(ad);
pack();
setBounds(10, 10, 100, 100);
setVisible(true);
}
public static void main(String[] args) {
new Test();
}
}
###@###.### 2002-08-02
======================================================================
|