Search in sources :

Example 1 with IdeGlassPaneImpl

use of com.intellij.openapi.wm.impl.IdeGlassPaneImpl in project intellij-community by JetBrains.

the class IdeMouseEventDispatcher method dispatchMouseEvent.

/**
   * @return {@code true} if and only if the passed event is already dispatched by the
   *         {@code IdeMouseEventDispatcher} and there is no need for any other processing of the event.
   *         If the method returns {@code false} then it means that the event should be delivered
   *         to normal event dispatching.
   */
public boolean dispatchMouseEvent(MouseEvent e) {
    Component c = e.getComponent();
    //frame activation by mouse click
    if (e.getID() == MOUSE_PRESSED && c instanceof IdeFrame && !c.hasFocus()) {
        IdeFocusManager focusManager = IdeFocusManager.getGlobalInstance();
        if (focusManager instanceof FocusManagerImpl) {
            Component at = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY());
            if (at != null && at.isFocusable()) {
                ((FocusManagerImpl) focusManager).setLastFocusedAtDeactivation((IdeFrame) c, at);
            }
        }
    }
    if (e.isPopupTrigger()) {
        if (BUTTON3 == e.getButton()) {
            if (Registry.is("ide.mouse.popup.trigger.modifiers.disabled") && (~BUTTON3_DOWN_MASK & e.getModifiersEx()) != 0) {
                // it allows to use our mouse shortcuts for Ctrl+Button3, for example
                resetPopupTrigger(e);
            }
        } else if (SystemInfo.isXWindow) {
            // we can do better than silly triggering popup on everything but left click
            resetPopupTrigger(e);
        }
    }
    boolean ignore = false;
    if (!(e.getID() == MOUSE_PRESSED || e.getID() == MOUSE_RELEASED || e.getID() == MOUSE_WHEEL && 0 < e.getModifiersEx() || e.getID() == MOUSE_CLICKED)) {
        ignore = true;
    }
    patchClickCount(e);
    int clickCount = e.getClickCount();
    int button = MouseShortcut.getButton(e);
    if (button == MouseShortcut.BUTTON_WHEEL_UP || button == MouseShortcut.BUTTON_WHEEL_DOWN) {
        clickCount = 1;
    }
    if (e.isConsumed() || e.isPopupTrigger() || (button > 3 ? e.getID() != MOUSE_PRESSED && e.getID() != MOUSE_WHEEL : e.getID() != MOUSE_RELEASED) || clickCount < 1 || button == NOBUTTON) {
        // See #16995. It did happen
        ignore = true;
    }
    @JdkConstants.InputEventMask int modifiers = e.getModifiers();
    @JdkConstants.InputEventMask int modifiersEx = e.getModifiersEx();
    if (e.getID() == MOUSE_PRESSED) {
        myPressedModifiersStored = true;
        myModifiers = modifiers;
        myModifiersEx = modifiersEx;
    } else if (e.getID() == MOUSE_RELEASED) {
        myForceTouchIsAllowed = true;
        if (myPressedModifiersStored) {
            myPressedModifiersStored = false;
            modifiers = myModifiers;
            modifiersEx = myModifiersEx;
        }
    }
    final JRootPane root = findRoot(e);
    if (root != null) {
        BlockState blockState = myRootPane2BlockedId.get(root);
        if (blockState != null) {
            if (SWING_EVENTS_PRIORITY.indexOf(blockState.currentEventId) < SWING_EVENTS_PRIORITY.indexOf(e.getID())) {
                blockState.currentEventId = e.getID();
                if (blockState.blockMode == IdeEventQueue.BlockMode.COMPLETE) {
                    return true;
                } else {
                    ignore = true;
                }
            } else {
                myRootPane2BlockedId.remove(root);
            }
        }
    }
    if (c == null) {
        throw new IllegalStateException("component cannot be null");
    }
    c = SwingUtilities.getDeepestComponentAt(c, e.getX(), e.getY());
    if (c instanceof IdeGlassPaneImpl) {
        c = ((IdeGlassPaneImpl) c).getTargetComponentFor(e);
    }
    if (c == null) {
        // do nothing if component doesn't contains specified point
        return false;
    }
    if (c instanceof MouseShortcutPanel || c.getParent() instanceof MouseShortcutPanel) {
        // forward mouse processing to the special shortcut panel
        return false;
    }
    if (isHorizontalScrolling(c, e)) {
        boolean done = doHorizontalScrolling(c, (MouseWheelEvent) e);
        if (done)
            return true;
    }
    if (ignore)
        return false;
    // avoid "cyclic component initialization error" in case of dialogs shown because of component initialization failure
    if (!KeymapManagerImpl.ourKeymapManagerInitialized) {
        return false;
    }
    final MouseShortcut shortcut = new MouseShortcut(button, modifiersEx, clickCount);
    fillActionsList(c, shortcut, IdeKeyEventDispatcher.isModalContext(c));
    ActionManagerEx actionManager = ActionManagerEx.getInstanceEx();
    if (actionManager != null) {
        AnAction[] actions = myActions.toArray(new AnAction[myActions.size()]);
        for (AnAction action : actions) {
            DataContext dataContext = DataManager.getInstance().getDataContext(c);
            Presentation presentation = myPresentationFactory.getPresentation(action);
            AnActionEvent actionEvent = new AnActionEvent(e, dataContext, ActionPlaces.MAIN_MENU, presentation, ActionManager.getInstance(), modifiers);
            if (ActionUtil.lastUpdateAndCheckDumb(action, actionEvent, false)) {
                actionManager.fireBeforeActionPerformed(action, dataContext, actionEvent);
                final Component context = PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext);
                if (context != null && !context.isShowing())
                    continue;
                ActionUtil.performActionDumbAware(action, actionEvent);
                actionManager.fireAfterActionPerformed(action, dataContext, actionEvent);
                e.consume();
            }
        }
    }
    return e.getButton() > 3;
}
Also used : FocusManagerImpl(com.intellij.openapi.wm.impl.FocusManagerImpl) IdeGlassPaneImpl(com.intellij.openapi.wm.impl.IdeGlassPaneImpl) MouseShortcutPanel(com.intellij.openapi.keymap.impl.ui.MouseShortcutPanel) IdeFocusManager(com.intellij.openapi.wm.IdeFocusManager) IdeFrame(com.intellij.openapi.wm.IdeFrame) ActionManagerEx(com.intellij.openapi.actionSystem.ex.ActionManagerEx)

