From cf30bc495d240859768778315fe0010b3fcf10cc Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 31 Aug 2016 17:33:33 +0200 Subject: [PATCH] override DefaultKeyboardFocusManager to track events that IdeEventQueue misses (IDEA-160588) --- .../src/com/intellij/ide/IdeEventQueue.java | 17 +++++---- .../intellij/ide/IdeKeyboardFocusManager.java | 35 +++++++++++++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.java diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index 0bafaa7f09f7..f8f5fa4e0e0c 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -139,7 +139,7 @@ public class IdeEventQueue extends EventQueue { systemEventQueue.push(this); addIdleTimeCounterRequest(); - final KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager(); + KeyboardFocusManager keyboardFocusManager = IdeKeyboardFocusManager.replaceDefault(); keyboardFocusManager.addPropertyChangeListener("permanentFocusOwner", e -> { final Application application = ApplicationManager.getApplication(); if (application == null) { @@ -373,7 +373,7 @@ public class IdeEventQueue extends EventQueue { } boolean wasInputEvent = myIsInInputEvent; - myIsInInputEvent = e instanceof InputEvent || e instanceof InputMethodEvent || e instanceof WindowEvent || e instanceof ActionEvent; + myIsInInputEvent = isInputEvent(e); if (myIsInInputEvent) { HeavyProcessLatch.INSTANCE.prioritizeUiActivity(); } else { @@ -382,8 +382,7 @@ public class IdeEventQueue extends EventQueue { AWTEvent oldEvent = myCurrentEvent; myCurrentEvent = e; - boolean userActivity = myIsInInputEvent || e instanceof ItemEvent || e instanceof FocusEvent; - try (AccessToken ignored = startActivity(userActivity)) { + try (AccessToken ignored = startActivity(e)) { _dispatchEvent(e, false); } catch (Throwable t) { @@ -403,6 +402,10 @@ public class IdeEventQueue extends EventQueue { } } + private static boolean isInputEvent(@NotNull AWTEvent e) { + return e instanceof InputEvent || e instanceof InputMethodEvent || e instanceof WindowEvent || e instanceof ActionEvent; + } + @Override public AWTEvent getNextEvent() throws InterruptedException { AWTEvent event = super.getNextEvent(); @@ -413,11 +416,13 @@ public class IdeEventQueue extends EventQueue { } @Nullable - private static AccessToken startActivity(boolean userActivity) { + static AccessToken startActivity(AWTEvent e) { if (ourTransactionGuard == null && appIsLoaded()) { ourTransactionGuard = (TransactionGuardImpl)TransactionGuard.getInstance(); } - return ourTransactionGuard == null ? null : ourTransactionGuard.startActivity(userActivity); + return ourTransactionGuard == null + ? null + : ourTransactionGuard.startActivity(isInputEvent(e) || e instanceof ItemEvent || e instanceof FocusEvent); } private void processException(Throwable t) { diff --git a/platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.java b/platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.java new file mode 100644 index 000000000000..180240db68cf --- /dev/null +++ b/platform/platform-impl/src/com/intellij/ide/IdeKeyboardFocusManager.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2016 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; + +import com.intellij.openapi.application.AccessToken; +import sun.awt.AppContext; + +import java.awt.*; + +class IdeKeyboardFocusManager extends DefaultKeyboardFocusManager { + @Override + public boolean dispatchEvent(AWTEvent e) { + try (AccessToken ignore = (EventQueue.isDispatchThread() ? IdeEventQueue.startActivity(e) : null)) { + return super.dispatchEvent(e); + } + } + + static IdeKeyboardFocusManager replaceDefault() { + AppContext.getAppContext().put(KeyboardFocusManager.class, new IdeKeyboardFocusManager()); + return (IdeKeyboardFocusManager)getCurrentKeyboardFocusManager(); + } +}