void (int uid, int eventType, boolean doFiltering) { // glib main-loop thread if (windowHandle == null || myIsDisposed) { if (TRACE_ENABLED) _trace("window was closed when received event '%s', just skip it", _evtype2str(eventType)); return; } final MenuItemInternal mi = _findMenuItem(uid); if (mi == null) { LOG.debug("can't find menu-item by uid " + uid + ", eventType=" + eventType); return; } if (mi.nativePeer == null) { LOG.debug("menu-item hasn't native peer, uid = " + uid + ", eventType=" + eventType); return; } if (mi.action == null) { LOG.debug("menu-item hasn't associated AnAction, uid = " + uid + ", eventType=" + eventType); return; } if (TRACE_EVENTS) _trace("received event '%s' from item %s", _evtype2str(eventType), mi); if (!DISABLE_EVENTS_FILTERING && !isFirstFilling && doFiltering && !eventFilter.check(uid, eventType, mi)) { return; } if (isFirstFilling) { final Timer timer = new Timer(5000, e -> isFirstFilling = false); timer.setRepeats(false); timer.start(); } if (_isFillEvent(eventType)) { // glib main-loop thread if (!DONT_CLOSE_POPUPS) { ApplicationManager.getApplication().invokeLater(() -> IdeEventQueue.getInstance().getPopupManager().closeAllPopups()); } mi.cancelClearSwing(); // simple check to avoid double (or frequent) filling final long timeMs = System.currentTimeMillis(); int[] stats = new int[]{0, 0, 0}; if (timeMs - mi.lastFilledMs < 1500 && mi.lastClearedMs < mi.lastFilledMs) { if (TRACE_SKIPPED_EVENT) _trace("skipped fill-event for item '%s', use cached (too frequent fill-events)", String.valueOf(mi.txt)); } else { ApplicationManager.getApplication().invokeAndWait(() -> { // ETD-start final JMenuItem jmi = mi.jitem; if (jmi == null) { if (TRACE_HIERARCHY_MISMATCHES) { _trace( "corresponding (opening) swing item is null, event source: " + mi + ", swing menu hierarchy:\n" + _dumpSwingHierarchy()); } return; } if (!(jmi instanceof ActionMenu am)) { LOG.debug("corresponding (opening) swing item isn't instance of ActionMenu, class=" + jmi.getClass().getName() + ", event source: " + mi); return; } mi.lastFilledMs = timeMs; am.removeAll(); am.setSelected(true); am.fillMenu(); _syncChildren(mi, am, DONT_FILL_SUBMENU ? 1 : 2, stats); // NOTE: fill next submenus level to avoid empty submenu showing (intermittent behaviour of menu-applet) }); // glib main-loop thread final long elapsedMs = System.currentTimeMillis() - timeMs; if (TRACE_SYNC_STATS) { _trace("filled menu %s '%s', spent (in EDT) %d ms, stats: %s", (mi.isRoot() ? "root menu" : "submenu"), String.valueOf(mi.txt), elapsedMs, _stats2str(stats)); } _processChildren(mi); } } if (eventType == GlobalMenuLib.EVENT_CLOSED) { // glib main-loop thread mi.scheduleClearSwing(); return; } if (eventType == GlobalMenuLib.EVENT_CLICKED) { _trace("process click event (%s), event source: %s", _evtype2str(eventType), mi); final JMenuItem jmi = mi.jitem; if (jmi == null) { if (TRACE_HIERARCHY_MISMATCHES) { _trace( "can't find corresponding (clicked) ActionMenuItem, event source: " + mi + ", swing menu hierarchy:\n" + _dumpSwingHierarchy()); } return; } if (!(jmi instanceof ActionMenuItem ami)) { LOG.debug("corresponding (clicked) swing item isn't instance of ActionMenuItem, class=" + jmi.getClass().getName() + ", event source: " + mi); return; } ApplicationManager.getApplication().invokeLater(() -> ami.doClick()); } }