add FrameStateListener message bus topic

This commit is contained in:
Vladimir Krivosheev
2019-01-12 21:17:18 +01:00
parent abc15c74cd
commit 9926cce708
12 changed files with 202 additions and 259 deletions
@@ -1,8 +1,8 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.debugger.ui.impl;
import com.intellij.application.Topics;
import com.intellij.ide.FrameStateListener;
import com.intellij.ide.FrameStateManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -43,7 +43,6 @@ public class TipManager implements Disposable, PopupMenuListener {
boolean isFocusOwner();
}
private boolean isOverTip(MouseEvent e) {
if (myCurrentTooltip != null) {
if(!myCurrentTooltip.isShowing()) {
@@ -222,7 +221,7 @@ public class TipManager implements Disposable, PopupMenuListener {
public void hideTooltip() {
hideTooltip(true);
}
public void hideTooltip(boolean now) {
if (myTipPopup == null) return;
@@ -246,7 +245,6 @@ public class TipManager implements Disposable, PopupMenuListener {
private final JComponent myComponent;
private MouseListener myMouseListener = new MyMouseListener();
private MouseMotionListener myMouseMotionListener = new MyMouseMotionListener();
private FrameStateListener myFrameStateListener = new MyFrameStateListener();
private final Alarm myShowAlarm = new Alarm();
private final Alarm myHideAlarm = new Alarm();
@@ -300,7 +298,7 @@ public class TipManager implements Disposable, PopupMenuListener {
myHideCanceller = new MyAwtPreprocessor();
Toolkit.getDefaultToolkit().addAWTEventListener(myHideCanceller, AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK);
FrameStateManager.getInstance().addListener(myFrameStateListener);
Topics.subscribe(FrameStateListener.TOPIC, this, new MyFrameStateListener());
}
@Override
@@ -315,8 +313,6 @@ public class TipManager implements Disposable, PopupMenuListener {
myShowAlarm.cancelAllRequests();
myMouseListener = null;
myMouseMotionListener = null;
FrameStateManager.getInstance().removeListener(myFrameStateListener);
myFrameStateListener = null;
}
private class MyAwtPreprocessor implements AWTEventListener {
@@ -1,14 +1,16 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;
import com.intellij.util.messages.Topic;
/**
* Listener for receiving notifications when the IDEA window is activated or deactivated.
*
* @since 5.0.2
* @see FrameStateManager#addListener(FrameStateListener)
* @see FrameStateManager#removeListener(FrameStateListener)
*/
public interface FrameStateListener {
Topic<FrameStateListener> TOPIC = new Topic<>("FrameStateListener", FrameStateListener.class);
/**
* Called when the IDEA window is deactivated.
*/
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;
import com.intellij.openapi.Disposable;
@@ -27,7 +13,6 @@ import org.jetbrains.annotations.Nullable;
*
* @since 5.0.2
*/
public abstract class FrameStateManager {
/**
* Returns the global {@code FrameStateManager} instance.
@@ -39,11 +24,15 @@ public abstract class FrameStateManager {
}
/**
* Adds a listener which is called when the IDEA window is activated or deactivated.
*
* @param listener the listener instance.
* @deprecated Use message bus {@link FrameStateListener#TOPIC}
*/
@Deprecated
public abstract void addListener(@NotNull FrameStateListener listener);
/**
* @deprecated Use message bus {@link FrameStateListener#TOPIC}
*/
@Deprecated
public abstract void addListener(@NotNull FrameStateListener listener, @Nullable Disposable disposable);
/**
@@ -1,4 +1,4 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;
import com.intellij.openapi.application.ApplicationManager;
@@ -32,10 +32,12 @@ public class FileChangedNotificationProvider extends EditorNotifications.Provide
private final Project myProject;
public FileChangedNotificationProvider(@NotNull Project project, @NotNull FrameStateManager frameStateManager) {
public FileChangedNotificationProvider(@NotNull Project project) {
myProject = project;
frameStateManager.addListener(new FrameStateListener() {
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(myProject);
connection.subscribe(FrameStateListener.TOPIC, new FrameStateListener() {
@Override
public void onFrameActivated() {
if (!myProject.isDisposed() && !GeneralSettings.getInstance().isSyncOnFrameActivation()) {
@@ -45,9 +47,8 @@ public class FileChangedNotificationProvider extends EditorNotifications.Provide
}
}
}
}, project);
});
MessageBusConnection connection = ApplicationManager.getApplication().getMessageBus().connect(myProject);
connection.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener() {
@Override
public void after(@NotNull List<? extends VFileEvent> events) {
@@ -1,26 +1,11 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.impl.ApplicationImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.BusyObject;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -32,18 +17,16 @@ public class FrameStateManagerImpl extends FrameStateManager {
private final List<FrameStateListener> myListeners = ContainerUtil.createLockFreeCopyOnWriteList();
private final BusyObject.Impl myActive;
private final ApplicationImpl myApp;
public FrameStateManagerImpl(final ApplicationImpl app) {
myApp = app;
public FrameStateManagerImpl() {
myActive = new BusyObject.Impl() {
@Override
public boolean isReady() {
return myApp.isActive();
return ApplicationManager.getApplication().isActive();
}
};
app.getMessageBus().connect().subscribe(ApplicationActivationListener.TOPIC, new ApplicationActivationListener() {
ApplicationManager.getApplication().getMessageBus().connect().subscribe(ApplicationActivationListener.TOPIC, new ApplicationActivationListener() {
@Override
public void applicationActivated(@NotNull IdeFrame ideFrame) {
System.setProperty("com.jetbrains.suppressWindowRaise", "false");
@@ -54,7 +37,7 @@ public class FrameStateManagerImpl extends FrameStateManager {
@Override
public void applicationDeactivated(@NotNull IdeFrame ideFrame) {
System.setProperty("com.jetbrains.suppressWindowRaise", "true");
if (!app.isDisposed()) {
if (!ApplicationManager.getApplication().isDisposed()) {
fireDeactivationEvent();
}
}
@@ -80,19 +63,16 @@ public class FrameStateManagerImpl extends FrameStateManager {
@Override
public void addListener(@NotNull FrameStateListener listener) {
addListener(listener, null);
myListeners.add(listener);
}
@Override
public void addListener(@NotNull final FrameStateListener listener, @Nullable Disposable disposable) {
myListeners.add(listener);
if (disposable != null) {
Disposer.register(disposable, new Disposable() {
@Override
public void dispose() {
removeListener(listener);
}
});
ApplicationManager.getApplication().getMessageBus().connect(disposable).subscribe(FrameStateListener.TOPIC, listener);
}
else {
myListeners.add(listener);
}
}
@@ -1,202 +1,162 @@
/*
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide;
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.TransactionGuard;
import com.intellij.openapi.application.impl.LaterInvocator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
import com.intellij.openapi.vfs.newvfs.RefreshQueue;
import com.intellij.openapi.vfs.newvfs.RefreshSession;
import com.intellij.util.SingleAlarm;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.application.TransactionGuard
import com.intellij.openapi.application.impl.LaterInvocator
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.diagnostic.debug
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.ProjectManager
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.newvfs.ManagingFS
import com.intellij.openapi.vfs.newvfs.NewVirtualFile
import com.intellij.openapi.vfs.newvfs.RefreshQueue
import com.intellij.util.SingleAlarm
import java.beans.PropertyChangeListener
import java.util.concurrent.atomic.AtomicInteger
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
private val LOG = Logger.getInstance(SaveAndSyncHandler::class.java)
/**
* @author Anton Katilin
* @author Vladimir Kondratyev
*/
public class SaveAndSyncHandlerImpl extends SaveAndSyncHandler implements Disposable {
private static final Logger LOG = Logger.getInstance(SaveAndSyncHandler.class);
class SaveAndSyncHandlerImpl(private val settings: GeneralSettings, fileDocumentManager: FileDocumentManager) : SaveAndSyncHandler(), Disposable {
private val generalSettingsListener: PropertyChangeListener
private val refreshDelayAlarm = SingleAlarm(Runnable { this.doScheduledRefresh() }, delay = 300, parentDisposable = this)
private val blockSaveOnFrameDeactivationCount = AtomicInteger()
private val blockSyncOnFrameActivationCount = AtomicInteger()
@Volatile
private var refreshSessionId: Long = 0
private final Runnable myIdleListener;
private final PropertyChangeListener myGeneralSettingsListener;
private final GeneralSettings mySettings;
private final ProgressManager myProgressManager;
private final SingleAlarm myRefreshDelayAlarm = new SingleAlarm(this::doScheduledRefresh, 300, this);
private final AtomicInteger myBlockSaveOnFrameDeactivationCount = new AtomicInteger();
private final AtomicInteger myBlockSyncOnFrameActivationCount = new AtomicInteger();
private volatile long myRefreshSessionId;
public SaveAndSyncHandlerImpl(@NotNull GeneralSettings generalSettings,
@NotNull ProgressManager progressManager,
@NotNull FrameStateManager frameStateManager,
@NotNull FileDocumentManager fileDocumentManager) {
mySettings = generalSettings;
myProgressManager = progressManager;
myIdleListener = () -> {
if (mySettings.isAutoSaveIfInactive() && canSyncOrSave()) {
TransactionGuard.submitTransaction(ApplicationManager.getApplication(), () -> ((FileDocumentManagerImpl)fileDocumentManager).saveAllDocuments(false));
private val idleListener = {
if (settings.isAutoSaveIfInactive && canSyncOrSave()) {
submitTransaction {
(fileDocumentManager as FileDocumentManagerImpl).saveAllDocuments(false)
}
};
IdeEventQueue.getInstance().addIdleListener(myIdleListener, mySettings.getInactiveTimeout() * 1000);
}
}
myGeneralSettingsListener = new PropertyChangeListener() {
@Override
public void propertyChange(@NotNull PropertyChangeEvent e) {
if (GeneralSettings.PROP_INACTIVE_TIMEOUT.equals(e.getPropertyName())) {
IdeEventQueue eventQueue = IdeEventQueue.getInstance();
eventQueue.removeIdleListener(myIdleListener);
Integer timeout = (Integer)e.getNewValue();
eventQueue.addIdleListener(myIdleListener, timeout.intValue() * 1000);
}
init {
IdeEventQueue.getInstance().addIdleListener(idleListener, settings.inactiveTimeout * 1000)
generalSettingsListener = PropertyChangeListener { e ->
if (GeneralSettings.PROP_INACTIVE_TIMEOUT == e.propertyName) {
val eventQueue = IdeEventQueue.getInstance()
eventQueue.removeIdleListener(idleListener)
eventQueue.addIdleListener(idleListener, (e.newValue as Int) * 1000)
}
};
mySettings.addPropertyChangeListener(myGeneralSettingsListener);
}
settings.addPropertyChangeListener(generalSettingsListener)
frameStateManager.addListener(new FrameStateListener() {
@Override
public void onFrameDeactivated() {
LOG.debug("save(): enter");
TransactionGuard.submitTransaction(ApplicationManager.getApplication(), () -> {
val busConnection = ApplicationManager.getApplication().messageBus.connect(this)
busConnection.subscribe(FrameStateListener.TOPIC, object : FrameStateListener {
override fun onFrameDeactivated() {
LOG.debug("save(): enter")
submitTransaction {
if (canSyncOrSave()) {
saveProjectsAndDocuments();
saveProjectsAndDocuments()
}
LOG.debug("save(): exit");
});
}
@Override
public void onFrameActivated() {
if (!ApplicationManager.getApplication().isDisposed() && mySettings.isSyncOnFrameActivation()) {
scheduleRefresh();
LOG.debug("save(): exit")
}
}
});
}
@Override
public void dispose() {
RefreshQueue.getInstance().cancelSession(myRefreshSessionId);
mySettings.removePropertyChangeListener(myGeneralSettingsListener);
IdeEventQueue.getInstance().removeIdleListener(myIdleListener);
}
private boolean canSyncOrSave() {
return !LaterInvocator.isInModalContext() && !myProgressManager.hasModalProgressIndicator();
}
@Override
public void saveProjectsAndDocuments() {
Application app = ApplicationManager.getApplication();
if (!app.isDisposed() &&
mySettings.isSaveOnFrameDeactivation() &&
myBlockSaveOnFrameDeactivationCount.get() == 0) {
app.saveAll();
}
}
@Override
public void scheduleRefresh() {
myRefreshDelayAlarm.cancelAndRequest();
}
private void doScheduledRefresh() {
TransactionGuard.submitTransaction(this, () -> {
if (canSyncOrSave()) {
refreshOpenFiles();
override fun onFrameActivated() {
if (!ApplicationManager.getApplication().isDisposed && settings.isSyncOnFrameActivation) {
scheduleRefresh()
}
}
maybeRefresh(ModalityState.NON_MODAL);
});
})
}
public void maybeRefresh(@NotNull ModalityState modalityState) {
if (myBlockSyncOnFrameActivationCount.get() == 0 && mySettings.isSyncOnFrameActivation()) {
RefreshQueue queue = RefreshQueue.getInstance();
queue.cancelSession(myRefreshSessionId);
override fun dispose() {
RefreshQueue.getInstance().cancelSession(refreshSessionId)
settings.removePropertyChangeListener(generalSettingsListener)
IdeEventQueue.getInstance().removeIdleListener(idleListener)
}
RefreshSession session = queue.createSession(true, true, null, modalityState);
session.addAllFiles(ManagingFS.getInstance().getLocalRoots());
myRefreshSessionId = session.getId();
session.launch();
LOG.debug("vfs refreshed");
}
else if (LOG.isDebugEnabled()) {
LOG.debug("vfs refresh rejected, blocked: " + (myBlockSyncOnFrameActivationCount.get() != 0)
+ ", isSyncOnFrameActivation: " + mySettings.isSyncOnFrameActivation());
private fun canSyncOrSave(): Boolean {
return !LaterInvocator.isInModalContext() && !ProgressManager.getInstance().hasModalProgressIndicator()
}
override fun saveProjectsAndDocuments() {
val app = ApplicationManager.getApplication()
if (!app.isDisposed &&
settings.isSaveOnFrameDeactivation &&
blockSaveOnFrameDeactivationCount.get() == 0) {
app.saveAll()
}
}
@Override
public void refreshOpenFiles() {
List<VirtualFile> files = ContainerUtil.newArrayList();
override fun scheduleRefresh() {
refreshDelayAlarm.cancelAndRequest()
}
for (Project project : ProjectManager.getInstance().getOpenProjects()) {
for (VirtualFile file : FileEditorManager.getInstance(project).getSelectedFiles()) {
if (file instanceof NewVirtualFile) {
files.add(file);
private fun doScheduledRefresh() {
submitTransaction {
if (canSyncOrSave()) {
refreshOpenFiles()
}
maybeRefresh(ModalityState.NON_MODAL)
}
}
fun maybeRefresh(modalityState: ModalityState) {
if (blockSyncOnFrameActivationCount.get() == 0 && settings.isSyncOnFrameActivation) {
val queue = RefreshQueue.getInstance()
queue.cancelSession(refreshSessionId)
val session = queue.createSession(true, true, null, modalityState)
session.addAllFiles(*ManagingFS.getInstance().localRoots)
refreshSessionId = session.id
session.launch()
LOG.debug("vfs refreshed")
}
else {
LOG.debug { "vfs refresh rejected, blocked: ${blockSyncOnFrameActivationCount.get() != 0}, isSyncOnFrameActivation: ${settings.isSyncOnFrameActivation}" }
}
}
override fun refreshOpenFiles() {
val files = ArrayList<VirtualFile>()
for (project in ProjectManager.getInstance().openProjects) {
for (file in FileEditorManager.getInstance(project).selectedFiles) {
if (file is NewVirtualFile) {
files.add(file)
}
}
}
if (!files.isEmpty()) {
// refresh open files synchronously so it doesn't wait for potentially longish refresh request in the queue to finish
RefreshQueue.getInstance().refresh(false, false, null, files);
RefreshQueue.getInstance().refresh(false, false, null, files)
}
}
@Override
public void blockSaveOnFrameDeactivation() {
LOG.debug("save blocked");
myBlockSaveOnFrameDeactivationCount.incrementAndGet();
override fun blockSaveOnFrameDeactivation() {
LOG.debug("save blocked")
blockSaveOnFrameDeactivationCount.incrementAndGet()
}
@Override
public void unblockSaveOnFrameDeactivation() {
myBlockSaveOnFrameDeactivationCount.decrementAndGet();
LOG.debug("save unblocked");
override fun unblockSaveOnFrameDeactivation() {
blockSaveOnFrameDeactivationCount.decrementAndGet()
LOG.debug("save unblocked")
}
@Override
public void blockSyncOnFrameActivation() {
LOG.debug("sync blocked");
myBlockSyncOnFrameActivationCount.incrementAndGet();
override fun blockSyncOnFrameActivation() {
LOG.debug("sync blocked")
blockSyncOnFrameActivationCount.incrementAndGet()
}
@Override
public void unblockSyncOnFrameActivation() {
myBlockSyncOnFrameActivationCount.decrementAndGet();
LOG.debug("sync unblocked");
override fun unblockSyncOnFrameActivation() {
blockSyncOnFrameActivationCount.decrementAndGet()
LOG.debug("sync unblocked")
}
}
private inline fun submitTransaction(crossinline handler: () -> Unit) {
TransactionGuard.submitTransaction(this, Runnable { handler() })
}
}
@@ -1,20 +1,22 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.internal.statistic.updater;
import com.intellij.application.Topics;
import com.intellij.concurrency.JobScheduler;
import com.intellij.ide.FrameStateListener;
import com.intellij.ide.FrameStateManager;
import com.intellij.internal.statistic.connect.StatisticsService;
import com.intellij.internal.statistic.eventLog.FeatureUsageLogger;
import com.intellij.internal.statistic.service.fus.collectors.FUStatisticRecorder;
import com.intellij.internal.statistic.service.fus.collectors.FUStatisticsStateService;
import com.intellij.internal.statistic.utils.StatisticsUploadAssistant;
import com.intellij.notification.impl.NotificationsConfigurationImpl;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.BaseComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.project.ProjectManagerListener;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.wm.WindowManager;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
@@ -41,8 +43,6 @@ public class StatisticsJobsScheduler implements BaseComponent {
public static final int PERSIST_SESSIONS_INITIAL_DELAY_IN_MIN = 30;
public static final int PERSIST_SESSIONS_DELAY_IN_MIN = 12 * 60;
private final FrameStateManager myFrameStateManager;
private static final Map<Project, Future> myPersistStatisticsSessionsMap = Collections.synchronizedMap(new HashMap<>());
@Override
@@ -53,9 +53,8 @@ public class StatisticsJobsScheduler implements BaseComponent {
runStatisticsSessionsPersistence();
}
public StatisticsJobsScheduler(@NotNull FrameStateManager frameStateManager) {
public StatisticsJobsScheduler() {
NotificationsConfigurationImpl.remove("SendUsagesStatistics");
myFrameStateManager = frameStateManager;
}
private static boolean isEmpty(Window window) {
@@ -69,15 +68,16 @@ public class StatisticsJobsScheduler implements BaseComponent {
return false;
}
private void runStatisticsService() {
private static void runStatisticsService() {
if (StatisticsUploadAssistant.isShouldShowNotification()) {
myFrameStateManager.addListener(new FrameStateListener() {
Disposable disposable = Disposer.newDisposable();
Topics.subscribe(FrameStateListener.TOPIC, disposable, new FrameStateListener() {
@Override
public void onFrameActivated() {
if (isEmpty(((WindowManagerEx)WindowManager.getInstance()).getMostRecentFocusedWindow())) {
final StatisticsService statisticsService = StatisticsUploadAssistant.getApprovedGroupsStatisticsService();
ApplicationManager.getApplication().invokeLater(() -> StatisticsNotificationManager.showNotification(statisticsService));
myFrameStateManager.removeListener(this);
Disposer.dispose(disposable);
}
}
});
@@ -1,6 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.notification.impl;
import com.intellij.application.Topics;
import com.intellij.codeInsight.hint.TooltipController;
import com.intellij.icons.AllIcons;
import com.intellij.ide.DataManager;
@@ -289,13 +290,13 @@ public class NotificationsManagerImpl extends NotificationsManager {
callback.run();
}
else {
FrameStateManager.getInstance().addListener(new FrameStateListener() {
Topics.subscribe(FrameStateListener.TOPIC, balloon, new FrameStateListener() {
@Override
public void onFrameActivated() {
FrameStateManager.getInstance().removeListener(this);
callback.run();
}
}, balloon);
});
}
}
@@ -1,9 +1,13 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ui;
import com.intellij.application.Topics;
import com.intellij.codeInsight.hint.HintManagerImpl;
import com.intellij.icons.AllIcons;
import com.intellij.ide.*;
import com.intellij.ide.FrameStateListener;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.IdeTooltip;
import com.intellij.ide.RemoteDesktopService;
import com.intellij.openapi.MnemonicHelper;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -881,7 +885,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
public void startSmartFadeoutTimer(int delay) {
mySmartFadeout = true;
mySmartFadeoutDelay = delay;
FrameStateManager.getInstance().addListener(new FrameStateListener() {
Topics.subscribe(FrameStateListener.TOPIC, this, new FrameStateListener() {
@Override
public void onFrameDeactivated() {
if (myFadeoutAlarm.getActiveRequestCount() > 0) {
@@ -892,7 +896,7 @@ public class BalloonImpl implements Balloon, IdeTooltip.Ui {
}
}
}
}, this);
});
}
public void startFadeoutTimer(final int fadeoutDelay) {
@@ -39,7 +39,8 @@ interface StorageCreator {
}
/**
* Low-level method to save component manager state store. Intended for Java clients only.
* Low-level method to save component manager state store. Use it with care and only if you understand what are you doing.
* Intended for Java clients only. Do not use in Kotlin.
*/
@JvmOverloads
fun saveComponentManager(componentManager: ComponentManager, isForceSavingAllSettings: Boolean = false) {
@@ -598,9 +598,9 @@ public class PlatformTestUtil {
saveProject(project, false);
}
public static void saveProject(@NotNull Project project, boolean isForce) {
public static void saveProject(@NotNull Project project, boolean isForceSavingAllSettings) {
ProjectManagerEx.getInstanceEx().flushChangedProjectFileAlarm();
StateStorageManagerKt.saveComponentManager(project, isForce);
StateStorageManagerKt.saveComponentManager(project, isForceSavingAllSettings);
}
static void waitForAllBackgroundActivityToCalmDown() {
@@ -1,11 +1,11 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.idea.svn;
import com.intellij.ide.FrameStateListener;
import com.intellij.ide.FrameStateManager;
import com.intellij.idea.RareLogger;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -15,6 +15,7 @@ import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.annotate.AnnotationProvider;
@@ -116,7 +117,8 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
private SvnCopiesRefreshManager myCopiesRefreshManager;
private SvnFileUrlMappingImpl myMapping;
private final MyFrameStateListener myFrameStateListener;
private Disposable myFrameStateListenerDisposable;
//Consumer<Boolean>
public static final Topic<Consumer> ROOTS_RELOADED = new Topic<>("ROOTS_RELOADED", Consumer.class);
@@ -164,8 +166,6 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
myVcsListener = () -> invokeRefreshSvnRoots();
}
myFrameStateListener = project.isDefault() ? null : new MyFrameStateListener(ChangeListManager.getInstance(project),
VcsDirtyScopeManager.getInstance(project));
myChecker = new SvnExecutableChecker(this);
Application app = ApplicationManager.getApplication();
@@ -298,9 +298,10 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
@Override
public void activate() {
MessageBusConnection busConnection = myProject.getMessageBus().connect();
if (!myProject.isDefault()) {
ChangeListManager.getInstance(myProject).addChangeListListener(myChangeListListener);
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, myVcsListener);
busConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, myVcsListener);
}
SvnApplicationSettings.getInstance().svnActivated();
@@ -309,7 +310,11 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}
// this will initialize its inner listener for committed changes upload
LoadedRevisionsCache.getInstance(myProject);
FrameStateManager.getInstance().addListener(myFrameStateListener);
if (myFrameStateListenerDisposable == null && !myProject.isDefault()) {
myFrameStateListenerDisposable = Disposer.newDisposable();
busConnection.subscribe(FrameStateListener.TOPIC, new MyFrameStateListener(ChangeListManager.getInstance(myProject),
VcsDirtyScopeManager.getInstance(myProject)));
}
myAuthNotifier.init();
mySvnBranchPointsCalculator = new SvnBranchPointsCalculator(this);
@@ -336,7 +341,7 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
}, SvnBundle.message("refreshing.working.copies.roots.progress.text"), true, myProject);*/
});
myProject.getMessageBus().connect().subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, myRootsToWorkingCopies);
busConnection.subscribe(ProjectLevelVcsManager.VCS_CONFIGURATION_CHANGED, myRootsToWorkingCopies);
myLoadedBranchesStorage.activate();
}
@@ -355,7 +360,11 @@ public class SvnVcs extends AbstractVcs<CommittedChangeList> {
@Override
public void deactivate() {
FrameStateManager.getInstance().removeListener(myFrameStateListener);
Disposable frameStateListenerDisposable = myFrameStateListenerDisposable;
if (frameStateListenerDisposable != null) {
myFrameStateListenerDisposable = null;
Disposer.dispose(frameStateListenerDisposable);
}
if (myEntriesFileListener != null) {
VirtualFileManager.getInstance().removeVirtualFileListener(myEntriesFileListener);