mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
macro playback fixed
This commit is contained in:
@@ -439,7 +439,7 @@ public class PlaybackDebugger implements UiDebuggerExtension, PlaybackRunner.Sta
|
||||
myMessage.clear();
|
||||
|
||||
addInfo("Waiting for IDE frame activation", -1);
|
||||
myRunner = new PlaybackRunner(myDocument.getText(), this);
|
||||
myRunner = new PlaybackRunner(myDocument.getText(), this, false);
|
||||
|
||||
|
||||
new Thread() {
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.keymap.impl.IdeKeyEventDispatcher;
|
||||
import com.intellij.openapi.keymap.impl.IdeMouseEventDispatcher;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
@@ -48,10 +49,7 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
/**
|
||||
@@ -83,7 +81,7 @@ public class IdeEventQueue extends EventQueue {
|
||||
private final Map<Runnable, MyFireIdleRequest> myListener2Request = new HashMap<Runnable, MyFireIdleRequest>();
|
||||
// IdleListener -> MyFireIdleRequest
|
||||
|
||||
private final IdeKeyEventDispatcher myKeyEventDispatcher = new IdeKeyEventDispatcher();
|
||||
private final IdeKeyEventDispatcher myKeyEventDispatcher = new IdeKeyEventDispatcher(this);
|
||||
|
||||
private final IdeMouseEventDispatcher myMouseEventDispatcher = new IdeMouseEventDispatcher();
|
||||
|
||||
@@ -130,6 +128,9 @@ public class IdeEventQueue extends EventQueue {
|
||||
private final Set<EventDispatcher> myDispatchers = new LinkedHashSet<EventDispatcher>();
|
||||
private final Set<EventDispatcher> myPostprocessors = new LinkedHashSet<EventDispatcher>();
|
||||
|
||||
private Set<Runnable> myReady = new HashSet<Runnable>();
|
||||
private boolean myKeyboardBusy;
|
||||
|
||||
private static class IdeEventQueueHolder {
|
||||
private static final IdeEventQueue INSTANCE = new IdeEventQueue();
|
||||
}
|
||||
@@ -379,6 +380,10 @@ public class IdeEventQueue extends EventQueue {
|
||||
each.dispatch(e);
|
||||
}
|
||||
|
||||
if (e instanceof KeyEvent) {
|
||||
maybeReady();
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
final long processTime = System.currentTimeMillis() - t;
|
||||
if (processTime > 100) {
|
||||
@@ -427,6 +432,10 @@ public class IdeEventQueue extends EventQueue {
|
||||
enterSuspendModeIfNeeded(e);
|
||||
}
|
||||
|
||||
if (e instanceof KeyEvent) {
|
||||
myKeyboardBusy = e.getID() != KeyEvent.KEY_RELEASED || ((KeyEvent)e).getModifiers() != 0;
|
||||
}
|
||||
|
||||
if (typeAheadDispatchToFocusManager(e)) return;
|
||||
|
||||
if (e instanceof WindowEvent) {
|
||||
@@ -735,4 +744,37 @@ public class IdeEventQueue extends EventQueue {
|
||||
public boolean hasFocusEventsPending() {
|
||||
return peekEvent(FocusEvent.FOCUS_GAINED) != null || peekEvent(FocusEvent.FOCUS_LOST) != null;
|
||||
}
|
||||
|
||||
private boolean isReady() {
|
||||
return !myKeyboardBusy && myKeyEventDispatcher.isReady();
|
||||
}
|
||||
|
||||
public void maybeReady() {
|
||||
flushReady();
|
||||
}
|
||||
|
||||
private void flushReady() {
|
||||
if (myReady.size() == 0 || !isReady()) return;
|
||||
|
||||
Runnable[] ready = myReady.toArray(new Runnable[myReady.size()]);
|
||||
myReady.clear();
|
||||
|
||||
for (Runnable each : ready) {
|
||||
each.run();
|
||||
}
|
||||
}
|
||||
|
||||
public void doWhenReady(final Runnable runnable) {
|
||||
if (EventQueue.isDispatchThread()) {
|
||||
myReady.add(runnable);
|
||||
maybeReady();
|
||||
} else {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
myReady.add(runnable);
|
||||
maybeReady();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.intellij.openapi.ui.playback.PlaybackRunner;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.NamedJDOMExternalizable;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import org.jdom.Element;
|
||||
@@ -212,7 +213,7 @@ public class ActionMacroManager implements ExportableApplicationComponent, Named
|
||||
public void messageEdt(String text, int curentLine) {
|
||||
frame.getStatusBar().setInfo("Line " + curentLine + ": " + text);
|
||||
}
|
||||
});
|
||||
}, Registry.is("actionSystem.playback.useDirectActionCall"));
|
||||
|
||||
myIsPlaying = true;
|
||||
|
||||
|
||||
+13
-2
@@ -93,8 +93,10 @@ public final class IdeKeyEventDispatcher implements Disposable {
|
||||
private final KeyboardGestureProcessor myKeyGestureProcessor = new KeyboardGestureProcessor(this);
|
||||
|
||||
private final KeyProcessorContext myContext = new KeyProcessorContext();
|
||||
private IdeEventQueue myQueue;
|
||||
|
||||
public IdeKeyEventDispatcher(){
|
||||
public IdeKeyEventDispatcher(IdeEventQueue queue){
|
||||
myQueue = queue;
|
||||
Application parent = ApplicationManager.getApplication(); // Application is null on early start when e.g. license dialog is shown
|
||||
if (parent != null) Disposer.register(parent, this);
|
||||
}
|
||||
@@ -348,7 +350,9 @@ public final class IdeKeyEventDispatcher implements Disposable {
|
||||
KeyStroke originalKeyStroke=KeyStroke.getKeyStrokeForEvent(e);
|
||||
KeyStroke keyStroke=getKeyStrokeWithoutMouseModifiers(originalKeyStroke);
|
||||
|
||||
if (myKeyGestureProcessor.processInitState()) return true;
|
||||
if (myKeyGestureProcessor.processInitState()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (SystemInfo.isMac) {
|
||||
if (e.getModifiersEx() == InputEvent.ALT_DOWN_MASK &&
|
||||
@@ -620,6 +624,9 @@ public final class IdeKeyEventDispatcher implements Disposable {
|
||||
|
||||
public void setState(final int state) {
|
||||
myState = state;
|
||||
if (myQueue != null) {
|
||||
myQueue.maybeReady();
|
||||
}
|
||||
}
|
||||
|
||||
public void resetState() {
|
||||
@@ -634,4 +641,8 @@ public final class IdeKeyEventDispatcher implements Disposable {
|
||||
public void setPressedWasProcessed(boolean pressedWasProcessed) {
|
||||
myPressedWasProcessed = pressedWasProcessed;
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
return myState == STATE_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,6 @@ import com.intellij.openapi.util.ActionCallback;
|
||||
import java.awt.*;
|
||||
|
||||
public interface PlaybackCommand {
|
||||
ActionCallback execute(PlaybackRunner.StatusCallback cb, Robot robot);
|
||||
ActionCallback execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean useDirectActionCall);
|
||||
boolean canGoFurther();
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.ui.playback;
|
||||
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.openapi.ui.playback.commands.AssertFocused;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.ui.playback.commands.*;
|
||||
@@ -39,10 +40,12 @@ public class PlaybackRunner {
|
||||
private ArrayList<PlaybackCommand> myCommands = new ArrayList<PlaybackCommand>();
|
||||
private ActionCallback myActionCallback;
|
||||
private boolean myStopRequested;
|
||||
private boolean myUseDirectActionCall;
|
||||
|
||||
public PlaybackRunner(String script, StatusCallback callback) {
|
||||
public PlaybackRunner(String script, StatusCallback callback, final boolean useDirectActionCall) {
|
||||
myScript = script;
|
||||
myCallback = callback;
|
||||
myUseDirectActionCall = useDirectActionCall;
|
||||
}
|
||||
|
||||
public ActionCallback run() {
|
||||
@@ -58,7 +61,15 @@ public class PlaybackRunner {
|
||||
new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
executeFrom(0);
|
||||
if (myUseDirectActionCall) {
|
||||
executeFrom(0);
|
||||
} else {
|
||||
IdeEventQueue.getInstance().doWhenReady(new Runnable() {
|
||||
public void run() {
|
||||
executeFrom(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
|
||||
@@ -78,7 +89,7 @@ public class PlaybackRunner {
|
||||
myActionCallback.setRejected();
|
||||
return;
|
||||
}
|
||||
cmd.execute(myCallback, myRobot).doWhenDone(new Runnable() {
|
||||
cmd.execute(myCallback, myRobot, myUseDirectActionCall).doWhenDone(new Runnable() {
|
||||
public void run() {
|
||||
if (cmd.canGoFurther()) {
|
||||
executeFrom(cmdIndex + 1);
|
||||
@@ -226,7 +237,7 @@ public class PlaybackRunner {
|
||||
public void message(String text, int currentLine) {
|
||||
System.out.println(currentLine + " " + text);
|
||||
}
|
||||
}).run();
|
||||
}, false).run();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -45,10 +45,10 @@ public abstract class AbstractCommand implements PlaybackCommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
public final ActionCallback execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
public final ActionCallback execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean useDirectActionCall) {
|
||||
try {
|
||||
dumpCommand(cb);
|
||||
return _execute(cb, robot);
|
||||
return _execute(cb, robot, useDirectActionCall);
|
||||
}
|
||||
catch (Exception e) {
|
||||
cb.error(e.getMessage(), getLine());
|
||||
@@ -56,7 +56,7 @@ public abstract class AbstractCommand implements PlaybackCommand {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot);
|
||||
protected abstract ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall);
|
||||
|
||||
public void dumpCommand(final PlaybackRunner.StatusCallback cb) {
|
||||
cb.message(getText(), getLine());
|
||||
|
||||
+18
-15
@@ -38,7 +38,7 @@ public class ActionCommand extends TypeCommand {
|
||||
super(text, line);
|
||||
}
|
||||
|
||||
protected ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
protected ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
final String actionName = getText().substring(PREFIX.length()).trim();
|
||||
|
||||
final AnAction action = ActionManager.getInstance().getAction(actionName);
|
||||
@@ -48,23 +48,26 @@ public class ActionCommand extends TypeCommand {
|
||||
}
|
||||
|
||||
|
||||
final Shortcut[] sc = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionName);
|
||||
KeyStroke stroke = null;
|
||||
for (Shortcut each : sc) {
|
||||
if (each instanceof KeyboardShortcut) {
|
||||
final KeyboardShortcut ks = (KeyboardShortcut)each;
|
||||
final KeyStroke first = ks.getFirstKeyStroke();
|
||||
final KeyStroke second = ks.getSecondKeyStroke();
|
||||
if (first != null && second == null) {
|
||||
stroke = KeyStroke.getKeyStroke(first.getKeyCode(), first.getModifiers(), false);
|
||||
if (!directActionCall) {
|
||||
final Shortcut[] sc = KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionName);
|
||||
KeyStroke stroke = null;
|
||||
for (Shortcut each : sc) {
|
||||
if (each instanceof KeyboardShortcut) {
|
||||
final KeyboardShortcut ks = (KeyboardShortcut)each;
|
||||
final KeyStroke first = ks.getFirstKeyStroke();
|
||||
final KeyStroke second = ks.getSecondKeyStroke();
|
||||
if (first != null && second == null) {
|
||||
stroke = KeyStroke.getKeyStroke(first.getKeyCode(), first.getModifiers(), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (stroke != null) {
|
||||
cb.message("Invoking action via shortcut: " + stroke.toString(), getLine());
|
||||
type(robot, stroke);
|
||||
return new ActionCallback.Done();
|
||||
if (stroke != null) {
|
||||
cb.message("Invoking action via shortcut: " + stroke.toString(), getLine());
|
||||
type(robot, stroke);
|
||||
return new ActionCallback.Done();
|
||||
}
|
||||
}
|
||||
|
||||
final InputEvent input = getInputEvent(actionName);
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class AlphaNumericTypeCommand extends TypeCommand {
|
||||
super(text, line);
|
||||
}
|
||||
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
final String text = getText();
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
final char each = text.charAt(i);
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ public class AssertFocused extends AbstractCommand {
|
||||
super(text, line);
|
||||
}
|
||||
|
||||
protected ActionCallback _execute(final PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
protected ActionCallback _execute(final PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
final ActionCallback result = new ActionCallback();
|
||||
|
||||
String text = getText().substring(PREFIX.length()).trim();
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ public class DelayCommand extends AbstractCommand {
|
||||
super(text, line);
|
||||
}
|
||||
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
final String s = getText().substring(PREFIX.length()).trim();
|
||||
|
||||
try {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ public class EmptyCommand extends AbstractCommand {
|
||||
super("", line);
|
||||
}
|
||||
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
return new ActionCallback.Done();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -26,7 +26,7 @@ public class ErrorCommand extends AbstractCommand {
|
||||
super(text, line);
|
||||
}
|
||||
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
dumpError(cb, getText());
|
||||
return new ActionCallback.Rejected();
|
||||
}
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class KeyShortcutCommand extends TypeCommand {
|
||||
super(text, line);
|
||||
}
|
||||
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
public ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
final String one = getText().substring(PREFIX.length());
|
||||
if (!one.endsWith("]")) {
|
||||
dumpError(cb, "Expected " + "]");
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public class StopCommand extends AbstractCommand {
|
||||
super(text, line);
|
||||
}
|
||||
|
||||
protected ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot) {
|
||||
protected ActionCallback _execute(PlaybackRunner.StatusCallback cb, Robot robot, boolean directActionCall) {
|
||||
cb.message("Stopped", getLine());
|
||||
return new ActionCallback.Done();
|
||||
}
|
||||
|
||||
@@ -15,7 +15,8 @@ actionSystem.commandProcessingTimeout.description=Timeout after which currently
|
||||
actionSystem.typeAheadTimeBeforeDialog=2000
|
||||
actionSystem.typeAheadTimeBeforeDialog.description=If dialog shown as a result of some typing, all key types withing this time will be redispatched after dialog is closed
|
||||
actionSystem.playback.autodelay=20
|
||||
actionSystem.playback.description=Delay between events generated by the playback runner
|
||||
actionSystem.playback.autodelay.description=Delay between events generated by the playback runner
|
||||
actionSystem.playback.useDirectActionCall=true
|
||||
actionSystem.focusIdleTimeout=20
|
||||
actionSystem.mac.screenMenuNotUpdatedFix=false
|
||||
actionSystem.keyGestures.enabled=false
|
||||
|
||||
Reference in New Issue
Block a user