Skip to content

MuleNotebook: dispatch the right-click forward synchronously so PopupMenu's grab is fresh - #683

Merged
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/mulenotebook-rclick-popup-async-race
May 22, 2026
Merged

MuleNotebook: dispatch the right-click forward synchronously so PopupMenu's grab is fresh#683
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix/mulenotebook-rclick-popup-async-race

Conversation

@got3nks

@got3nks got3nks commented May 22, 2026

Copy link
Copy Markdown
Contributor

Addresses the right-click-category-menu-doesn't-latch half of #680 (intermittent, amulegui-only, ~80 % failure rate per Stoatwblr).

CMuleNotebook::OnRMButton (src/MuleNotebook.cpp:136) receives the EVT_RIGHT_DOWN event from the category notebook, then at line 168 forwards it to the parent widget (e.g. CTransferWnd::OnNMRclickDLtab, which calls PopupMenu()) via:

m_popup_widget->GetEventHandler()->AddPendingEvent( evt );

AddPendingEvent is asynchronous — it queues the event for delivery on the next event-loop cycle. The original button-down handler returns, the X11 button-down event is consumed, and PopupMenu() only runs later when the queued event is dispatched. By that time the user has typically already released the right button; the late button-up arrives just after PopupMenu() has opened the menu, and wxGTK interprets it as "dismiss the menu opened just now". The popup vanishes on button-release, looking like the menu "doesn't latch on".

Stoatwblr's strace (failing case, pid 1154904 reading from fd=4 continuously) confirmed it: PopupMenu() was returning immediately, with no pause in the event drain that a properly-latched modal popup would cause.

Why amulegui-only / ~80 %: the queue→dispatch latency varies with event-loop activity. Monolithic amule's main thread has lower per-tick latency; amulegui has the 1 Hz EC poll timer + EC traffic + internal work between event-queue insertions and dispatches, so the queued event is delivered ~10-20 ms later than in monolithic — long enough that the human's button-release arrives first the bulk of the time.

Fix

Replace AddPendingEvent with ProcessEvent, which runs the parent's handler synchronously inside the same button-down stack while the pointer grab is still fresh:

m_popup_widget->GetEventHandler()->ProcessEvent( evt );

Monolithic amule is unaffected (the handler runs in the same stack regardless), and amulegui gets the same fresh-grab guarantee. Comment in-place explains why the dispatch needs to be synchronous so a future passer-by doesn't switch it back.

…Menu's grab is fresh (amule-project#680)

CMuleNotebook::OnRMButton forwards the EVT_RIGHT_DOWN event to the
parent's handler (which calls PopupMenu) via AddPendingEvent.
That's asynchronous: the button-down handler returns, the X11
button-down event is consumed, and PopupMenu only runs later when
the queued event is dispatched. By that time the user has typically
released the right button; the late button-up arrives just after
PopupMenu has opened the menu, and wxGTK interprets it as "dismiss
the menu opened just now". The popup vanishes on button-release,
looking like the menu doesn't latch on.

Monolithic amule was lucky enough most of the time -- main thread
has tight per-tick latency. amulegui has the 1 Hz EC poll timer +
EC traffic between event-queue inserts and dispatches, which adds
~10-20 ms of latency, long enough that the human's button-release
beats PopupMenu about 80 % of the time per the issue report.

Replace AddPendingEvent with ProcessEvent so the parent's handler
runs synchronously inside the same button-down stack while the
pointer grab is still fresh. Monolithic is unaffected (the handler
runs in the same stack regardless); amulegui gets the same
fresh-grab guarantee.
@got3nks got3nks mentioned this pull request May 22, 2026
@mrjimenez
mrjimenez merged commit d3ccb0c into amule-project:master May 22, 2026
12 checks passed
@got3nks
got3nks deleted the fix/mulenotebook-rclick-popup-async-race branch May 22, 2026 23:44
mrjimenez pushed a commit to mrjimenez/amule that referenced this pull request Jul 30, 2026
…ct#683)

Shrinks the per-tab connect button and names its network (Connect/Disconnect/Cancel ED2K|Kad), adds top padding to both network tabs' first row, and scales the button icon to a uniform DPI-aware size with a per-(state, size) cache.

Bitmap margins are wxOSX-only: wxMSW keeps its native font-derived default, wxGTK keeps the leading-space fallback since it has no margin support.

Kad tab redesigned to mirror the ED2K tab: the graph spans the full width with the bootstrap-from-node row beneath it, and the four-octet IP entry collapses to a single trimmed x.x.x.x field.

Drops two redundant controls: the inert global Connect toolbar button (no event binding since amule-project#663/amule-project#677) and the "Bootstrap from known clients" button, which called the same StartKad() as the Kad tab's own Connect toggle.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants