Overview
Ghidra’s event system provides a publish-subscribe mechanism for plugins to communicate. Events enable loose coupling between plugins, allowing them to broadcast notifications and respond to changes without direct dependencies.Event Architecture
The event system consists of:- PluginEvent: Base class for all events
- Event Producers: Plugins that fire events
- Event Consumers: Plugins that process events
- EventManager: Manages event registration and distribution
~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginEvent.java:26
Creating Plugin Events
Basic Event Structure
All plugin events must extendPluginEvent:
~/workspace/source/Ghidra/Features/Base/src/main/java/ghidra/app/events/ProgramActivatedPluginEvent.java:28
Event Naming Conventions
Descriptive Names
Event class names should clearly describe what happened (e.g.,
ProgramActivatedPluginEvent)Past Tense
Use past tense to indicate the event has occurred (e.g., “Activated”, not “Activate”)
PluginEvent Suffix
Always end class names with
PluginEventPackage Organization
Place events in appropriate packages (e.g.,
ghidra.app.events)Cross-Tool Events
Events can be passed between tools using the@ToolEventName annotation:
ToolConnection.
Reference: ~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginEvent.java:62
Producing Events
Declaring Events
Declare events your plugin produces in the@PluginInfo annotation:
~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:261
Firing Events
Fire events using thefirePluginEvent() method:
~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:468
Event Firing Best Practices
Fire After State Change
Fire After State Change
Always fire events AFTER the state change is complete to ensure consistency.
Use Weak References
Use Weak References
For events containing large objects, use
WeakReference to avoid memory leaks.Avoid Excessive Events
Avoid Excessive Events
Don’t fire events for every minor change. Batch updates when possible.
Consuming Events
Declaring Event Consumption
Declare events your plugin consumes in the@PluginInfo annotation:
~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:265
Processing Events
Override theprocessEvent() method to handle events:
~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:317
Event Filtering
Events from the source plugin are automatically filtered out:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:306
Common Event Types
Program Events
Events related to program lifecycle:Location Events
Events for navigation and cursor movement:Selection Events
Events for selection changes:Highlight Events
Events for highlighting code:Event Patterns
State Synchronization
Multiple plugins can stay synchronized through events:Event Cascading
Events can trigger other events:Trigger Event Tracking
Events can track what triggered them:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginEvent.java:99
EventManager API
TheEventManager handles event distribution within a tool:
Dynamic Event Registration
Plugins can register for events dynamically:~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/Plugin.java:568
Event System Best Practices
Event Granularity
Event Granularity
Create specific event types rather than generic ones. This makes code more maintainable and type-safe.
Immutable Event Data
Immutable Event Data
Make event data immutable to prevent modification by consumers.
Event Documentation
Event Documentation
Document when events are fired and what information they carry.
Avoid Blocking Operations
Avoid Blocking Operations
Event handlers should be fast. Move long operations to background tasks.
Debugging Events
Logging Events
Event Details
OverridegetDetails() for better debugging:
~/workspace/source/Ghidra/Framework/Project/src/main/java/ghidra/framework/plugintool/PluginEvent.java:122
Viewing Last Events
The tool maintains a history of recent events:Event vs Service Communication
When to use events vs services:| Use Events When | Use Services When |
|---|---|
| Broadcasting to multiple listeners | Direct method invocation needed |
| Loose coupling desired | Strong contract required |
| State changes to announce | Requesting data or operations |
| One-way notification | Two-way communication needed |
| Temporal decoupling needed | Immediate response required |
Common Patterns
Observer Pattern
Event Filtering
Related Documentation
- Plugin Development - Plugin lifecycle and structure
- Services - Service-based communication
