@Override
    public void eventDispatched(final AWTEvent e) {
      if (mySmartFadeoutDelay > 0) {
        startFadeoutTimer(mySmartFadeoutDelay);
        mySmartFadeoutDelay = 0;
      }

      final int id = e.getID();
      if (e instanceof MouseEvent me) {
        final boolean insideBalloon = isInsideBalloon(me);

        boolean forcedExit = id == MouseEvent.MOUSE_EXITED && me.getButton() != MouseEvent.NOBUTTON && !myBlockClicks;
        if (myHideOnMouse && (id == MouseEvent.MOUSE_PRESSED || forcedExit)) {
          if ((!insideBalloon || forcedExit) && !isWithinChildWindow(me)) {
            if (myHideListener == null) {
              hide();
              if (forcedExit) {
                int[] ids = {MouseEvent.MOUSE_ENTERED, MouseEvent.MOUSE_PRESSED, MouseEvent.MOUSE_RELEASED, MouseEvent.MOUSE_CLICKED};
                for (int id_ : ids) {
                  IdeEventQueue.getInstance()
                    .dispatchEvent(new MouseEvent(me.getComponent(), id_, me.getWhen(), me.getModifiers(), me.getX(), me
                      .getY(), me.getClickCount(), me.isPopupTrigger(), me.getButton()));
                }
              }
            }
            else if (myHideListener instanceof HideListenerWithMouse listener) {
              listener.run(me);
            }
            else {
              myHideListener.run();
            }
          }
          return;
        }

        if (myClickHandler != null && id == MouseEvent.MOUSE_CLICKED) {
          if (!(me.getComponent() instanceof CloseButton) && insideBalloon) {
            myClickHandler.actionPerformed(new ActionEvent(me, ActionEvent.ACTION_PERFORMED, "click", me.getModifiersEx()));
            if (myCloseOnClick) {
              hide();
              return;
            }
          }
        }

        if (myEnableButtons && id == MouseEvent.MOUSE_MOVED) {
          final boolean moveChanged = insideBalloon != myLastMoveWasInsideBalloon;
          myLastMoveWasInsideBalloon = insideBalloon;
          if (moveChanged) {
            if (insideBalloon && !myFadeoutAlarm.isEmpty()) { //Pause hiding timer when mouse is hover
              myFadeoutAlarm.cancelAllRequests();
              myFadeoutRequestDelay -= System.currentTimeMillis() - myFadeoutRequestMillis;
            }
            if (!insideBalloon && myFadeoutRequestDelay > 0) {
              startFadeoutTimer(myFadeoutRequestDelay);
            }
            component.repaintButton();
          }
        }

        if (myHideOnCloseClick && UIUtil.isCloseClick(me)) {
          if (isInsideBalloon(me)) {
            hide();
            me.consume();
          }
          return;
        }
      }

      if ((myHideOnKey || myHideListener != null) && e instanceof KeyEvent ke && id == KeyEvent.KEY_PRESSED) {
        if (myHideListener != null) {
          if (ke.getKeyCode() == KeyEvent.VK_ESCAPE) {
            myHideListener.run();
          }
          return;
        }
        if (ke.getKeyCode() != KeyEvent.VK_SHIFT &&
            ke.getKeyCode() != KeyEvent.VK_CONTROL &&
            ke.getKeyCode() != KeyEvent.VK_ALT &&
            ke.getKeyCode() != KeyEvent.VK_META &&
            ke.getKeyCode() != KeyEvent.VK_WINDOWS) {
          boolean doHide = false;
          // Close the balloon is ESC is pressed inside the balloon
          if (ke.getKeyCode() == KeyEvent.VK_ESCAPE && SwingUtilities.isDescendingFrom(ke.getComponent(), component)) {
            doHide = true;
          }
          // Close the balloon if any key is pressed outside the balloon
          //noinspection ConstantConditions
          if (myHideOnKey && !SwingUtilities.isDescendingFrom(ke.getComponent(), component)) {
            doHide = true;
          }
          if (doHide) {
            hide();
          }
        }
      }
    }
@Override
    public void eventDispatched(final AWTEvent e)