Commit 9cc0bd08 authored by Daniil Ovchinnikov's avatar Daniil Ovchinnikov Committed by intellij-monorepo-bot
Browse files

IDEA-299807 skip mouse press/release events in activity flow

Consider the following:
- mouse is pressed on an item component in the bar;
- MOUSE_PRESSED triggers activity tick;
- the bar is updated from context (which happens immediately because no focus events are in the queue at this point);
- item components are changed;
- mouse click (which should've requested a focus on the clicked component) is not even invoked
  because the clicked component does not exist at this point.

After this change, the activity will be ticked after MOUSE_CLICKED event, after all listeners are run,
one of which can have a chance to request the focus in nav bar, preventing the bar to update its items.

GitOrigin-RevId: 542050befde6ca29314c561b4b5a7b4e218ab3cf
parent d5f6a84e
Showing with 12 additions and 2 deletions
+12 -2
......@@ -22,6 +22,8 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.suspendCancellableCoroutine
import java.awt.AWTEvent
import java.awt.event.MouseEvent
import kotlin.coroutines.resume
internal val isNavbarV2Enabled: Boolean = Registry.`is`("ide.navBar.v2", false)
......@@ -32,12 +34,13 @@ internal fun UISettings.isNavbarShown(): Boolean {
return showNavigationBar && !presentationMode
}
// TODO move to activity tracker?
internal fun activityFlow(): Flow<Unit> {
return channelFlow {
val disposable: Disposable = Disposer.newDisposable()
IdeEventQueue.getInstance().addActivityListener(Runnable {
this.trySend(Unit)
if (!skipActivityEvent(IdeEventQueue.getCurrentEvent())) {
trySend(Unit)
}
}, disposable)
awaitClose {
Disposer.dispose(disposable)
......@@ -45,6 +48,13 @@ internal fun activityFlow(): Flow<Unit> {
}.buffer(Channel.CONFLATED)
}
private fun skipActivityEvent(e: AWTEvent): Boolean {
if (e is MouseEvent && (e.id == MouseEvent.MOUSE_PRESSED || e.id == MouseEvent.MOUSE_RELEASED)) {
return true
}
return false
}
// TODO move to DataManager
internal suspend fun focusDataContext(): DataContext = suspendCancellableCoroutine {
IdeFocusManager.getGlobalInstance().doWhenFocusSettlesDown(Runnable {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment