IJPL-158075 use flow instead of deprecated alarm for moveOrResizeRequests

GitOrigin-RevId: af5833e031fb27e379f1bc4dd558fd522ad6bd6c
This commit is contained in:
Vladimir Krivosheev
2024-07-11 13:23:29 +02:00
committed by intellij-monorepo-bot
parent 547c08495a
commit 184812fb0d
5 changed files with 58 additions and 38 deletions

View File

@@ -2985,7 +2985,8 @@ f:com.intellij.util.SingleAlarm
- <init>(java.lang.Runnable,I,com.intellij.openapi.Disposable):V
- <init>(java.lang.Runnable,I,com.intellij.openapi.Disposable,com.intellij.util.Alarm$ThreadToUse):V
- <init>(java.lang.Runnable,I,com.intellij.openapi.Disposable,com.intellij.util.Alarm$ThreadToUse,com.intellij.openapi.application.ModalityState):V
- b:<init>(java.lang.Runnable,I,com.intellij.openapi.Disposable,com.intellij.util.Alarm$ThreadToUse,com.intellij.openapi.application.ModalityState,I,kotlin.jvm.internal.DefaultConstructorMarker):V
- <init>(java.lang.Runnable,I,com.intellij.openapi.Disposable,com.intellij.util.Alarm$ThreadToUse,com.intellij.openapi.application.ModalityState,kotlinx.coroutines.CoroutineScope):V
- b:<init>(java.lang.Runnable,I,com.intellij.openapi.Disposable,com.intellij.util.Alarm$ThreadToUse,com.intellij.openapi.application.ModalityState,kotlinx.coroutines.CoroutineScope,I,kotlin.jvm.internal.DefaultConstructorMarker):V
- <init>(java.lang.Runnable,I,com.intellij.util.Alarm$ThreadToUse,com.intellij.openapi.Disposable):V
- f:cancel():V
- f:cancelAllRequests():I
@@ -2996,13 +2997,14 @@ f:com.intellij.util.SingleAlarm
- f:isDisposed():Z
- f:isEmpty():Z
- f:request():V
- f:request(com.intellij.openapi.application.ModalityState):V
- f:request(Z):V
- f:request(Z,I):V
- bs:request$default(com.intellij.util.SingleAlarm,Z,I,I,java.lang.Object):V
- sf:singleAlarm(I,kotlinx.coroutines.CoroutineScope,java.lang.Runnable):com.intellij.util.SingleAlarm
- f:waitForAllExecuted(J,java.util.concurrent.TimeUnit):V
f:com.intellij.util.SingleAlarm$Companion
- f:pooledThreadSingleAlarm(I,com.intellij.openapi.Disposable,kotlin.jvm.functions.Function0):com.intellij.util.SingleAlarm
- f:singleAlarm(I,kotlinx.coroutines.CoroutineScope,java.lang.Runnable):com.intellij.util.SingleAlarm
f:com.intellij.util.WaitForProgressToShow
- s:execute(com.intellij.openapi.progress.ProgressIndicator):V
- s:runOrInvokeAndWaitAboveProgress(java.lang.Runnable):V

View File

