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);
  }
Exemple #13
0
    @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();
 }