Example 2 with IdeGlassPaneImpl

use of com.intellij.openapi.wm.impl.IdeGlassPaneImpl in project intellij-community by JetBrains.

the class AbstractPopup method show.

public void show(Component owner, int aScreenX, int aScreenY, final boolean considerForcedXY) {
    if (ApplicationManagerEx.getApplicationEx() != null && ApplicationManager.getApplication().isHeadlessEnvironment())
        return;
    if (isDisposed()) {
        throw new IllegalStateException("Popup was already disposed. Recreate a new instance to show again");
    }
    assert ApplicationManager.getApplication().isDispatchThread();
    assert myState == State.INIT : "Popup was already shown. Recreate a new instance to show again.";
    debugState("show popup", State.INIT);
    myState = State.SHOWING;
    installWindowHook(this);
    installProjectDisposer();
    addActivity();
    final Component prevOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
    final boolean shouldShow = beforeShow();
    if (!shouldShow) {
        removeActivity();
        debugState("rejected to show popup", State.SHOWING);
        myState = State.INIT;
        return;
    }
    prepareToShow();
    if (myInStack) {
        myFocusTrackback = new FocusTrackback(this, owner, true);
        myFocusTrackback.setMustBeShown(true);
    }
    Dimension sizeToSet = null;
    if (myDimensionServiceKey != null) {
        sizeToSet = DimensionService.getInstance().getSize(myDimensionServiceKey, myProject);
    }
    if (myForcedSize != null) {
        sizeToSet = myForcedSize;
    }
    Rectangle screen = ScreenUtil.getScreenRectangle(aScreenX, aScreenY);
    if (myLocateWithinScreen) {
        Dimension size = sizeToSet != null ? sizeToSet : myContent.getPreferredSize();
        if (size.width > screen.width) {
            size.width = screen.width;
            sizeToSet = size;
        }
        if (size.height > screen.height) {
            size.height = screen.height;
            sizeToSet = size;
        }
    }
    if (sizeToSet != null) {
        sizeToSet.width = Math.max(sizeToSet.width, myContent.getMinimumSize().width);
        sizeToSet.height = Math.max(sizeToSet.height, myContent.getMinimumSize().height);
        myContent.setSize(sizeToSet);
        myContent.setPreferredSize(sizeToSet);
    }
    Point xy = new Point(aScreenX, aScreenY);
    boolean adjustXY = true;
    if (myUseDimServiceForXYLocation && myDimensionServiceKey != null) {
        final Point storedLocation = DimensionService.getInstance().getLocation(myDimensionServiceKey, myProject);
        if (storedLocation != null) {
            xy = storedLocation;
            adjustXY = false;
        }
    }
    if (adjustXY) {
        final Insets insets = myContent.getInsets();
        if (insets != null) {
            xy.x -= insets.left;
            xy.y -= insets.top;
        }
    }
    if (considerForcedXY && myForcedLocation != null) {
        xy = myForcedLocation;
    }
    fixLocateByContent(xy, false);
    Rectangle targetBounds = new Rectangle(xy, myContent.getPreferredSize());
    if (targetBounds.width > screen.width || targetBounds.height > screen.height) {
        LOG.warn("huge popup requested: " + targetBounds.width + " x " + targetBounds.height);
    }
    Rectangle original = new Rectangle(targetBounds);
    if (myLocateWithinScreen) {
        ScreenUtil.moveToFit(targetBounds, screen, null);
    }
    if (myMouseOutCanceller != null) {
        myMouseOutCanceller.myEverEntered = targetBounds.equals(original);
    }
    // use correct popup owner for non-modal dialogs too
    myOwner = getFrameOrDialog(owner);
    if (myOwner == null) {
        myOwner = owner;
    }
    myRequestorComponent = owner;
    boolean forcedDialog = myMayBeParent || SystemInfo.isMac && !(myOwner instanceof IdeFrame) && myOwner != null && myOwner.isShowing();
    PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog);
    myNativePopup = factory.isNativePopup();
    Component popupOwner = myOwner;
    if (popupOwner instanceof RootPaneContainer && !(popupOwner instanceof IdeFrame && !Registry.is("popup.fix.ide.frame.owner"))) {
        // JDK uses cached heavyweight popup for a window ancestor
        RootPaneContainer root = (RootPaneContainer) popupOwner;
        popupOwner = root.getRootPane();
        LOG.debug("popup owner fixed for JDK cache");
    }
    if (LOG.isDebugEnabled()) {
        LOG.debug("expected preferred size: " + myContent.getPreferredSize());
    }
    myPopup = factory.getPopup(popupOwner, myContent, targetBounds.x, targetBounds.y, this);
    if (LOG.isDebugEnabled()) {
        LOG.debug("  actual preferred size: " + myContent.getPreferredSize());
    }
    if ((targetBounds.width != myContent.getWidth()) || (targetBounds.height != myContent.getHeight())) {
        // JDK uses cached heavyweight popup that is not initialized properly
        LOG.debug("the expected size is not equal to the actual size");
        Window popup = myPopup.getWindow();
        if (popup != null) {
            popup.setSize(targetBounds.width, targetBounds.height);
            if (myContent.getParent().getComponentCount() != 1) {
                LOG.debug("unexpected count of components in heavy-weight popup");
            }
        } else {
            LOG.debug("cannot fix size for non-heavy-weight popup");
        }
    }
    if (myResizable) {
        final JRootPane root = myContent.getRootPane();
        final IdeGlassPaneImpl glass = new IdeGlassPaneImpl(root);
        root.setGlassPane(glass);
        int i = Registry.intValue("ide.popup.resizable.border.sensitivity", 4);
        WindowResizeListener resizeListener = new WindowResizeListener(myContent, myMovable ? JBUI.insets(i, i, i, i) : JBUI.insets(0, 0, i, i), isToDrawMacCorner() ? AllIcons.General.MacCorner : null) {

            private Cursor myCursor;

            @Override
            protected void setCursor(Component content, Cursor cursor) {
                if (myCursor != cursor || myCursor != Cursor.getDefaultCursor()) {
                    glass.setCursor(cursor, this);
                    myCursor = cursor;
                }
            }
        };
        glass.addMousePreprocessor(resizeListener, this);
        glass.addMouseMotionPreprocessor(resizeListener, this);
        myResizeListener = resizeListener;
    }
    if (myCaption != null && myMovable) {
        final WindowMoveListener moveListener = new WindowMoveListener(myCaption) {

            @Override
            public void mousePressed(final MouseEvent e) {
                if (e.isConsumed())
                    return;
                if (UIUtil.isCloseClick(e) && myCaption.isWithinPanel(e)) {
                    cancel();
                } else {
                    super.mousePressed(e);
                }
            }
        };
        myCaption.addMouseListener(moveListener);
        myCaption.addMouseMotionListener(moveListener);
        final MyContentPanel saved = myContent;
        Disposer.register(this, new Disposable() {

            @Override
            public void dispose() {
                ListenerUtil.removeMouseListener(saved, moveListener);
                ListenerUtil.removeMouseMotionListener(saved, moveListener);
            }
        });
        myMoveListener = moveListener;
    }
    for (JBPopupListener listener : myListeners) {
        listener.beforeShown(new LightweightWindowEvent(this));
    }
    myPopup.setRequestFocus(myRequestFocus);
    myPopup.show();
    WindowAction.setEnabledFor(myPopup.getWindow(), myResizable);
    final Window window = getContentWindow(myContent);
    myWindow = window;
    myWindowListener = new MyWindowListener();
    window.addWindowListener(myWindowListener);
    if (myFocusable) {
        window.setFocusableWindowState(true);
        window.setFocusable(true);
    }
    if (myWindow != null) {
        // we still have to be able to use IdeFrame as parent
        if (!myMayBeParent && !(myWindow instanceof Frame)) {
            WindowManager.getInstance().doNotSuggestAsParent(myWindow);
        }
    }
    setMinimumSize(myMinSize);
    final Runnable afterShow = () -> {
        if (myPreferredFocusedComponent != null && myInStack && myFocusable) {
            myFocusTrackback.registerFocusComponent(myPreferredFocusedComponent);
            if (myPreferredFocusedComponent instanceof JTextComponent) {
                IJSwingUtilities.moveMousePointerOn(myPreferredFocusedComponent);
            }
        }
        removeActivity();
        afterShow();
    };
    if (myRequestFocus) {
        getPopupWindow().setFocusableWindowState(true);
        getPopupWindow().setFocusable(true);
        getFocusManager().requestFocus(new FocusCommand() {

            @NotNull
            @Override
            public ActionCallback run() {
                if (isDisposed()) {
                    removeActivity();
                    return ActionCallback.DONE;
                }
                _requestFocus();
                final ActionCallback result = new ActionCallback();
                final Runnable afterShowRunnable = () -> {
                    afterShow.run();
                    result.setDone();
                };
                if (myNativePopup) {
                    final FocusRequestor furtherRequestor = getFocusManager().getFurtherRequestor();
                    //noinspection SSBasedInspection
                    SwingUtilities.invokeLater(() -> {
                        if (isDisposed()) {
                            result.setRejected();
                            return;
                        }
                        furtherRequestor.requestFocus(new FocusCommand() {

                            @NotNull
                            @Override
                            public ActionCallback run() {
                                if (isDisposed()) {
                                    return ActionCallback.REJECTED;
                                }
                                _requestFocus();
                                afterShowRunnable.run();
                                return ActionCallback.DONE;
                            }
                        }, true).notify(result).doWhenProcessed(() -> removeActivity());
                    });
                } else {
                    afterShowRunnable.run();
                }
                return result;
            }
        }, true).doWhenRejected(() -> afterShow.run());
    } else {
        //noinspection SSBasedInspection
        SwingUtilities.invokeLater(() -> {
            if (isDisposed()) {
                removeActivity();
                return;
            }
            if (X_WINDOW_FOCUS_BUG && !myRequestFocus && prevOwner != null && Registry.is("actionSystem.xWindow.remove.focus.from.nonFocusable.popups")) {
                new Alarm().addRequest(() -> {
                    if (isFocused()) {
                        IdeFocusManager.getInstance(myProject).requestFocus(prevOwner, false);
                    }
                }, Registry.intValue("actionSystem.xWindow.remove.focus.from.nonFocusable.popups.delay"));
            }
            afterShow.run();
        });
    }
    debugState("popup shown", State.SHOWING);
    myState = State.SHOWN;
}
Also used : JTextComponent(javax.swing.text.JTextComponent) NotNull(org.jetbrains.annotations.NotNull) JTextComponent(javax.swing.text.JTextComponent) Disposable(com.intellij.openapi.Disposable) IdeGlassPaneImpl(com.intellij.openapi.wm.impl.IdeGlassPaneImpl) RelativePoint(com.intellij.ui.awt.RelativePoint) RelativePoint(com.intellij.ui.awt.RelativePoint) Alarm(com.intellij.util.Alarm)

Aggregations

IdeGlassPaneImpl (com.intellij.openapi.wm.impl.IdeGlassPaneImpl)2 Disposable (com.intellij.openapi.Disposable)1 ActionManagerEx (com.intellij.openapi.actionSystem.ex.ActionManagerEx)1 MouseShortcutPanel (com.intellij.openapi.keymap.impl.ui.MouseShortcutPanel)1 IdeFocusManager (com.intellij.openapi.wm.IdeFocusManager)1 IdeFrame (com.intellij.openapi.wm.IdeFrame)1 FocusManagerImpl (com.intellij.openapi.wm.impl.FocusManagerImpl)1 RelativePoint (com.intellij.ui.awt.RelativePoint)1 Alarm (com.intellij.util.Alarm)1 JTextComponent (javax.swing.text.JTextComponent)1 NotNull (org.jetbrains.annotations.NotNull)1