one AnActionListener for all dispatchers

GitOrigin-RevId: 722db31bfe6d1b1967246823ec4f496f7dc53c57
This commit is contained in:
Vladimir Krivosheev
2019-12-03 14:38:48 +00:00
committed by intellij-monorepo-bot
parent da6f32743f
commit de90c7022e
2 changed files with 73 additions and 72 deletions
@@ -4,14 +4,12 @@ package com.intellij.openapi.keymap.impl;
import com.intellij.ide.DataManager;
import com.intellij.ide.IdeEventQueue;
import com.intellij.ide.actions.ActionsCollector;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.ActionManagerEx;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Couple;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
@@ -39,7 +37,7 @@ import static com.intellij.openapi.keymap.KeymapUtil.getActiveKeymapShortcuts;
* @author Dmitry Batrak
* @author Konstantin Bulenkov
*/
public final class ModifierKeyDoubleClickHandler implements Disposable {
public final class ModifierKeyDoubleClickHandler {
private static final Logger LOG = Logger.getInstance(ModifierKeyDoubleClickHandler.class);
private static final TIntIntHashMap KEY_CODE_TO_MODIFIER_MAP = new TIntIntHashMap();
@@ -62,14 +60,33 @@ public final class ModifierKeyDoubleClickHandler implements Disposable {
registerAction(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT_WITH_SELECTION, modifierKeyCode, KeyEvent.VK_RIGHT);
registerAction(IdeActions.ACTION_EDITOR_MOVE_LINE_START_WITH_SELECTION, modifierKeyCode, KeyEvent.VK_HOME);
registerAction(IdeActions.ACTION_EDITOR_MOVE_LINE_END_WITH_SELECTION, modifierKeyCode, KeyEvent.VK_END);
}
@Override
public void dispose() {
for (MyDispatcher dispatcher : myDispatchers.values()) {
Disposer.dispose(dispatcher);
}
myDispatchers.clear();
ApplicationManager.getApplication().getMessageBus().connect().subscribe(AnActionListener.TOPIC, new AnActionListener() {
@Override
public void beforeActionPerformed(@NotNull AnAction action, @NotNull DataContext dataContext, @NotNull AnActionEvent event) {
if (myIsRunningAction) {
return;
}
for (MyDispatcher dispatcher : myDispatchers.values()) {
dispatcher.resetState();
}
}
});
IdeEventQueue.getInstance().addDispatcher(event -> {
if (!(event instanceof KeyEvent)) {
return false;
}
boolean result = false;
KeyEvent keyEvent = (KeyEvent)event;
for (MyDispatcher dispatcher : myDispatchers.values()) {
if (dispatcher.dispatch(keyEvent)) {
result = true;
}
}
return result;
}, ApplicationManager.getApplication());
}
public static ModifierKeyDoubleClickHandler getInstance() {
@@ -90,13 +107,7 @@ public final class ModifierKeyDoubleClickHandler implements Disposable {
int modifierKeyCode,
int actionKeyCode,
boolean skipIfActionHasShortcut) {
MyDispatcher dispatcher = new MyDispatcher(actionId, modifierKeyCode, actionKeyCode, skipIfActionHasShortcut);
MyDispatcher oldDispatcher = myDispatchers.put(actionId, dispatcher);
IdeEventQueue.getInstance().addDispatcher(dispatcher, dispatcher);
ApplicationManager.getApplication().getMessageBus().connect(dispatcher).subscribe(AnActionListener.TOPIC, dispatcher);
if (oldDispatcher != null) {
Disposer.dispose(oldDispatcher);
}
myDispatchers.put(actionId, new MyDispatcher(actionId, modifierKeyCode, actionKeyCode, skipIfActionHasShortcut));
}
/**
@@ -109,17 +120,14 @@ public final class ModifierKeyDoubleClickHandler implements Disposable {
}
public void unregisterAction(@NotNull String actionId) {
MyDispatcher oldDispatcher = myDispatchers.remove(actionId);
if (oldDispatcher != null) {
Disposer.dispose(oldDispatcher);
}
myDispatchers.remove(actionId);
}
public boolean isRunningAction() {
return myIsRunningAction;
}
private final class MyDispatcher implements IdeEventQueue.EventDispatcher, Disposable, AnActionListener {
private final class MyDispatcher {
private final String myActionId;
private final int myModifierKeyCode;
private final int myActionKeyCode;
@@ -137,44 +145,45 @@ public final class ModifierKeyDoubleClickHandler implements Disposable {
mySkipIfActionHasShortcut = skipIfActionHasShortcut;
}
@Override
public boolean dispatch(@NotNull AWTEvent event) {
if (event instanceof KeyEvent) {
final KeyEvent keyEvent = (KeyEvent)event;
final int keyCode = keyEvent.getKeyCode();
LOG.debug("", this, event);
if (keyCode == myModifierKeyCode) {
if (hasOtherModifiers(keyEvent)) {
resetState();
return false;
}
if (myActionKeyCode == -1 && ourOtherKeyWasPressed.get() && keyEvent.getWhen() - ourLastTimePressed.get() < 100) {
resetState();
return false;
}
ourOtherKeyWasPressed.set(false);
if (ourPressed.first.get() && keyEvent.getWhen() - ourLastTimePressed.get() > 500) {
resetState();
}
handleModifier((KeyEvent)event);
public boolean dispatch(@NotNull KeyEvent event) {
int keyCode = event.getKeyCode();
LOG.debug("", this, event);
if (keyCode == myModifierKeyCode) {
if (hasOtherModifiers(event)) {
resetState();
return false;
} else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get() && myActionKeyCode != -1) {
if (keyCode == myActionKeyCode && !hasOtherModifiers(keyEvent)) {
if (event.getID() == KeyEvent.KEY_PRESSED) {
return run(keyEvent);
}
return true;
}
return false;
} else {
ourLastTimePressed.set(keyEvent.getWhen());
ourOtherKeyWasPressed.set(true);
if (keyCode == KeyEvent.VK_ESCAPE || keyCode == KeyEvent.VK_TAB) {
ourLastTimePressed.set(0);
}
}
resetState();
if (myActionKeyCode == -1 && ourOtherKeyWasPressed.get() && event.getWhen() - ourLastTimePressed.get() < 100) {
resetState();
return false;
}
ourOtherKeyWasPressed.set(false);
if (ourPressed.first.get() && event.getWhen() - ourLastTimePressed.get() > 500) {
resetState();
}
handleModifier(event);
return false;
}
else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get() && myActionKeyCode != -1) {
if (keyCode == myActionKeyCode && !hasOtherModifiers(event)) {
if (event.getID() == KeyEvent.KEY_PRESSED) {
return run(event);
}
return true;
}
return false;
}
else {
ourLastTimePressed.set(event.getWhen());
ourOtherKeyWasPressed.set(true);
if (keyCode == KeyEvent.VK_ESCAPE || keyCode == KeyEvent.VK_TAB) {
ourLastTimePressed.set(0);
}
}
resetState();
return false;
}
@@ -200,19 +209,22 @@ public final class ModifierKeyDoubleClickHandler implements Disposable {
ourPressed.first.set(true);
ourLastTimePressed.set(event.getWhen());
return;
} else {
}
else {
if (ourPressed.first.get() && ourReleased.first.get()) {
ourPressed.second.set(true);
ourLastTimePressed.set(event.getWhen());
return;
}
}
} else if (event.getID() == KeyEvent.KEY_RELEASED) {
}
else if (event.getID() == KeyEvent.KEY_RELEASED) {
if (ourPressed.first.get() && !ourReleased.first.get()) {
ourReleased.first.set(true);
ourLastTimePressed.set(event.getWhen());
return;
} else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get()) {
}
else if (ourPressed.first.get() && ourReleased.first.get() && ourPressed.second.get()) {
resetState();
if (myActionKeyCode == -1 && !shouldSkipIfActionHasShortcut()) {
run(event);
@@ -273,15 +285,6 @@ public final class ModifierKeyDoubleClickHandler implements Disposable {
return mySkipIfActionHasShortcut && getActiveKeymapShortcuts(myActionId).getShortcuts().length > 0;
}
@Override
public void beforeActionPerformed(@NotNull AnAction action, @NotNull DataContext dataContext, @NotNull AnActionEvent event) {
if (!myIsRunningAction) resetState();
}
@Override
public void dispose() {
}
@Override
public String toString() {
return "modifier double-click dispatcher [modifierKeyCode=" + myModifierKeyCode +
@@ -6,11 +6,9 @@
<component>
<implementation-class>com.intellij.openapi.editor.impl.VisibleEditorsTracker</implementation-class>
</component>
<component>
<implementation-class>com.intellij.openapi.keymap.impl.ModifierKeyDoubleClickHandler</implementation-class>
</component>
</application-components>
<extensions defaultExtensionNs="com.intellij">
<applicationService serviceImplementation="com.intellij.openapi.keymap.impl.ModifierKeyDoubleClickHandler" preload="true"/>
<projectService serviceInterface="com.intellij.openapi.fileEditor.ex.IdeDocumentHistory"
serviceImplementation="com.intellij.openapi.fileEditor.impl.IdeDocumentHistoryImpl" preload="await"/>
</extensions>