FlatLaf icon indicating copy to clipboard operation
FlatLaf copied to clipboard

AWT native code freezee at sun.awt.windows.WGlobalCursorManager#findHeavyweightUnderCursor

Open VISTALL opened this issue 1 year ago • 2 comments

Hello. I'm testing FlatLaf as default laf for Consulo IDE (https://github.com/consulo), which is an IDEA fork.

I want replace internal laf implementation by FlatLaf, but catch very strange freeze at sun.awt.windows.WGlobalCursorManager#findHeavyweightUnderCursor. Freeze can appear in random time (there no specific time when, app can start - I can do something, and catch UI lock, or just at start)

JRE: 21.0.2+13-b375.1 (JetBrains s.r.o.) JVM: 21.0.2+13-b375.1 (OpenJDK 64-Bit Server VM)

Using last library version

Also tested with Adoptium JDK 21 - some issue.

Any guess?

"AWT-EventQueue-0@4684" tid=0x56 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
	 blocks AWT-Windows@3479
	  at sun.awt.windows.WGlobalCursorManager.findHeavyweightUnderCursor(WGlobalCursorManager.java:-1)
	  at sun.awt.GlobalCursorManager._updateCursor(GlobalCursorManager.java:178)
	  at sun.awt.GlobalCursorManager.updateCursorImmediately(GlobalCursorManager.java:95)
	  at sun.awt.windows.WComponentPeer.updateCursorImmediately(WComponentPeer.java:710)
	  at java.awt.Component.updateCursorImmediately(Component.java:3259)
	  at java.awt.Container.validate(Container.java:1672)
	  at com.formdev.flatlaf.ui.FlatRootPaneUI$FlatRootLayout.layoutContainer(FlatRootPaneUI.java:630)
	  at java.awt.Container.layout(Container.java:1541)
	  at java.awt.Container.doLayout(Container.java:1530)
	  at java.awt.Container.validateTree(Container.java:1725)
	  at java.awt.Container.validate(Container.java:1660)
	  - locked <0x5d93> (a java.awt.Component$AWTTreeLock)
	  at javax.swing.RepaintManager$3.run(RepaintManager.java:760)
	  at javax.swing.RepaintManager$3.run(RepaintManager.java:758)
	  at java.security.AccessController.executePrivileged(AccessController.java:778)
	  at java.security.AccessController.doPrivileged(AccessController.java:400)
	  at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	  at javax.swing.RepaintManager.validateInvalidComponents(RepaintManager.java:757)
	  at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1911)
	  at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
	  at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:781)
	  at java.awt.EventQueue$4.run(EventQueue.java:728)
	  at java.awt.EventQueue$4.run(EventQueue.java:722)
	  at java.security.AccessController.executePrivileged(AccessController.java:778)
	  at java.security.AccessController.doPrivileged(AccessController.java:400)
	  at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	  at java.awt.EventQueue.dispatchEvent(EventQueue.java:750)
	  at consulo.desktop.awt.ui.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:769)
	  at consulo.desktop.awt.ui.IdeEventQueue._dispatchEvent(IdeEventQueue.java:680)
	  at consulo.desktop.awt.ui.IdeEventQueue.lambda$dispatchEvent$5(IdeEventQueue.java:367)
	  at consulo.desktop.awt.ui.IdeEventQueue$$Lambda/0x0000000800bfe2d0.compute(Unknown Source:-1)
	  at consulo.application.impl.internal.progress.CoreProgressManager.computePrioritized(CoreProgressManager.java:770)
	  at consulo.desktop.awt.ui.IdeEventQueue.lambda$dispatchEvent$6(IdeEventQueue.java:366)
	  at consulo.desktop.awt.ui.IdeEventQueue$$Lambda/0x0000000800bfe090.run(Unknown Source:-1)
	  at consulo.desktop.awt.ui.IdeEventQueue.dispatchEvent(IdeEventQueue.java:405)
	  at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
	  at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
	  at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
	  at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
	  at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
	  at java.awt.EventDispatchThread.run(EventDispatchThread.java:92)

VISTALL avatar Aug 14 '24 14:08 VISTALL

Disabling window decoration (-Dflatlaf.useWindowDecorations=false) looks like fix issue

VISTALL avatar Aug 14 '24 17:08 VISTALL

My research. I attached VS for application and found this:

Native Call Stack image

Deeper

image

Found source code

image

And I'm stuck at that point

VISTALL avatar Aug 15 '24 21:08 VISTALL

Not sure how I could help 😕 Don't see any relation to FlatLaf in provided information.

The stack in your initial post shows that thread AWT-EventQueue-0 "blocks AWT-Windows@3479". Could you post the stack of the blocked thread AWT-Windows?

DevCharly avatar Sep 03 '24 17:09 DevCharly

Hello. I'm 100% sure stuck in native code inside FlatLaf library code, but I'm don't known how found the problem

VISTALL avatar Sep 03 '24 17:09 VISTALL

I will try

VISTALL avatar Sep 03 '24 17:09 VISTALL

Sometimes lock not inside AppMenu - but same position (heavy cursor find). Here another thread image

VISTALL avatar Sep 03 '24 18:09 VISTALL

I think it would be better to use jstack to get more information (stack of all threads, blocked threads, etc).

See https://intellij-support.jetbrains.com/hc/en-us/articles/206544899-Getting-a-thread-dump-when-IDE-hangs-and-doesn-t-respond

