Widgets are plugins. The memory chart is the built-in one; external plugins are jar files placed in
~/.mjdev/plugins/. The control center Plugins tab lists them (image, label, on/off switch,
expandable details) and the enabled ones are drawn on the desktop.
my-plugin.jar
├── plugin.json metadata, read WITHOUT running plugin code
├── icon.png optional image (or name it in plugin.json "icon")
├── META-INF/services/org.mjdev.desktop.plugins.IDesktopPlugin -> one implementation class
└── com/example/MyPlugin.class
plugin.json:
{
"id": "com.example.clock",
"name": "Clock",
"description": "Shows the time.",
"version": "1.0",
"author": "Example",
"icon": "icon.png"
}
Implement org.mjdev.desktop.plugins.IDesktopPlugin: expose a RemoteDocument (the look, plain
data: RECT, ARC, TEXT ops with geometry normalized to 0..1) and return live
RemoteVariables from variables() (numbers drive sweepVar of arcs, texts replace {name}
placeholders). Colors use palette tokens (BACKGROUND, TEXT, ICONS, BORDER, SELECTED) so a
widget follows the wallpaper; #RRGGBB / #AARRGGBB are also accepted. See
MemoryWidgetPlugin for a complete example. RemoteDocument.encode() / decode() give the JSON form.
A plugin jar runs with the same permissions as the desktop once it is enabled. Metadata and image are read without loading any class, and nothing is loaded until the user switches the plugin on. Only enable plugins you trust.
State (which plugins are enabled) is stored in ~/.mjdev/desktop/plugins.json.