@@ -12713,7 +12713,7 @@ a:com.intellij.ide.GeneratedSourceFileChangeTracker
f:com.intellij.ide.GeneratedSourceFileChangeTrackerImpl
- com.intellij.ide.GeneratedSourceFileChangeTracker
- s:IN_TRACKER_TEST:Z
- <init>(com.intellij.openapi.project.Project):V
- <init>(com.intellij.openapi.project.Project,kotlinx.coroutines.CoroutineScope):V
- cancelAllAndWait(J,java.util.concurrent.TimeUnit):V
- isEditedGeneratedFile(com.intellij.openapi.vfs.VirtualFile):Z
f:com.intellij.ide.NativeIconProvider

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.openapi.wm.impl;
import com.intellij.ide.ui.UISettings;
@@ -89,8 +89,8 @@ public final class FloatingDecorator extends JDialog implements FloatingDecorato
if (LOG.isDebugEnabled()) {
LOG.debug("Updating floating window " + toolWindow.getId() + " bounds because it's closed: " + getBounds());
}
toolWindow.getToolWindowManager().movedOrResized(decorator);
toolWindow.getToolWindowManager().hideToolWindow(toolWindow.getId(), false);
toolWindow.toolWindowManager.movedOrResized(decorator);
toolWindow.toolWindowManager.hideToolWindow(toolWindow.getId(), false);
}
});
addComponentListener(new ComponentAdapter() {

View File

@@ -1,4 +1,6 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:OptIn(FlowPreview::class)
package com.intellij.openapi.wm.impl
import com.intellij.icons.AllIcons
@@ -17,6 +19,7 @@ import com.intellij.openapi.Disposable
import com.intellij.openapi.actionSystem.*
import com.intellij.openapi.actionSystem.ex.ActionUtil
import com.intellij.openapi.actionSystem.impl.FusAwareAction
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.diagnostic.logger
@@ -44,12 +47,21 @@ import com.intellij.ui.scale.JBUIScale
import com.intellij.util.ArrayUtil
import com.intellij.util.ModalityUiUtil
import com.intellij.util.SingleAlarm
import com.intellij.util.cancelOnDispose
import com.intellij.util.concurrency.SynchronizedClearableLazy
import com.intellij.util.ui.*
import com.intellij.util.ui.update.Activatable
import com.intellij.util.ui.update.UiNotifyConnector
import kotlinx.collections.immutable.PersistentList
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jetbrains.annotations.ApiStatus
import java.awt.AWTEvent
import java.awt.Color
@@ -62,16 +74,18 @@ import java.util.function.Supplier
import javax.swing.*
import kotlin.math.abs
internal class ToolWindowImpl(val toolWindowManager: ToolWindowManagerImpl,
private val id: String,
private val canCloseContent: Boolean,
private val dumbAware: Boolean,
component: JComponent?,
private val parentDisposable: Disposable,
windowInfo: WindowInfo,
private var contentFactory: ToolWindowFactory?,
private var isAvailable: Boolean = true,
private var stripeTitleProvider: Supplier<@NlsContexts.TabTitle String>) : ToolWindowEx {
internal class ToolWindowImpl(
@JvmField val toolWindowManager: ToolWindowManagerImpl,
private val id: String,
private val canCloseContent: Boolean,
private val dumbAware: Boolean,
component: JComponent?,
private val parentDisposable: Disposable,
windowInfo: WindowInfo,
private var contentFactory: ToolWindowFactory?,
private var isAvailable: Boolean = true,
private var stripeTitleProvider: Supplier<@NlsContexts.TabTitle String>,
) : ToolWindowEx {
@JvmField
var windowInfoDuringInit: WindowInfoImpl? = null
@@ -119,25 +133,12 @@ internal class ToolWindowImpl(val toolWindowManager: ToolWindowManagerImpl,
private val contentManager = SynchronizedClearableLazy {
val result = createContentManager()
if (toolWindowManager.isNewUi) {
result.addContentManagerListener(UpdateBackgroundContentManager(decorator))
result.addContentManagerListener(UpdateBackgroundContentManager())
}
result
}
private val moveOrResizeAlarm = SingleAlarm(
task = Runnable {
val decorator = decorator
if (decorator != null) {
toolWindowManager.log().debug { "Invoking scheduled tool window $id bounds update" }
toolWindowManager.movedOrResized(decorator)
}
val updatedWindowInfo = toolWindowManager.getLayout().getInfo(getId()) as WindowInfo
this@ToolWindowImpl.windowInfo = updatedWindowInfo
toolWindowManager.log().debug { "Updated window info: $updatedWindowInfo" }
},
delay = 100,
parentDisposable = disposable,
)
private val moveOrResizeRequests = MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST)
init {
if (component != null) {
@@ -146,9 +147,26 @@ internal class ToolWindowImpl(val toolWindowManager: ToolWindowManagerImpl,
contentManager.addContent(content)
contentManager.setSelectedContent(content, false)
}
toolWindowManager.coroutineScope.launch {
moveOrResizeRequests
.debounce(100)
.collectLatest {
withContext(Dispatchers.EDT) {
val decorator = decorator
if (decorator != null) {
toolWindowManager.log().debug { "Invoking scheduled tool window $id bounds update" }
toolWindowManager.movedOrResized(decorator)
}
val updatedWindowInfo = toolWindowManager.getLayout().getInfo(getId()) as WindowInfo
this@ToolWindowImpl.windowInfo = updatedWindowInfo
toolWindowManager.log().debug { "Updated window info: $updatedWindowInfo" }
}
}
}.cancelOnDispose(disposable)
}
private class UpdateBackgroundContentManager(private val decorator: InternalDecoratorImpl?) : ContentManagerListener {
private class UpdateBackgroundContentManager() : ContentManagerListener {
override fun contentAdded(event: ContentManagerEvent) {
InternalDecoratorImpl.setBackgroundRecursively(event.content.component, JBUI.CurrentTheme.ToolWindow.background())
}
@@ -210,7 +228,7 @@ internal class ToolWindowImpl(val toolWindowManager: ToolWindowManagerImpl,
override fun unprocessComponent(component: Component) = Unit
}.register(decorator)
if (ExperimentalUI.isNewUI()) {
scrollPaneTracker = ScrollPaneTracker(decorator, { true }) {
scrollPaneTracker = ScrollPaneTracker(container = decorator, filter = { true }) {
updateScrolledState()
}
}
@@ -310,7 +328,7 @@ internal class ToolWindowImpl(val toolWindowManager: ToolWindowManagerImpl,
}
fun onMovedOrResized() {
moveOrResizeAlarm.cancelAndRequest()
check(moveOrResizeRequests.tryEmit(Unit))
}
internal fun setWindowInfoSilently(info: WindowInfo) {

View File

@@ -156,7 +156,7 @@ public final class ToolWindowContentUi implements ContentUI, UiCompatibleDataPro
@Override
public void contentRemoved(@NotNull ContentManagerEvent event) {
if (window.isDisposed() || window.getToolWindowManager().getProject().isDisposed()) {
if (window.isDisposed() || window.toolWindowManager.getProject().isDisposed()) {
return;
}
@@ -183,7 +183,7 @@ public final class ToolWindowContentUi implements ContentUI, UiCompatibleDataPro
else {
return;
}
window.getToolWindowManager()
window.toolWindowManager
.hideToolWindow(window.getId(), /* hideSide = */ false, /* moveFocus = */ true, removeFromStripe, /* source = */ null);
}
}
@@ -268,7 +268,7 @@ public final class ToolWindowContentUi implements ContentUI, UiCompatibleDataPro
return false;
}
ToolWindowManagerImpl manager = window.getToolWindowManager();
ToolWindowManagerImpl manager = window.toolWindowManager;
for (String id : manager.getIdsOn(window.getAnchor())) {
if (id.equals(window.getId())) {
continue;
@@ -699,7 +699,7 @@ public final class ToolWindowContentUi implements ContentUI, UiCompatibleDataPro
public void uiDataSnapshot(@NotNull DataSink sink) {
sink.set(PlatformDataKeys.TOOL_WINDOW, window);
sink.set(PlatformCoreDataKeys.HELP_ID, window.getHelpId());
sink.set(CommonDataKeys.PROJECT, window.getToolWindowManager().getProject());
sink.set(CommonDataKeys.PROJECT, window.toolWindowManager.getProject());
sink.set(CloseAction.CloseTarget.KEY, computeCloseTarget());
if (getCurrentLayout() instanceof MorePopupAware o) {
sink.set(MorePopupAware.KEY_TOOLWINDOW_TITLE, o);