JDK-4074498 : JDK REGRESSION: Setting the cursor to MOVE_CURSOR on Win32 doesn't work.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 1.1.4
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_nt
  • CPU: x86
  • Submitted: 1997-08-26
  • Updated: 1999-01-15
  • Resolved: 1999-01-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other Other
1.1.7 b01Fixed 1.2.0Fixed
Related Reports
Relates :  
Description
The call setting the Cursor to MOVE_CURSOR doesn't seem to work correctly under Win32. When the cursor is changed to MOVE_CURSOR and the pointer is dragged, the previous cursor is drawn. The returned value of getCursor indicates that it has been set to MOVE_CURSOR. Sometimes the MOVE_CURSOR is drawn at the end of the drag.

To reproduce in JWS (sorry I don't have an isolated test case but i've examined the GUI builder code extensively):
- Open a GUI builder project and put a component on the layout. 
- Move the cursor to the edge of the component and when the cursor changes to the HAND_CURSOR you may move the component by dragging it. 
- The MOVE_CURSOR should appear instead of the HAND_CURSOR

If you change the _SS_JDK variable to say JDK1.1.2A it will behave correctly. It also behaves correctly on Sparc. Setting the cursor to the hand cursor seems to work fine.

I noticed that awt_Component.cpp has had some recent modifications with respect to pointer motion and setting the cursor. 


john.walker@Eng 1997-09-04

I believe this same regression is manifesting itself in Java Studio Visual Java.
The cursor no longer changes on a mouse down.

To reproduce:

Bring up Java Studio and instantiate a component (such as the button) 
by selecting the button in the palette and then clicking in the GUI
window.  Now click on the border of the button, the cursor should change
to a move cursor on grow cursor depending on where on the border you
have clicked but it stays as the default cursor.

This behavior works using JDK1.1.2A and JDK1.1.3D.

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: 1.1.7 1.2beta4 FIXED IN: 1.1.7 1.2beta4 INTEGRATED IN: 1.1.7 1.2beta4 1.2fcs
14-06-2004

EVALUATION robert.wilson@Eng 1998-01-09: At Paul Sheehan's request, I have investigated this bug some more. It turns out that there are four or five separate Java WorkShop bug reports that are addressed by the suggested fix for 4074498. The engineer who did this didn't bother to separate out which changes affected which bug, so I've had to do a bit of work to figure it out. Here are my conclusions. The bugs are: 4066822 4065517 4064272 4062238 4074498 The problems described in 4062238 and 4074498 have already been addressed by the fix for 4038721. The fix for 4038721 is almost exactly the same change as shown here for awt_Component.h and awt_Component.cpp. (I hope the engineer who fixed 4038721 didn't spend a lot of time coming up with the same fix that we already had....) So, you don't need to worry about the changes to the awt_Component files. I cannot reproduce the problem described in 4064272. If Robert Bruce is still in the AWT group, you might want to ask him about his comment in the suggested fix section of 4064272. That leaves two open problems. I can still reproduce 4065517 on JDK 1.1.5 running on NT 4.0. I sent mail to Paul Sheehan with instructions for reproducing this in Java WorkShop. I wish I had a smaller test program, but I don't really understand this stuff well enough to write one. I've verified that the changes to awt_Canvas.h and awt_Canvas.cpp fix this problem (at least in the context of JDK 1.1.5), but I suppose you'll want to do that yourself as well. I don't understand the change well enough to assess whether it is really the right thing to do. Hopefully you can do that. The other problem is 4066822. This problem still occurs with the changes to awt_Canvas, but it is fixed when I include the changes to awt_Toolkit. If you can find someone there (Robert Bruce?) who understands why that chunk of code is in awt_Toolkit and knows whether it can safely be removed, then that would settle the matter. ralph.kar@Eng 1998-03-12 I implemented the suggested fixes for awt_Toolkit.cpp, awt_Canvas.h and awt_Canvas.cpp. I also talked to Tom Ball and Fred Ecks about the changes. Tom wants the code that will be eliminated in awt_Canvas.cpp to be moved to awt_Frame.cpp. I implemented all changes and tested that they will work. I also have a small testcase for 4066822 which I will also check in.
11-06-2004