DevCharly avatar Sep 03 '24 20:09 DevCharly

log.txt

VISTALL avatar Sep 03 '24 20:09 VISTALL

This is interesting.

Thread AWT-Windows is blocked while handling WM_NCHITTEST message:

"AWT-Windows" #71 [12588] daemon prio=6 os_prio=0 cpu=421.88ms elapsed=132.46s tid=0x0000020ac2435ed0 nid=12588 waiting for monitor entry  [0x000000b0657fd000]
   java.lang.Thread.State: BLOCKED (on object monitor)
	at java.awt.Component.getLocationOnScreen([email protected]/Component.java:2118)
==>	- waiting to lock <0x000000020713be18> (a java.awt.Component$AWTTreeLock)
	at javax.swing.SwingUtilities.convertPointToScreen([email protected]/SwingUtilities.java:437)
	at javax.swing.SwingUtilities.convertPoint([email protected]/SwingUtilities.java:197)
==>	at consulo.ide.impl.idea.ui.BalloonImpl$MyComponent.contains(consulo.ide.impl@3-SNAPSHOT/BalloonImpl.java:1953)
	at com.formdev.flatlaf.ui.FlatTitlePane.isTitleBarCaptionAt(com.formdev.flatlaf/FlatTitlePane.java:1082)
	at com.formdev.flatlaf.ui.FlatTitlePane.isTitleBarCaptionAt(com.formdev.flatlaf/FlatTitlePane.java:1127)
	at com.formdev.flatlaf.ui.FlatTitlePane.captionHitTest(com.formdev.flatlaf/FlatTitlePane.java:1077)
	at com.formdev.flatlaf.ui.FlatTitlePane$$Lambda/0x0000020a7c6c0240.test(com.formdev.flatlaf/Unknown Source)
==>	at com.formdev.flatlaf.ui.FlatWindowsNativeWindowBorder$WndProc.onNcHitTest(com.formdev.flatlaf/FlatWindowsNativeWindowBorder.java:379)
	at sun.awt.windows.WToolkit.eventLoop([email protected]/Native Method)
	at sun.awt.windows.WToolkit.run([email protected]/WToolkit.java:360)
	at java.lang.Thread.runWith([email protected]/Thread.java:1596)
	at java.lang.Thread.run([email protected]/Thread.java:1583)

Here is thread AWT-EventQueue-0, which owns the AWT lock:

"AWT-EventQueue-0" #86 [19664] prio=6 os_prio=0 cpu=5921.88ms elapsed=131.73s tid=0x0000020ac2434490 nid=19664 runnable  [0x000000b0633fe000]
   java.lang.Thread.State: RUNNABLE
	at sun.awt.windows.WGlobalCursorManager.findHeavyweightUnderCursor([email protected]/Native Method)
	at sun.awt.GlobalCursorManager._updateCursor([email protected]/GlobalCursorManager.java:178)
	at sun.awt.GlobalCursorManager.updateCursorImmediately([email protected]/GlobalCursorManager.java:95)
	at sun.awt.windows.WComponentPeer.updateCursorImmediately([email protected]/WComponentPeer.java:710)
	at java.awt.Component.updateCursorImmediately([email protected]/Component.java:3259)
	at java.awt.Container.validate([email protected]/Container.java:1672)
	at com.formdev.flatlaf.ui.FlatRootPaneUI$FlatRootLayout.layoutContainer(com.formdev.flatlaf/FlatRootPaneUI.java:630)
	at java.awt.Container.layout([email protected]/Container.java:1541)
	at java.awt.Container.doLayout([email protected]/Container.java:1530)
	at java.awt.Container.validateTree([email protected]/Container.java:1725)
	at java.awt.Container.validate([email protected]/Container.java:1660)
==>	- locked <0x000000020713be18> (a java.awt.Component$AWTTreeLock)
	at javax.swing.RepaintManager$3.run([email protected]/RepaintManager.java:762)
	at javax.swing.RepaintManager$3.run([email protected]/RepaintManager.java:760)

So the problem is causes by consulo.ide.impl.idea.ui.BalloonImpl$MyComponent.contains(x, y), which invokes SwingUtilities.convertPoint() on thread AWT-Windows while AWT is locked on thread AWT-EventQueue-0.

If you (temporary) change consulo.ide.impl.idea.ui.BalloonImpl$MyComponent.contains(x, y) to simply return false, the application should no longer freeze.

On FlatLaf side, I'll remove the invocation of Component.contains(x, y) to avoid that problem/risk. I'll also review the code that runs on thread AWT-Windows...

DevCharly avatar Sep 03 '24 22:09 DevCharly

fixed in latest 3.6-SNAPSHOT: https://github.com/JFormDesigner/FlatLaf#snapshots

DevCharly avatar Sep 03 '24 22:09 DevCharly

Good day. I will test, thanks for possible fix :)

VISTALL avatar Sep 04 '24 07:09 VISTALL

Looks like - bug fixed, I can't reproduce for now. I had misscheck AWT-Windows thread locking.

This logic also exists in IDEA (https://github.com/JetBrains/intellij-community/blob/master/platform/platform-impl/src/com/intellij/ui/BalloonImpl.java#L2011)

BalloonImpl its notifications,etc component ui.

VISTALL avatar Sep 04 '24 15:09 VISTALL