mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge branch 'master' of git.labs.intellij.net:idea/community
This commit is contained in:
@@ -18,6 +18,7 @@ package com.intellij.openapi.util;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProcessCanceledException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -30,21 +31,23 @@ public class SimpleTimer {
|
||||
|
||||
private final Timer ourTimer;
|
||||
|
||||
private static final SimpleTimer ourInstance = new SimpleTimer();
|
||||
@NonNls private static final String THREAD_NAME = "SimpleTimer";
|
||||
private static final SimpleTimer ourInstance = newInstance("Shared SimpleTimer");
|
||||
|
||||
private long myNextScheduledTime = Long.MAX_VALUE;
|
||||
private TimerTask myNextProcessingTask;
|
||||
|
||||
private final Map<Long, ArrayList<SimpleTimerTask>> myTime2Task = new TreeMap<Long, ArrayList<SimpleTimerTask>>();
|
||||
private String myThreadName;
|
||||
|
||||
private SimpleTimer() {
|
||||
private SimpleTimer(@NotNull String threadName) {
|
||||
myThreadName = threadName;
|
||||
|
||||
final Thread thread = Thread.currentThread();
|
||||
final int currentPrio = thread.getPriority();
|
||||
try {
|
||||
// need this becase the timer's thread will inherit the priority on creation
|
||||
thread.setPriority(Thread.MIN_PRIORITY + 1);
|
||||
ourTimer = new Timer(THREAD_NAME, true);
|
||||
ourTimer = new Timer(threadName, true);
|
||||
}
|
||||
finally {
|
||||
thread.setPriority(currentPrio);
|
||||
@@ -54,6 +57,10 @@ public class SimpleTimer {
|
||||
public static SimpleTimer getInstance() {
|
||||
return ourInstance;
|
||||
}
|
||||
|
||||
public static SimpleTimer newInstance(@NotNull String name) {
|
||||
return new SimpleTimer(name);
|
||||
}
|
||||
|
||||
public SimpleTimerTask setUp(final Runnable runnable, long delay) {
|
||||
synchronized (myTime2Task) {
|
||||
@@ -150,7 +157,7 @@ public class SimpleTimer {
|
||||
}
|
||||
|
||||
public boolean isTimerThread(Thread thread) {
|
||||
return THREAD_NAME.equals(thread.getName());
|
||||
return myThreadName.equals(thread.getName());
|
||||
}
|
||||
|
||||
void onCancelled(SimpleTimerTask task) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
%startTest Generate actions
|
||||
|
||||
%include extract_Superclass.ijs
|
||||
%include newClass_projectView.ijs
|
||||
|
||||
%endTest
|
||||
@@ -1,12 +1,15 @@
|
||||
%startTest Create superclass
|
||||
%startTest Create superclass from popup menu
|
||||
|
||||
%%include ../include/project1Init.ijs
|
||||
%%action GotoClass
|
||||
%%PsiManager\n
|
||||
|
||||
%include ../include/init.ijs
|
||||
%include ../include/project1Init.ijs
|
||||
%action GotoClass
|
||||
FileEditorManager\n
|
||||
%call checkFocus(editorTab=FileEditorManager.java)
|
||||
%call contextMenu(Refactor|Extract Superclass)
|
||||
TestSuperclass\n
|
||||
%call checkFocus(dialog=Analyze and Replace Usages)
|
||||
%call waitForDialog(Analyze and Replace Usages)
|
||||
%[space]
|
||||
%call waitForDialog(Use Interface Where Possible)
|
||||
%[space]
|
||||
%call checkFocus(editorTab=FileEditorManager.java)
|
||||
|
||||
%endTest
|
||||
@@ -8,9 +8,9 @@ PsiManager\n
|
||||
%[left]
|
||||
%[left]
|
||||
%[down]
|
||||
%call checkFocus(navBar=module1>src>com>intellij>[testProject]>idea>PsiManager|navBarPopup=[fabrique]>idea>mps)
|
||||
%call checkFocus(navBar=module1>src>com>intellij>[testProject]>idea>PsiManager|navBarPopup=fabrique>[idea]>mps)
|
||||
\n
|
||||
%call flushUi()
|
||||
\n
|
||||
%call checkFocus(editorTab=ActiveLibrary.java)
|
||||
%call checkFocus(editorTab=FileEditorManager.java)
|
||||
|
||||
|
||||
@@ -17,15 +17,28 @@ package com.intellij.openapi.util;
|
||||
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
|
||||
public abstract class EdtRunnable implements Runnable {
|
||||
public abstract class EdtRunnable implements ExpirableRunnable {
|
||||
|
||||
private boolean myExpired;
|
||||
|
||||
public final void run() {
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
public void run() {
|
||||
runEdt();
|
||||
if (!isExpired()) {
|
||||
runEdt();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void expire() {
|
||||
myExpired = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
return myExpired;
|
||||
}
|
||||
|
||||
public abstract void runEdt();
|
||||
}
|
||||
@@ -319,10 +319,8 @@ public class DataManagerImpl extends DataManager implements ApplicationComponent
|
||||
myEventCount + "; current event count = " + currentEventCount
|
||||
);
|
||||
*/
|
||||
if (false) {
|
||||
LOG.error("cannot share data context between Swing events; initial event count = " + myEventCount + "; current event count = " +
|
||||
currentEventCount);
|
||||
}
|
||||
}
|
||||
|
||||
Component _component = myRef.get();
|
||||
|
||||
@@ -247,19 +247,25 @@ public class ProgressWindow extends BlockingProgressIndicator implements Disposa
|
||||
|
||||
super.stop();
|
||||
|
||||
if (myDialog != null) {
|
||||
myDialog.hide();
|
||||
if (myDialog.wasShown()) {
|
||||
myFocusTrackback.restoreFocus();
|
||||
}
|
||||
else {
|
||||
myFocusTrackback.consume();
|
||||
}
|
||||
}
|
||||
|
||||
myStoppedAlready = true;
|
||||
UIUtil.invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (myDialog != null) {
|
||||
myDialog.hide();
|
||||
if (myDialog.wasShown()) {
|
||||
myFocusTrackback.restoreFocus();
|
||||
}
|
||||
else {
|
||||
myFocusTrackback.consume();
|
||||
}
|
||||
}
|
||||
|
||||
Disposer.dispose(this);
|
||||
myStoppedAlready = true;
|
||||
|
||||
Disposer.dispose(ProgressWindow.this);
|
||||
}
|
||||
});
|
||||
|
||||
SwingUtilities.invokeLater(EmptyRunnable.INSTANCE); // Just to give blocking dispatching a chance to go out.
|
||||
}
|
||||
|
||||
+45
@@ -24,6 +24,9 @@ import com.intellij.openapi.ui.Queryable;
|
||||
import com.intellij.openapi.ui.playback.PlaybackContext;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.AsyncResult;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.SimpleTimer;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.IdeFocusManager;
|
||||
import com.intellij.openapi.wm.IdeFrame;
|
||||
import com.intellij.openapi.wm.ToolWindow;
|
||||
@@ -34,8 +37,10 @@ import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.AWTEventListener;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.util.*;
|
||||
|
||||
public class WindowSystemPlaybackCall {
|
||||
@@ -67,6 +72,46 @@ public class WindowSystemPlaybackCall {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public static AsyncResult<String> waitForDialog(final PlaybackContext context, final String title) {
|
||||
final AsyncResult<String> result = new AsyncResult<String>();
|
||||
|
||||
final Ref<AWTEventListener> listener = new Ref<AWTEventListener>();
|
||||
listener.set(new AWTEventListener() {
|
||||
@Override
|
||||
public void eventDispatched(AWTEvent event) {
|
||||
if (event.getID() == WindowEvent.WINDOW_ACTIVATED) {
|
||||
final Window wnd = ((WindowEvent)event).getWindow();
|
||||
if (wnd instanceof JDialog) {
|
||||
if (title.equals(((JDialog)wnd).getTitle())) {
|
||||
Toolkit.getDefaultToolkit().removeAWTEventListener(listener.get());
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getUiReady(context).notify(result);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener(listener.get(), WindowEvent.WINDOW_EVENT_MASK);
|
||||
|
||||
SimpleTimer.getInstance().setUp(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toolkit.getDefaultToolkit().removeAWTEventListener(listener.get());
|
||||
if (!result.isProcessed()) {
|
||||
result.setRejected("Timed out waiting for window: " + title);
|
||||
}
|
||||
}
|
||||
}, Registry.intValue("actionSystem.commandProcessingTimeout"));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static AsyncResult<String> checkFocus(final PlaybackContext context, String expected) {
|
||||
final AsyncResult<String> result = new AsyncResult<String>();
|
||||
final Map<String, String> expectedMap = new LinkedHashMap<String, String>();
|
||||
|
||||
@@ -27,10 +27,7 @@ import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.util.ActionCallback;
|
||||
import com.intellij.openapi.util.EdtRunnable;
|
||||
import com.intellij.openapi.util.Expirable;
|
||||
import com.intellij.openapi.util.ExpirableRunnable;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.wm.*;
|
||||
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
|
||||
@@ -79,24 +76,11 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
final EdtAlarm myFocusedComponentAlaram;
|
||||
private final EdtAlarm myForcedFocusRequestsAlarm;
|
||||
|
||||
private SimpleTimer myTimer = SimpleTimer.newInstance("FocusManager timer");
|
||||
|
||||
private final EdtAlarm myIdleAlarm;
|
||||
private final Set<Runnable> myIdleRequests = new LinkedHashSet<Runnable>();
|
||||
private final EdtRunnable myIdleRunnable = new EdtRunnable() {
|
||||
public void runEdt() {
|
||||
if (canFlushIdleRequests()) {
|
||||
flushIdleRequests();
|
||||
}
|
||||
else {
|
||||
if (processFocusRevalidation()) {
|
||||
if (isFocusTransferReady()) {
|
||||
flushIdleRequests();
|
||||
}
|
||||
}
|
||||
|
||||
restartIdleAlarm();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private boolean myFlushWasDelayedToFixFocus;
|
||||
private ExpirableRunnable myFocusRevalidator;
|
||||
|
||||
@@ -106,6 +90,24 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
private UiActivityMonitor myActivityMonitor;
|
||||
private boolean myTypeaheadEnabled = true;
|
||||
|
||||
|
||||
private class IdleRunnable extends EdtRunnable {
|
||||
public void runEdt() {
|
||||
if (canFlushIdleRequests()) {
|
||||
flushIdleRequests();
|
||||
}
|
||||
else {
|
||||
if (processFocusRevalidation()) {
|
||||
if (isFocusTransferReady()) {
|
||||
flushIdleRequests();
|
||||
}
|
||||
}
|
||||
|
||||
restartIdleAlarm();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canFlushIdleRequests() {
|
||||
Component focusOwner = getFocusOwner();
|
||||
return isFocusTransferReady()
|
||||
@@ -128,9 +130,9 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
myQueue = IdeEventQueue.getInstance();
|
||||
myActivityMonitor = UiActivityMonitor.getInstance();
|
||||
|
||||
myFocusedComponentAlaram = new EdtAlarm(this);
|
||||
myForcedFocusRequestsAlarm = new EdtAlarm(this);
|
||||
myIdleAlarm = new EdtAlarm(this);
|
||||
myFocusedComponentAlaram = new EdtAlarm();
|
||||
myForcedFocusRequestsAlarm = new EdtAlarm();
|
||||
myIdleAlarm = new EdtAlarm();
|
||||
|
||||
final AppListener myAppListener = new AppListener();
|
||||
myApp.getMessageBus().connect().subscribe(ApplicationActivationListener.TOPIC, myAppListener);
|
||||
@@ -183,6 +185,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
|
||||
@NotNull
|
||||
public ActionCallback requestFocus(@NotNull final FocusCommand command, final boolean forced) {
|
||||
assertDispatchThread();
|
||||
|
||||
if (isInternalMode) {
|
||||
recordCommand(command, new Throwable(), forced);
|
||||
}
|
||||
@@ -460,7 +464,7 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
|
||||
private void restartIdleAlarm() {
|
||||
myIdleAlarm.cancelAllRequests();
|
||||
myIdleAlarm.addRequest(myIdleRunnable, Registry.intValue("actionSystem.focusIdleTimeout"));
|
||||
myIdleAlarm.addRequest(new IdleRunnable(), Registry.intValue("actionSystem.focusIdleTimeout"));
|
||||
}
|
||||
|
||||
private void flushIdleRequests() {
|
||||
@@ -602,6 +606,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
}
|
||||
|
||||
public boolean isFocusTransferReady() {
|
||||
assertDispatchThread();
|
||||
|
||||
if (myRunContext != null) return true;
|
||||
|
||||
invalidateFocusRequestsQueue();
|
||||
@@ -741,6 +747,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
}
|
||||
|
||||
public void suspendKeyProcessingUntil(@NotNull final ActionCallback done) {
|
||||
assertDispatchThread();
|
||||
|
||||
requestFocus(new FocusCommand(done) {
|
||||
public ActionCallback run() {
|
||||
return done;
|
||||
@@ -749,6 +757,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
}
|
||||
|
||||
public Expirable getTimestamp(final boolean trackOnlyForcedCommands) {
|
||||
assertDispatchThread();
|
||||
|
||||
return new Expirable() {
|
||||
long myOwnStamp = trackOnlyForcedCommands ? myForcedCmdTimestamp : myCmdTimestamp;
|
||||
|
||||
@@ -760,6 +770,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
|
||||
@Override
|
||||
public FocusRequestor getFurtherRequestor() {
|
||||
assertDispatchThread();
|
||||
|
||||
FurtherRequestor requestor = new FurtherRequestor(this, getTimestamp(true));
|
||||
myValidFurtherRequestors.add(requestor);
|
||||
revalidateFurtherRequestors();
|
||||
@@ -789,6 +801,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
|
||||
@Override
|
||||
public Component getFocusOwner() {
|
||||
assertDispatchThread();
|
||||
|
||||
Component result = null;
|
||||
if (myRunContext != null) {
|
||||
result = (Component)myRunContext.getData(PlatformDataKeys.CONTEXT_COMPONENT.getName());
|
||||
@@ -815,6 +829,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
|
||||
@Override
|
||||
public void runOnOwnContext(DataContext context, Runnable runnable) {
|
||||
assertDispatchThread();
|
||||
|
||||
myRunContext = context;
|
||||
try {
|
||||
runnable.run();
|
||||
@@ -825,12 +841,16 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
|
||||
@Override
|
||||
public Component getLastFocusedFor(IdeFrame frame) {
|
||||
assertDispatchThread();
|
||||
|
||||
WeakReference<Component> ref = myLastFocused.get(frame);
|
||||
return ref != null ? ref.get() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toFront(JComponent c) {
|
||||
assertDispatchThread();
|
||||
|
||||
if (c == null) return;
|
||||
|
||||
final Window window = UIUtil.getParentOfType(Window.class, c);
|
||||
@@ -877,19 +897,20 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
}
|
||||
|
||||
|
||||
static class EdtAlarm {
|
||||
private final Alarm myAlarm;
|
||||
|
||||
private EdtAlarm(Disposable parent) {
|
||||
myAlarm = new Alarm(Alarm.ThreadToUse.OWN_THREAD, parent);
|
||||
}
|
||||
class EdtAlarm {
|
||||
|
||||
private Set<EdtRunnable> myRequests = new HashSet<EdtRunnable>();
|
||||
|
||||
public void cancelAllRequests() {
|
||||
myAlarm.cancelAllRequests();
|
||||
for (EdtRunnable each : myRequests) {
|
||||
each.expire();
|
||||
}
|
||||
myRequests.clear();
|
||||
}
|
||||
|
||||
public void addRequest(EdtRunnable runnable, int delay) {
|
||||
myAlarm.addRequest(runnable, delay);
|
||||
myRequests.add(runnable);
|
||||
myTimer.setUp(runnable, delay);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1018,4 +1039,8 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable {
|
||||
public boolean isFocusTransferEnabled() {
|
||||
return myApp.isActive() || !Registry.is("actionSystem.suspendFocusTransferIfApplicationInactive");
|
||||
}
|
||||
|
||||
private void assertDispatchThread() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user