diff --git a/platform/platform-api/src/com/intellij/openapi/application/UserActivity.java b/platform/platform-api/src/com/intellij/openapi/application/UserActivity.java new file mode 100644 index 000000000000..d4adfc01dc7b --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/application/UserActivity.java @@ -0,0 +1,44 @@ +/* + * Copyright 2000-2010 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.openapi.application; + +import com.intellij.util.messages.Topic; + +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; + +public interface UserActivity { + + Topic TOPIC = Topic.create("UserActivity", UserActivity.class); + + void onKeyboardActivity(KeyEvent e); + void onMouseActivity(MouseEvent e); + + void onIdle(); + + class Adapter implements UserActivity { + + public void onKeyboardActivity(KeyEvent e) { + } + + public void onMouseActivity(MouseEvent e) { + } + + public void onIdle() { + } + } + +} diff --git a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java index 333551b05cae..a5ef01b31473 100644 --- a/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java +++ b/platform/platform-api/src/com/intellij/openapi/util/registry/RegistryValue.java @@ -17,6 +17,7 @@ package com.intellij.openapi.util.registry; import com.intellij.openapi.Disposable; import com.intellij.openapi.util.Disposer; +import org.jetbrains.annotations.Nullable; import java.awt.*; import java.util.MissingResourceException; @@ -168,13 +169,15 @@ public class RegistryValue { setValue(getBundleValue(myKey, true)); } - public void addListener(final RegistryValueListener listener, Disposable parent) { + public void addListener(final RegistryValueListener listener, @Nullable Disposable parent) { myListeners.add(listener); - Disposer.register(parent, new Disposable() { - public void dispose() { - myListeners.remove(listener); - } - }); + if (parent != null) { + Disposer.register(parent, new Disposable() { + public void dispose() { + myListeners.remove(listener); + } + }); + } } @Override diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index 8eccf233039c..52eb17c923a3 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -24,6 +24,7 @@ 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.UserActivity; import com.intellij.openapi.application.impl.ApplicationImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher; @@ -33,12 +34,16 @@ import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.registry.Registry; +import com.intellij.openapi.util.registry.RegistryValue; +import com.intellij.openapi.util.registry.RegistryValueListener; import com.intellij.openapi.wm.IdeFocusManager; import com.intellij.openapi.wm.ex.WindowManagerEx; import com.intellij.util.Alarm; import com.intellij.util.ReflectionUtil; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; +import com.intellij.util.messages.Topic; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -126,6 +131,14 @@ public class IdeEventQueue extends EventQueue { private final Set myReady = new HashSet(); private boolean myKeyboardBusy; + private UserActivity myUserActivity = new UserActivity.Adapter(); + + private Runnable myIdleMessageBusNotifier = new Runnable() { + public void run() { + getUserActivity().onIdle(); + } + }; + private boolean myWasEverInstalledNotifier; private static class IdeEventQueueHolder { private static final IdeEventQueue INSTANCE = new IdeEventQueue(); @@ -157,6 +170,30 @@ public class IdeEventQueue extends EventQueue { } } }); + + Registry.get("actionSystem.idleTime").addListener(new RegistryValueListener() { + public void beforeValueChanged(RegistryValue value) { + } + + public void afterValueChanged(RegistryValue value) { + installIdleMessageBusSync(); + } + }, null); + + installIdleMessageBusSync(); + } + + private void installIdleMessageBusSync() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + public void run() { + if (myWasEverInstalledNotifier) { + removeIdleListener(myIdleMessageBusNotifier); + } + + addIdleListener(myIdleMessageBusNotifier, Registry.intValue("actionSystem.idleTime")); + myWasEverInstalledNotifier = true; + } + }); } @@ -453,6 +490,16 @@ public class IdeEventQueue extends EventQueue { for (Runnable activityListener : myActivityListeners) { activityListener.run(); } + + if (e instanceof KeyEvent) { + if (e.getID() == KeyEvent.KEY_PRESSED) { + getUserActivity().onKeyboardActivity((KeyEvent)e); + } + } else if (e instanceof MouseEvent ){ + if (e.getID() == MouseEvent.MOUSE_PRESSED) { + getUserActivity().onMouseActivity((MouseEvent)e); + } + } } } } @@ -770,4 +817,12 @@ public class IdeEventQueue extends EventQueue { }); } } + + public void setApplication(Application instance) { + myUserActivity = instance.getMessageBus().syncPublisher(UserActivity.TOPIC); + } + + private UserActivity getUserActivity() { + return myUserActivity; + } } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationManagerEx.java b/platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationManagerEx.java index 0d43ab2172e4..6c3dae933372 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationManagerEx.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationManagerEx.java @@ -15,6 +15,7 @@ */ package com.intellij.openapi.application.ex; +import com.intellij.ide.IdeEventQueue; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.Application; import com.intellij.openapi.application.ApplicationManager; @@ -37,6 +38,7 @@ public class ApplicationManagerEx extends ApplicationManager { public static void setApplication(Application instance) { ourApplication = instance; + IdeEventQueue.getInstance().setApplication(instance); CachedSingletonsRegistry.cleanupCachedFields(); } @@ -49,6 +51,7 @@ public class ApplicationManagerEx extends ApplicationManager { } }); ourApplication = instance; + IdeEventQueue.getInstance().setApplication(instance); CachedSingletonsRegistry.cleanupCachedFields(); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java index 34233d4e8575..d5e6056c8e3a 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java @@ -59,6 +59,7 @@ import com.intellij.util.ReflectionCache; import com.intellij.util.concurrency.ReentrantWriterPreferenceReadWriteLock; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Stack; +import com.intellij.util.messages.Topic; import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -67,6 +68,8 @@ import org.picocontainer.MutablePicoContainer; import javax.swing.*; import java.awt.*; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties index 114dfdbf81ef..c0ebb4791941 100644 --- a/platform/platform-resources-en/src/misc/registry.properties +++ b/platform/platform-resources-en/src/misc/registry.properties @@ -19,6 +19,7 @@ actionSystem.mac.screenMenuNotUpdatedFix=false actionSystem.keyGestures.enabled=false actionSystem.suspendFocusTransferIfApplicationInactive=false actionSystem.noContextComponentWhileFocusTransfer=true +actionSystem.idleTime=2000 ide.debugMode=true ide.debugMode.description=Record additonal information to make bug reports more informative