SUGGESTED FIX kiran.singh@Eng 1997-09-04 [ The changes shown here before were relative to some previous JWS-specific version. It appears that there were a number of related problems. I've combined all the changes and presented the diffs relative to 1.1.4 (and not including changes unrelated to mouse events - bwilson ] robert.wilson@Eng 1997-10-08: Here are the new diffs for this bug and for 4066822, 4065517 and 4064272: *** src/win32/sun/windows/awt_Component.cpp Tue Aug 26 16:08:05 1997 --- awt_Component.cpp Wed Sep 24 13:10:29 1997 *************** *** 996,1033 **** return mrConsume; } - MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y) - { - static AwtComponent* lastComp = NULL; - static int lastX = 0; - static int lastY = 0; // Only report mouse move and drag events if a move or drag actually // happened -- Windows sends a WM_MOUSEMOVE in case the app wants to // modify the cursor. ! if (lastComp != this || x != lastX || y != lastY) { lastComp = this; ! lastX = x; ! lastY = y; - long id; if ((flags&(MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))) { ! if (!m_dragged) { ! // eat the first move in case it is only a click ! m_dragged = TRUE; ! return mrConsume; ! } ! id = java_awt_event_MouseEvent_MOUSE_DRAGGED; ! } else { ! id = java_awt_event_MouseEvent_MOUSE_MOVED; ! } ! MSG* msg = CreateMessage(lastMessage, flags, MAKELPARAM(x, y)); ! SendMouseEvent(id, nowMillis(), x, y, ! GetJavaModifiers(flags, 0), 0, 0, msg); ! } else { ::SetCursor(GetCursor(TRUE)); ! } return mrConsume; } --- 988,1054 ---- return mrConsume; } + // ProcessMouseMove This routine compares the static vars with the + // arguments provided to see if the mouse is being moved, + // dragged or it's a mouse move message (synthesized by + // sun_awt_windows_WComponentPeer_setCursor() or sent by + // Windows) to modify cursor. + short AwtComponent::ProcessMouseMove(UINT flags, int x, int y) + { // Only report mouse move and drag events if a move or drag actually // happened -- Windows sends a WM_MOUSEMOVE in case the app wants to // modify the cursor. ! ! static AwtComponent* lastComp = NULL; ! static int lastX = 0; ! static int lastY = 0; ! ! if (this != lastComp || ! x != lastX || ! y != lastY) { ! lastComp = this; ! lastX = x; ! lastY = y; if ((flags&(MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))) { ! return PMM_MOUSE_DRAG; ! } ! else { ! return PMM_MOUSE_MOVE; ! } ! } ! else { ! return PMM_SET_CURSOR; ! } ! } ! ! MsgRouting AwtComponent::WmMouseMove(UINT flags, int x, int y) ! { ! long id; ! ! switch (ProcessMouseMove (flags, x, y)) { ! case PMM_MOUSE_MOVE: ! id = java_awt_event_MouseEvent_MOUSE_MOVED; ! break; ! case PMM_MOUSE_DRAG: ! m_dragged = TRUE; ! id = java_awt_event_MouseEvent_MOUSE_DRAGGED; ! break; ! case PMM_SET_CURSOR: ::SetCursor(GetCursor(TRUE)); ! return mrConsume; ! default: ! ASSERT(0); ! } ! ! MSG* msg = CreateMessage(lastMessage, flags, MAKELPARAM(x, y)); ! SendMouseEvent(id, nowMillis(), x, y, ! GetJavaModifiers(flags, 0), 0, 0, msg); ! return mrConsume; } *** src/win32/sun/windows/awt_Component.h Tue Aug 26 16:08:06 1997 --- awt_Component.h Wed Sep 24 11:56:52 1997 *************** *** 46,51 **** --- 46,56 ---- #define MIDDLE_BUTTON 2 #define RIGHT_BUTTON 3 + // ProcessMouseMove() return values + #define PMM_MOUSE_MOVE 1 + #define PMM_MOUSE_DRAG 2 + #define PMM_SET_CURSOR 3 + class AwtSharedDC; class AwtPopupMenu; *************** *** 256,261 **** --- 261,269 ---- // Forward a filtered event directly to the subclassed window. MsgRouting HandleEvent(MSG* msg); + // process the mouse msg to determine if it's a move, drag, etc. + short ProcessMouseMove(UINT flags, int x, int y); + // Event->message synthesizer methods. void SynthesizeKeyMessage(Hjava_awt_event_KeyEvent* hEvent); void SynthesizeMouseMessage(Hjava_awt_event_MouseEvent* hEvent); *** src/win32/sun/windows/awt_Toolkit.cpp Fri Oct 10 10:34:46 1997 --- /tmp/getb19810 Fri Oct 10 10:34:46 1997 *************** *** 514,543 **** mouseComp->SendMessage(WM_AWT_MOUSEENTER, mouseWParam, mouseLParam); } - // Look for missed MouseDowns or Ups & create them (which actual button - // is ignored by dispatcher) - if (msg.message >= WM_MOUSEFIRST && msg.message <= WM_MOUSELAST) { - if (msg.wParam&(MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) { - if (!m_mouseDown && - msg.message != WM_LBUTTONDOWN && - msg.message != WM_RBUTTONDOWN && - msg.message != WM_MBUTTONDOWN && - p) { - p->SendMessage(WM_LBUTTONDOWN, msg.wParam, msg.lParam); - } - m_mouseDown = TRUE; - } - if (!(msg.wParam&(MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))) { - if (m_mouseDown && - msg.message != WM_LBUTTONUP && - msg.message != WM_RBUTTONUP && - msg.message != WM_MBUTTONUP && - p) { - p->SendMessage(WM_LBUTTONUP, msg.wParam, msg.lParam); - } - m_mouseDown = FALSE; - } - } m_lastMouseOver = mouseComp; } --- 514,519 ---- *** src/win32/sun/windows/awt_Canvas.cpp Tue Aug 26 16:08:01 1997 --- awt_Canvas.cpp Wed Sep 24 11:56:09 1997 *************** *** 106,119 **** return mrConsume; } MsgRouting AwtCanvas::WmMouseMove(UINT flags, int x, int y) { - // First mouse move will be ignored, since m_dragged isn't set until - // AwtComponent::WmMouseDown is called. This is on purpose, so that - // frame buttons aren't interfered with. - if (m_dragged && ::GetCapture() != GetHWnd()) { - ::SetCapture(GetHWnd()); - } return AwtComponent::WmMouseMove(flags, x, y); } --- 106,119 ---- return mrConsume; } + MsgRouting AwtCanvas::WmMouseDown(UINT flags, int x, int y, int button) + { + ::SetCapture(GetHWnd()); + return AwtComponent::WmMouseDown(flags, x, y, button); + } + MsgRouting AwtCanvas::WmMouseMove(UINT flags, int x, int y) { return AwtComponent::WmMouseMove(flags, x, y); } *** src/win32/sun/windows/awt_Canvas.h Fri Feb 21 15:16:32 1997 --- awt_Canvas.h Wed Sep 24 10:58:19 1997 *************** *** 45,50 **** --- 45,51 ---- virtual MsgRouting WmEraseBkgnd(HDC hDC, BOOL& didErase); virtual MsgRouting WmPaint(HDC hDC); + virtual MsgRouting WmMouseDown(UINT flags, int x, int y, int button); virtual MsgRouting WmMouseMove(UINT flags, int x, int y); virtual MsgRouting WmMouseUp(UINT flags, int x, int y, int button); virtual MsgRouting WmPrintClient(HDC hDC, UINT flags);
11-06-2004

PUBLIC COMMENTS Cursor was being changed but it wasn't being redrawn right away.
10-06-2004