JDK-6242833 : Mouse cursor doesn't behave correctly after maximizing on Linux/JDS 3
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 5.0,5.0u5
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux,linux_2.6
  • CPU: other,x86
  • Submitted: 2005-03-18
  • Updated: 2011-01-19
  • Resolved: 2006-03-20
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.
JDK 6
6 b77Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
When you launch swing application and maximize it on Linux/JDS 3, the mouse cursor starts to change on wrong positions. The incorrect behaviour can is visible on SwingSet2 Demo in JDK. Steps to reproduce:

1. Launch the demo and choose JSplitPane (the one with astronaut). 
2. Maximize the window. 
3. Try to hover over the splitting line between the two images. The cursor doesn't change from arrow to the sliding cursor.

This bug seems to influence all swing applications. I report it due to problematic behaviour in NetBeans, there are many mouse cursor changes which stop to work correctly when the window is maximized.
###@###.### 2005-03-18 15:52:47 GMT

Comments
SUGGESTED FIX But after some more investigation we found that there is nothing could break if we just handle all of xcrossing events. So another fix look less safe but simple: --- XWindow.java 2006-02-06 12:55:06.000000000 +0300 *************** *** 751,761 **** if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xce.toString()); - // Skip event If it was caused by a grab - if (xce.get_mode() != NotifyNormal) { - return; - } - // X sends XCrossing to all hierarchy so if the edge of child equals to // ancestor and mouse enters child, the ancestor will get an event too. // From java point the event is bogus as ancestor is obscured, so if --- 751,756 ----
06-02-2006

EVALUATION Seems there is no reasons to filter these XCrossing events based on their mode. So we should just handle all events. Suggested fix section contain two variants of the fix and the last one (simple one) should go into workspace.
06-02-2006

EVALUATION This bug happens often (on awt-linux-01, linux machines) because (as described in my previous email) we skip crossingEvent and doesn't initialize XAwtState's componentEntered variable. That variable is then used in GlobalCursorManager to change cursor shape. Initially I though it's WM error and it just misses one Enter/LeaveNotify event but further testing uncovered a bug in awt : XWindow.java : handleXCrossingEvent() skip events if they are not in NotifyNormal mode. I found that only some actions may lead to skipping that event. (There are two instances will be considered in following: XContentWindow and XFramePeer.) In particular: 1) double clicking on titlebar of the window (it if leads to maximization) In this case we obtain 1) missed xEvent == XCrossingEvent = type = EnterNotify, sun.awt.X11.XFramePeer@1c5f743(2c00007), mode = 2, detail = 1 2) missed xEvent == XCrossingEvent = type = EnterNotify, sun.awt.X11.XContentWindow@2803d5(2c0000e), mode = 2, detail = 0 Mode 2 means NotifyUngrab (it happens on second mouse release) Detail 0 means NotifyAncestor Detail 1 - NotifyVirtual How does it work. When there are three windows: A(this is a root window), B(XFramePeer), C(XContentWindow) and A is a parent of B and B is a parent of C and crossing happens from A to C then B will receive NotifyVirtual and C - NotifyAncestor. You would imagine that similar things happen on crossing in other direction. 2) On pressing Alt-Tab: Now lets consider pressing ALT+TAB (although there are no complains on it in CR) Java window initially activated and pointer over it and over other window so when you release kbd pointer will come to different window: (events will arrive on PRESS - this is significant) 1) missed xEvent == XCrossingEvent = type = LeaveNotify, sun.awt.X11.XContentWindow@2803d5(2c0000e), mode = 1, detail = 0 2) missed xEvent == XCrossingEvent = type = LeaveNotify, sun.awt.X11.XFramePeer@1c5f743(2c00007), mode = 1, detail = 1 Similar situation - crossing happens affecting same windows like before: Mode 1 == NotifyGrab XContentWindow recieves NotifyAncestor and XFramePeer - NotifyVirtual as a middle-point in this chain. 3) On pressin ALT+TAB Other (read "native") window initially activated and pointer over it and over Java window: (events arrives on RELEASE - significant) 1) missed xEvent == XCrossingEvent = type = EnterNotify, sun.awt.X11.XFramePeer@1c5f743(2c00007), mode = 2, detail = 1 2) missed xEvent == XCrossingEvent = type = EnterNotify, sun.awt.X11.XContentWindow@2803d5(2c0000e), mode = 2, detail = 0 You would notice exactly the same situation as in case 1). We should correctly handle these events. I'm not sure about reasons of filtering them for now and I'd filter them more precisely respecting cases described above.
19-12-2005

EVALUATION After previous evaluation one place need to be clarified much: sun.awt.GlobalCursorManager uses findHeavyweightUnderCursor() that actually returns cached XAwtState.componentMouseEnteredRef component. If some of EnterNotify event has missed then we probably get wrong componentUnder mouse variable. There is another approach in MToolkit : we handle reference to current component under mouse on native level.
12-12-2005

SUGGESTED FIX At first we considered the most safe fix that affected xcrossing event handling within XWindow: now we won't spik it if it has NotifyGrab or NotifyUngrab modes. --- /net/karanar/export/dav/mustang67//webrev/src/solaris/classes/sun/awt/X11/XWindow.java ���� ������ 20 16:42:37 2005 *** 749,760 **** super.handleXCrossingEvent(ptr); XCrossingEvent xce = new XCrossingEvent(ptr); if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xce.toString()); // Skip event If it was caused by a grab ! if (xce.get_mode() != NotifyNormal) { return; } // X sends XCrossing to all hierarchy so if the edge of child equals to // ancestor and mouse enters child, the ancestor will get an event too. --- 749,776 ---- super.handleXCrossingEvent(ptr); XCrossingEvent xce = new XCrossingEvent(ptr); if (eventLog.isLoggable(Level.FINEST)) eventLog.finest(xce.toString()); + // 6242833 : Mouse cursor doesn't behave correctly after maximizing on Linux/JDS 3 + // On Maximize with double click on titlebar + // or _releasing_ ALT+TAB on other window so java window becomes active + boolean shouldHandle = false; + if (xce.get_mode() == NotifyUngrab && + (xce.get_detail() == NotifyVirtual || + xce.get_detail() == NotifyAncestor)) { + shouldHandle = true; + } + //On pressing ALT+TAB on java window + if (xce.get_mode() == NotifyGrab && + (xce.get_detail() == NotifyVirtual || + xce.get_detail() == NotifyAncestor)) { + shouldHandle = true; + } + // Skip event If it was caused by a grab ! if (xce.get_mode() != NotifyNormal && !shouldHandle) { return; } // X sends XCrossing to all hierarchy so if the edge of child equals to // ancestor and mouse enters child, the ancestor will get an event too.
08-12-2005

EVALUATION Cursor change is the result of Enter|LeaveNotify event. We set XAwtState.setComponentMouseEntered() before changing cursor (XWindow.handleXCrossingEvent()). But seems there is no any EnterNotify events (as well as LeaveNotify) while maximizing window even mouse pointer is actually still inside toplevel. Similar effect seen if we restore down ("normalize") that window. I noticed that if I restore window and move mouse back into inner space of that window there is no EnterNotify event again. (But it will happen if you move mouse slowly into that window.) Believe the last one is a timing issue and shouldn't be considered like a bug. To fix decribed problem we would make a detection of changing state of the window and initialize WeakRef on component under mouse. I tried to implement it in XFramePeer and it does work for SwingSet. To be honest, it's unsufficient just to set that component to "this" in the cases of Maximization/Restoring. We should invent how to find that correct component.
08-12-2005