public OperationStatus ensureFilesWritable(@NotNull VirtualFile... files) { if (files.length == 0) { return new OperationStatusImpl(VirtualFile.EMPTY_ARRAY); } ApplicationManager.getApplication().assertIsDispatchThread(); Set<VirtualFile> realFiles = new THashSet<VirtualFile>(files.length); for (VirtualFile file : files) { if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow) file).getDelegate(); if (file != null) { realFiles.add(file); } } files = VfsUtil.toVirtualFileArray(realFiles); for (WritingAccessProvider accessProvider : myAccessProviders) { Collection<VirtualFile> denied = accessProvider.requestWriting(files); if (!denied.isEmpty()) { return new OperationStatusImpl(VfsUtil.toVirtualFileArray(denied)); } } final FileInfo[] fileInfos = createFileInfos(files); if (fileInfos.length == 0) { // if all files are already writable return createResultStatus(files); } if (ApplicationManager.getApplication().isUnitTestMode()) { return createResultStatus(files); } // This event count hack is necessary to allow actions that called this stuff could still get // data from their data contexts. // Otherwise data manager stuff will fire up an assertion saying that event count has been // changed (due to modal dialog show-up) // The hack itself is safe since we guarantee that focus will return to the same component had // it before modal dialog have been shown. final int savedEventCount = IdeEventQueue.getInstance().getEventCount(); if (myState.SHOW_DIALOG) { new ReadOnlyStatusDialog(myProject, fileInfos).show(); } else { processFiles( new ArrayList<FileInfo>(Arrays.asList(fileInfos)), null); // the collection passed is modified } IdeEventQueue.getInstance().setEventCount(savedEventCount); return createResultStatus(files); }
private boolean runNextEvent() { final RunnableInfo lastInfo = getNextEvent(true); myLastInfo = lastInfo; if (lastInfo != null) { synchronized (RUN_LOCK) { // necessary only because of switching to our own event queue AWTEvent event = ourEventQueue.getTrueCurrentEvent(); ourEventStack.push(event); int stackSize = ourEventStack.size(); try { lastInfo.runnable.run(); lastInfo.callback.setDone(); } catch (ProcessCanceledException ignored) { } catch (Throwable t) { LOG.error(t); } finally { LOG.assertTrue(ourEventStack.size() == stackSize); ourEventStack.pop(); if (!DEBUG) myLastInfo = null; } } } return lastInfo != null; }
@Override public void initialize() { try { base.initialize(); } catch (Exception ignore) { } myDisposable = Disposer.newDisposable(); Application application = ApplicationManager.getApplication(); if (application != null) { Disposer.register(application, myDisposable); } myMnemonicAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD, myDisposable); IdeEventQueue.getInstance() .addDispatcher( e -> { if (e instanceof KeyEvent && ((KeyEvent) e).getKeyCode() == KeyEvent.VK_ALT) { myAltPressed = e.getID() == KeyEvent.KEY_PRESSED; myMnemonicAlarm.cancelAllRequests(); final Component focusOwner = IdeFocusManager.findInstance().getFocusOwner(); if (focusOwner != null) { myMnemonicAlarm.addRequest(() -> repaintMnemonics(focusOwner, myAltPressed), 10); } } return false; }, myDisposable); }
void showPopup(Component component) { if (myPopup == null || myPopup.getContent() == null) { myPopup = JBPopupFactory.getInstance() .createComponentPopupBuilder(this, myKeyboardPanel.myFirstStroke) .setRequestFocus(true) .setTitle(KeyMapBundle.message("filter.settings.popup.title")) .setCancelKeyEnabled(false) .setMovable(true) .createPopup(); IdeEventQueue.getInstance() .addPostprocessor( new IdeEventQueue.EventDispatcher() { boolean isEscWasPressed = false; @Override public boolean dispatch(AWTEvent e) { if (e instanceof KeyEvent && e.getID() == KeyEvent.KEY_PRESSED) { boolean isEsc = ((KeyEvent) e).getKeyCode() == KeyEvent.VK_ESCAPE; if (isEscWasPressed && isEsc) { myPopup.cancel(); } isEscWasPressed = isEsc; } return false; } }, myPopup); } myPopup.showUnderneathOf(component); }
public static void setActiveRoot(WizardPopup aRootPopup) { disposeActiveWizard(); ourActiveWizardRoot = aRootPopup; ourShowingStep = aRootPopup; if (ApplicationManager.getApplication() != null) { IdeEventQueue.getInstance().getPopupManager().push(ourInstance); } }
public static void clearRootIfNeeded(WizardPopup aRootPopup) { if (ourActiveWizardRoot == aRootPopup) { ourActiveWizardRoot = null; ourShowingStep = null; if (ApplicationManager.getApplication() != null) { IdeEventQueue.getInstance().getPopupManager().remove(ourInstance); } } }
public boolean processAction(final InputEvent e, ActionProcessor processor) { ActionManagerEx actionManager = ActionManagerEx.getInstanceEx(); final Project project = PlatformDataKeys.PROJECT.getData(myContext.getDataContext()); final boolean dumb = project != null && DumbService.getInstance(project).isDumb(); List<AnActionEvent> nonDumbAwareAction = new ArrayList<AnActionEvent>(); for (final AnAction action : myContext.getActions()) { final Presentation presentation = myPresentationFactory.getPresentation(action); // Mouse modifiers are 0 because they have no any sense when action is invoked via keyboard final AnActionEvent actionEvent = processor.createEvent( e, myContext.getDataContext(), ActionPlaces.MAIN_MENU, presentation, ActionManager.getInstance()); ActionUtil.performDumbAwareUpdate(action, actionEvent, true); if (dumb && !action.isDumbAware()) { if (Boolean.FALSE.equals( presentation.getClientProperty(ActionUtil.WOULD_BE_ENABLED_IF_NOT_DUMB_MODE))) { continue; } nonDumbAwareAction.add(actionEvent); continue; } if (!presentation.isEnabled()) { continue; } processor.onUpdatePassed(e, action, actionEvent); ((DataManagerImpl.MyDataContext) myContext.getDataContext()) .setEventCount(IdeEventQueue.getInstance().getEventCount(), this); actionManager.fireBeforeActionPerformed(action, actionEvent.getDataContext(), actionEvent); Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(actionEvent.getDataContext()); if (component != null && !component.isShowing()) { return true; } processor.performAction(e, action, actionEvent); actionManager.fireAfterActionPerformed(action, actionEvent.getDataContext(), actionEvent); return true; } if (!nonDumbAwareAction.isEmpty()) { showDumbModeWarningLaterIfNobodyConsumesEvent( e, nonDumbAwareAction.toArray(new AnActionEvent[nonDumbAwareAction.size()])); } return false; }
@Override public void mouseReleased(MouseEvent e) { if (UIUtil.isCloseClick(e, MouseEvent.MOUSE_RELEASED)) { final TabInfo info = myTabs.findInfo(e); if (info != null) { IdeEventQueue.getInstance().blockNextEvents(e); FileEditorManagerEx.getInstanceEx(myProject) .closeFile((VirtualFile) info.getObject(), myWindow); } } }
@Override public void mouseReleased(MouseEvent e) { if (!isActionClick(e) || isMultiSelectionEnabled() && UIUtil.isSelectionButtonDown(e)) return; IdeEventQueue.getInstance() .blockNextEvents( e); // sometimes, after popup close, MOUSE_RELEASE event delivers to other components final Object selectedValue = myList.getSelectedValue(); final ListPopupStep<Object> listStep = getListStep(); handleSelect(handleFinalChoices(e, selectedValue, listStep), e); stopTimer(); }
@TestOnly public static void dispatchAllInvocationEventsInIdeEventQueue() throws InterruptedException { assert SwingUtilities.isEventDispatchThread() : Thread.currentThread(); final EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); while (true) { AWTEvent event = eventQueue.peekEvent(); if (event == null) break; AWTEvent event1 = eventQueue.getNextEvent(); if (event1 instanceof InvocationEvent) { IdeEventQueue.getInstance().dispatchEvent(event1); } } }
public void performAction( final InputEvent e, final AnAction action, final AnActionEvent actionEvent) { e.consume(); action.actionPerformed(actionEvent); if (Registry.is("actionSystem.fixLostTyping")) { IdeEventQueue.getInstance() .doWhenReady( new Runnable() { @Override public void run() { IdeEventQueue.getInstance().getKeyEventDispatcher().resetState(); } }); } }
public void cancel(InputEvent e) { if (isDisposed()) return; if (myPopup != null) { if (!canClose()) { return; } storeDimensionSize(myContent.getSize()); if (myUseDimServiceForXYLocation) { final JRootPane root = myComponent.getRootPane(); if (root != null) { final Container popupWindow = root.getParent(); if (popupWindow != null && popupWindow.isShowing()) { storeLocation(popupWindow.getLocationOnScreen()); } } } if (e instanceof MouseEvent) { IdeEventQueue.getInstance().blockNextEvents(((MouseEvent) e)); } myPopup.hide(false); if (ApplicationManagerEx.getApplicationEx() != null) { StackingPopupDispatcher.getInstance().onPopupHidden(this); } if (myInStack) { myFocusTrackback.setForcedRestore(!myOk && myFocusable); myFocusTrackback.restoreFocus(); } disposePopup(); if (myListeners != null) { for (JBPopupListener each : myListeners) { each.onClosed(new LightweightWindowEvent(this, myOk)); } } } Disposer.dispose(this, false); }
@Override @SuppressWarnings("deprecation") public void show() { myFocusTrackback = new FocusTrackback(getDialogWrapper(), getParent(), true); final DialogWrapper dialogWrapper = getDialogWrapper(); boolean isAutoAdjustable = dialogWrapper.isAutoAdjustable(); Point location = null; if (isAutoAdjustable) { pack(); Dimension packedSize = getSize(); Dimension minSize = getMinimumSize(); setSize( Math.max(packedSize.width, minSize.width), Math.max(packedSize.height, minSize.height)); setSize( (int) (getWidth() * dialogWrapper.getHorizontalStretch()), (int) (getHeight() * dialogWrapper.getVerticalStretch())); // Restore dialog's size and location myDimensionServiceKey = dialogWrapper.getDimensionKey(); if (myDimensionServiceKey != null) { final Project projectGuess = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(this)); location = DimensionService.getInstance().getLocation(myDimensionServiceKey, projectGuess); Dimension size = DimensionService.getInstance().getSize(myDimensionServiceKey, projectGuess); if (size != null) { myInitialSize = new Dimension(size); _setSizeForLocation(myInitialSize.width, myInitialSize.height, location); } } if (myInitialSize == null) { myInitialSize = getSize(); } } if (location == null) { location = dialogWrapper.getInitialLocation(); } if (location != null) { setLocation(location); } else { setLocationRelativeTo(getOwner()); } if (isAutoAdjustable) { final Rectangle bounds = getBounds(); ScreenUtil.fitToScreen(bounds); setBounds(bounds); } addWindowListener( new WindowAdapter() { @Override public void windowActivated(WindowEvent e) { final DialogWrapper wrapper = getDialogWrapper(); if (wrapper != null && myFocusTrackback != null) { myFocusTrackback.cleanParentWindow(); myFocusTrackback.registerFocusComponent( new FocusTrackback.ComponentQuery() { @Override public Component getComponent() { return wrapper.getPreferredFocusedComponent(); } }); } } @Override public void windowDeactivated(WindowEvent e) { if (!isModal()) { final Ref<IdeFocusManager> focusManager = new Ref<IdeFocusManager>(null); Project project = getProject(); if (project != null && !project.isDisposed()) { focusManager.set(getFocusManager()); focusManager .get() .doWhenFocusSettlesDown( new Runnable() { @Override public void run() { disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get()); } }); } else { disposeFocusTrackbackIfNoChildWindowFocused(focusManager.get()); } } } @Override public void windowOpened(WindowEvent e) { if (!SystemInfo.isMacOSLion) return; Window window = e.getWindow(); if (window instanceof Dialog) { ID _native = MacUtil.findWindowForTitle(((Dialog) window).getTitle()); if (_native != null && _native.intValue() > 0) { // see MacMainFrameDecorator // NSCollectionBehaviorFullScreenAuxiliary = 1 << 8 Foundation.invoke(_native, "setCollectionBehavior:", 1 << 8); } } } }); if (Registry.is("actionSystem.fixLostTyping")) { final IdeEventQueue queue = IdeEventQueue.getInstance(); if (queue != null) { queue.getKeyEventDispatcher().resetState(); } // if (myProject != null) { // Project project = myProject.get(); // if (project != null && !project.isDisposed() && project.isInitialized()) { // // IdeFocusManager.findInstanceByComponent(this).requestFocus(new // MyFocusCommand(dialogWrapper), true); // } // } } if (SystemInfo.isMac && myProject != null && Registry.is("ide.mac.fix.dialog.showing") && !dialogWrapper.isModalProgress()) { final IdeFrame frame = WindowManager.getInstance().getIdeFrame(myProject.get()); AppIcon.getInstance().requestFocus(frame); } setBackground(UIUtil.getPanelBackground()); final ApplicationEx app = ApplicationManagerEx.getApplicationEx(); if (app != null && !app.isLoaded() && Splash.BOUNDS != null) { final Point loc = getLocation(); loc.y = Splash.BOUNDS.y + Splash.BOUNDS.height; setLocation(loc); } super.show(); }
public long getIdleTime() { return IdeEventQueue.getInstance().getIdleTime(); }
public ApplicationImpl( boolean isInternal, boolean isUnitTestMode, boolean isHeadless, boolean isCommandLine, @NotNull String appName) { super(null); getPicoContainer().registerComponentInstance(Application.class, this); CommonBundle.assertKeyIsFound = isUnitTestMode; if ((isInternal || isUnitTestMode) && !Comparing.equal("off", System.getProperty("idea.disposer.debug"))) { Disposer.setDebugMode(true); } myStartTime = System.currentTimeMillis(); myName = appName; ApplicationManagerEx.setApplication(this); PluginsFacade.INSTANCE = new PluginsFacade() { public IdeaPluginDescriptor getPlugin(PluginId id) { return PluginManager.getPlugin(id); } public IdeaPluginDescriptor[] getPlugins() { return PluginManager.getPlugins(); } }; if (!isUnitTestMode && !isHeadless) { Toolkit.getDefaultToolkit().getSystemEventQueue().push(IdeEventQueue.getInstance()); if (Patches.SUN_BUG_ID_6209673) { RepaintManager.setCurrentManager(new IdeRepaintManager()); } IconLoader.activate(); } myIsInternal = isInternal; myTestModeFlag = isUnitTestMode; myHeadlessMode = isHeadless; myCommandLineMode = isCommandLine; loadApplicationComponents(); if (myTestModeFlag) { registerShutdownHook(); } if (!isUnitTestMode && !isHeadless) { Disposer.register(this, Disposer.newDisposable(), "ui"); StartupUtil.addExternalInstanceListener( new Consumer<List<String>>() { @Override public void consume(final List<String> args) { invokeLater( new Runnable() { @Override public void run() { final Project project = CommandLineProcessor.processExternalCommandLine(args); final IdeFrame frame; if (project != null) { frame = WindowManager.getInstance().getIdeFrame(project); } else { frame = WindowManager.getInstance().getAllFrames()[0]; } ((IdeFrameImpl) frame).requestFocus(); } }); } }); } final String s = System.getProperty("jb.restart.code"); if (s != null) { try { myRestartCode = Integer.parseInt(s); } catch (NumberFormatException ignore) { } } }
public void setState(final KeyState state) { myState = state; if (myQueue != null) { myQueue.maybeReady(); } }
private static boolean isControlEnterOnDialog(Component component, Shortcut sc) { return CONTROL_ENTER.equals(sc) && !IdeEventQueue.getInstance().isPopupActive() // avoid Control+Enter in completion && DialogWrapper.findInstance(component) != null; }
@SuppressWarnings({"SSBasedInspection"}) public class LaterInvocator { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.application.impl.LaterInvocator"); private static final boolean DEBUG = LOG.isDebugEnabled(); private static final Object LOCK = new Object(); private static final IdeEventQueue ourEventQueue = IdeEventQueue.getInstance(); private static final FrequentEventDetector ourFrequentEventDetector = new FrequentEventDetector(1009, 100); private LaterInvocator() {} private static class RunnableInfo { @NotNull private final Runnable runnable; @NotNull private final ModalityState modalityState; @NotNull private final Condition<?> expired; @NotNull private final ActionCallback callback; public RunnableInfo( @NotNull Runnable runnable, @NotNull ModalityState modalityState, @NotNull Condition<?> expired, @NotNull ActionCallback callback) { this.runnable = runnable; this.modalityState = modalityState; this.expired = expired; this.callback = callback; } @Override @NonNls public String toString() { return "[runnable: " + runnable + "; state=" + modalityState + (expired.value(null) ? "; expired" : "") + "] "; } } private static final List<Object> ourModalEntities = ContainerUtil.createLockFreeCopyOnWriteList(); private static final List<RunnableInfo> ourQueue = new ArrayList<RunnableInfo>(); // protected by LOCK private static volatile int ourQueueSkipCount = 0; // optimization private static final FlushQueue ourFlushQueueRunnable = new FlushQueue(); private static final Stack<AWTEvent> ourEventStack = new Stack<AWTEvent>(); // guarded by RUN_LOCK private static final EventDispatcher<ModalityStateListener> ourModalityStateMulticaster = EventDispatcher.create(ModalityStateListener.class); private static final List<RunnableInfo> ourForcedFlushQueue = new ArrayList<RunnableInfo>(); public static void addModalityStateListener( @NotNull ModalityStateListener listener, @NotNull Disposable parentDisposable) { if (!ourModalityStateMulticaster.getListeners().contains(listener)) { ourModalityStateMulticaster.addListener(listener, parentDisposable); } } @NotNull static ModalityStateEx modalityStateForWindow(@NotNull Window window) { int index = ourModalEntities.indexOf(window); if (index < 0) { Window owner = window.getOwner(); if (owner == null) { return (ModalityStateEx) ApplicationManager.getApplication().getNoneModalityState(); } ModalityStateEx ownerState = modalityStateForWindow(owner); if (window instanceof Dialog && ((Dialog) window).isModal()) { return ownerState.appendEntity(window); } return ownerState; } List<Object> result = new ArrayList<Object>(); for (Object entity : ourModalEntities) { if (entity instanceof Window || entity instanceof ProgressIndicator && ((ProgressIndicator) entity).isModal()) { result.add(entity); } } return new ModalityStateEx(result.toArray()); } @NotNull static ActionCallback invokeLater(@NotNull Runnable runnable, @NotNull Condition<?> expired) { ModalityState modalityState = ModalityState.defaultModalityState(); return invokeLater(runnable, modalityState, expired); } @NotNull static ActionCallback invokeLater( @NotNull Runnable runnable, @NotNull ModalityState modalityState) { return invokeLater(runnable, modalityState, Conditions.FALSE); } @NotNull static ActionCallback invokeLater( @NotNull Runnable runnable, @NotNull ModalityState modalityState, @NotNull Condition<?> expired) { ourFrequentEventDetector.eventHappened(); final ActionCallback callback = new ActionCallback(); RunnableInfo runnableInfo = new RunnableInfo(runnable, modalityState, expired, callback); synchronized (LOCK) { ourQueue.add(runnableInfo); } requestFlush(); return callback; } static void invokeAndWait( @NotNull final Runnable runnable, @NotNull ModalityState modalityState) { LOG.assertTrue(!isDispatchThread()); final Semaphore semaphore = new Semaphore(); semaphore.down(); final Ref<Throwable> exception = Ref.create(); Runnable runnable1 = new Runnable() { @Override public void run() { try { runnable.run(); } catch (Throwable e) { exception.set(e); } finally { semaphore.up(); } } @Override @NonNls public String toString() { return "InvokeAndWait[" + runnable + "]"; } }; invokeLater(runnable1, modalityState); semaphore.waitFor(); if (!exception.isNull()) { throw new RuntimeException(exception.get()); } } public static void enterModal(@NotNull Object modalEntity) { LOG.assertTrue(isDispatchThread(), "enterModal() should be invoked in event-dispatch thread"); if (LOG.isDebugEnabled()) { LOG.debug("enterModal:" + modalEntity); } ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(true); ourModalEntities.add(modalEntity); } public static void leaveModal(@NotNull Object modalEntity) { LOG.assertTrue(isDispatchThread(), "leaveModal() should be invoked in event-dispatch thread"); if (LOG.isDebugEnabled()) { LOG.debug("leaveModal:" + modalEntity); } //noinspection StatementWithEmptyBody while (ourFlushQueueRunnable.runNextEvent()) ; ourModalityStateMulticaster.getMulticaster().beforeModalityStateChanged(false); boolean removed = ourModalEntities.remove(modalEntity); LOG.assertTrue(removed, modalEntity); cleanupQueueForModal(modalEntity); ourQueueSkipCount = 0; requestFlush(); } private static void cleanupQueueForModal(@NotNull final Object modalEntity) { synchronized (LOCK) { for (Iterator<RunnableInfo> iterator = ourQueue.iterator(); iterator.hasNext(); ) { RunnableInfo runnableInfo = iterator.next(); if (runnableInfo.modalityState instanceof ModalityStateEx) { ModalityStateEx stateEx = (ModalityStateEx) runnableInfo.modalityState; if (stateEx.contains(modalEntity)) { ourForcedFlushQueue.add(runnableInfo); iterator.remove(); } } } } } @TestOnly static void leaveAllModals() { ourModalEntities.clear(); ourQueueSkipCount = 0; requestFlush(); } @NotNull public static Object[] getCurrentModalEntities() { ApplicationManager.getApplication().assertIsDispatchThread(); // TODO! // LOG.assertTrue(IdeEventQueue.getInstance().isInInputEvent() || isInMyRunnable()); return ArrayUtil.toObjectArray(ourModalEntities); } public static boolean isInModalContext() { LOG.assertTrue(isDispatchThread()); return !ourModalEntities.isEmpty(); } private static boolean isDispatchThread() { return ApplicationManager.getApplication().isDispatchThread(); } private static void requestFlush() { if (FLUSHER_SCHEDULED.compareAndSet(false, true)) { SwingUtilities.invokeLater(ourFlushQueueRunnable); } } /** * There might be some requests in the queue, but ourFlushQueueRunnable might not be scheduled * yet. In these circumstances {@link EventQueue#peekEvent()} default implementation would return * null, and {@link UIUtil#dispatchAllInvocationEvents()} would stop processing events too early * and lead to spurious test failures. * * @see IdeEventQueue#peekEvent() */ public static boolean ensureFlushRequested() { if (getNextEvent(false) != null) { SwingUtilities.invokeLater(ourFlushQueueRunnable); return true; } return false; } @Nullable private static RunnableInfo getNextEvent(boolean remove) { synchronized (LOCK) { if (!ourForcedFlushQueue.isEmpty()) { final RunnableInfo toRun = remove ? ourForcedFlushQueue.remove(0) : ourForcedFlushQueue.get(0); if (!toRun.expired.value(null)) { return toRun; } else { toRun.callback.setDone(); } } ModalityState currentModality; if (ourModalEntities.isEmpty()) { Application application = ApplicationManager.getApplication(); currentModality = application == null ? ModalityState.NON_MODAL : application.getNoneModalityState(); } else { currentModality = new ModalityStateEx(ourModalEntities.toArray()); } while (ourQueueSkipCount < ourQueue.size()) { RunnableInfo info = ourQueue.get(ourQueueSkipCount); if (info.expired.value(null)) { ourQueue.remove(ourQueueSkipCount); info.callback.setDone(); continue; } if (!currentModality.dominates(info.modalityState)) { if (remove) { ourQueue.remove(ourQueueSkipCount); } return info; } ourQueueSkipCount++; } return null; } } private static final AtomicBoolean FLUSHER_SCHEDULED = new AtomicBoolean(false); private static final Object RUN_LOCK = new Object(); private static class FlushQueue implements Runnable { @SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized") private RunnableInfo myLastInfo; @Override public void run() { FLUSHER_SCHEDULED.set(false); if (runNextEvent()) { requestFlush(); } } private boolean runNextEvent() { final RunnableInfo lastInfo = getNextEvent(true); myLastInfo = lastInfo; if (lastInfo != null) { synchronized (RUN_LOCK) { // necessary only because of switching to our own event queue AWTEvent event = ourEventQueue.getTrueCurrentEvent(); ourEventStack.push(event); int stackSize = ourEventStack.size(); try { lastInfo.runnable.run(); lastInfo.callback.setDone(); } catch (ProcessCanceledException ignored) { } catch (Throwable t) { LOG.error(t); } finally { LOG.assertTrue(ourEventStack.size() == stackSize); ourEventStack.pop(); if (!DEBUG) myLastInfo = null; } } } return lastInfo != null; } @Override public String toString() { return "LaterInvocator.FlushQueue" + (myLastInfo == null ? "" : " lastInfo=" + myLastInfo); } } @TestOnly public static List<RunnableInfo> getLaterInvocatorQueue() { synchronized (LOCK) { return ContainerUtil.newArrayList(ourQueue); } } }
private boolean inInitState() { Component focusOwner = myContext.getFocusOwner(); boolean isModalContext = myContext.isModalContext(); DataContext dataContext = myContext.getDataContext(); KeyEvent e = myContext.getInputEvent(); // http://www.jetbrains.net/jira/browse/IDEADEV-12372 if (myLeftCtrlPressed && myRightAltPressed && focusOwner != null && e.getModifiers() == (InputEvent.CTRL_MASK | InputEvent.ALT_MASK)) { if (Registry.is("actionSystem.force.alt.gr")) { return false; } final InputContext inputContext = focusOwner.getInputContext(); if (inputContext != null) { Locale locale = inputContext.getLocale(); if (locale != null) { @NonNls final String language = locale.getLanguage(); if (ALT_GR_LAYOUTS.contains(language)) { // don't search for shortcuts return false; } } } } KeyStroke originalKeyStroke = KeyStroke.getKeyStrokeForEvent(e); KeyStroke keyStroke = getKeyStrokeWithoutMouseModifiers(originalKeyStroke); if (myKeyGestureProcessor.processInitState()) { return true; } if (SystemInfo.isMac) { boolean keyTyped = e.getID() == KeyEvent.KEY_TYPED; boolean hasMnemonicsInWindow = e.getID() == KeyEvent.KEY_PRESSED && hasMnemonicInWindow(focusOwner, e.getKeyCode()) || keyTyped && hasMnemonicInWindow(focusOwner, e.getKeyChar()); boolean imEnabled = IdeEventQueue.getInstance().isInputMethodEnabled(); if (e.getModifiersEx() == InputEvent.ALT_DOWN_MASK && (hasMnemonicsInWindow || (!imEnabled && keyTyped))) { setPressedWasProcessed(true); setState(KeyState.STATE_PROCESSED); return false; } } updateCurrentContext(focusOwner, new KeyboardShortcut(keyStroke, null), isModalContext); if (myContext.getActions().isEmpty()) { // there's nothing mapped for this stroke return false; } if (myContext.isHasSecondStroke()) { myFirstKeyStroke = keyStroke; final ArrayList<Pair<AnAction, KeyStroke>> secondKeyStrokes = getSecondKeystrokeActions(); final Project project = PlatformDataKeys.PROJECT.getData(dataContext); StringBuilder message = new StringBuilder(); message.append(KeyMapBundle.message("prefix.key.pressed.message")); message.append(' '); for (int i = 0; i < secondKeyStrokes.size(); i++) { Pair<AnAction, KeyStroke> pair = secondKeyStrokes.get(i); if (i > 0) message.append(", "); message.append(pair.getFirst().getTemplatePresentation().getText()); message.append(" ("); message.append(KeymapUtil.getKeystrokeText(pair.getSecond())); message.append(")"); } StatusBar.Info.set(message.toString(), project); mySecondStrokeTimeout.cancelAllRequests(); mySecondStrokeTimeout.addRequest( mySecondStrokeTimeoutRunnable, Registry.intValue("actionSystem.secondKeystrokeTimeout")); if (Registry.is("actionSystem.secondKeystrokeAutoPopupEnabled")) { mySecondKeystrokePopupTimeout.cancelAllRequests(); if (secondKeyStrokes.size() > 1) { final DataContext oldContext = myContext.getDataContext(); mySecondKeystrokePopupTimeout.addRequest( new Runnable() { @Override public void run() { if (myState == KeyState.STATE_WAIT_FOR_SECOND_KEYSTROKE) { StatusBar.Info.set(null, PlatformDataKeys.PROJECT.getData(oldContext)); new SecondaryKeystrokePopup(myFirstKeyStroke, secondKeyStrokes, oldContext) .showInBestPositionFor(oldContext); } } }, Registry.intValue("actionSystem.secondKeystrokePopupTimeout")); } } setState(KeyState.STATE_WAIT_FOR_SECOND_KEYSTROKE); return true; } else { return processAction(e, myActionProcessor); } }
@Override public boolean isPopupActive() { return IdeEventQueue.getInstance().isPopupActive(); }