Skip to main content

Widget Actions

Verification boundary

This page documents the committed source. Treat revision-sensitive RuneLite UI, packet, or in-game outcomes as pending live-client verification unless the page records direct evidence.

WidgetActions (com.n3plugins.Api.actions) clicks interface components: spell icons, dialog buttons, tab panels, and CS2 components that carry no named menu action. Every action queues its mouse-click packet before the widget operation, returns an InteractionResult, and routes through ActionPacer.

Click by action name

interact requires a unique action-name match and resolves it to a 1-based op index. A component with an onOp listener is invoked through RuneLite's native CC_OP path so the client listener runs; other named components use the direct widget packet path:

WidgetActions.interact(packedWidgetId, "Continue");
WidgetActions.interact(widget, "Select");

The native path uses the shared MenuDispatcher. Production resolves the vanilla static method through the revision cache described in menu-action-dispatch.md; it does not call an injected Client.menuAction(...) method. Resolution or invocation failure returns PACKET_NOT_QUEUED.

MethodTarget
interact(int widgetId, String... actions)packed widget id
interact(Widget widget, String... actions)a resolved widget

When the component exposes none of the listed actions, interact returns ACTION_NOT_FOUND and queues nothing. Multiple matching action slots also fail closed instead of choosing the first.

For an action followed by numeric input, use interactThenResumeCount(widget, count, actions). It preserves the ordered click, widget operation, and resume-count dispatch for both raw and native widget operations.

Click by raw op index

Many interface components carry no named action. The action-name path fails on them, so the click never queues. clickOp fires a 1-based op directly and skips action-name resolution:

WidgetAddress close = WidgetCatalog.getInstance()
.requireAddress("net.runelite.api.gameval.InterfaceID.SharedBank.CLOSE");
WidgetActions.clickOp(close.getPackedId(), 1);
WidgetActions.clickOp(widget, 1);
MethodTarget
clickOp(int widgetId, int op)packed widget id, raw op
clickOp(Widget widget, int op)a resolved widget, raw op

clickOp guards a null or hidden widget and returns the matching failure status. Use it when a component reacts to a click but lists no menu action. Confirm the op index against the widget inspector on a live run, since the mapping is not exposed by name. The packed ID should still come from a current WidgetCatalog address, RuneLite ComponentID, or gameval-backed InterfaceID constant; the stage-one correctness audit rejects unreviewed raw production literals.

clickOp is still a complete action operation: it applies pacing and queues the click packet before the explicit raw widget packet. The lower-level WidgetPackets.queueWidgetActionPacket(...) method is packet-only and is reserved for reviewed callers that explicitly queue their click first.

subAction reaches a nested menu entry on a widget:

WidgetActions.subAction(widget, "Cast", "Resurrect");
MethodDoes
subAction(Widget widget, String menu, String action)clicks action under the menu sub-menu of widget

Finding the widget first

WidgetActions acts on a widget you already resolved. To locate one, use the widget query helpers in query-helpers.md, or Api.actions.widgets (get, search, firstByAction/firstByName/firstByText) in automation-api.md. The query name predicates strip HTML tags widget-side, so pass bare strings.

When visible text belongs to a descriptive child, use WidgetInteractionResolver.findByText(root, text, actions). It examines the match and a bounded parent chain, requires one visible named-action owner, and returns explicit resolved, missing, or ambiguous status. It does not select an arbitrary sibling.

To inspect components while building a plugin, see WidgetExplorer and WidgetDescriptor in packet-debugging.md.