import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js'; import * as Main from 'resource:///org/gnome/shell/ui/main.js'; import { ClaudeStatusIndicator } from './lib/indicator.js'; export default class ClaudeCodeStatusExtension extends Extension { enable() { this._settings = this.getSettings(); this._place(); // Placement is applied by rebuilding rather than by moving the actor. // addToStatusArea is what registers the indicator under this uuid and // there is no documented call to move one between panel boxes; the // alternatives all reach into Main.panel's private boxes. Rebuilding // costs one re-read of a handful of small state files, and only when // the setting is touched. this._placementId = this._settings.connect('changed::panel-box', () => this._replace()); this._positionId = this._settings.connect('changed::panel-position', () => this._replace()); } disable() { for (const id of [this._placementId, this._positionId]) { if (id) this._settings.disconnect(id); } this._placementId = 0; this._positionId = 0; this._indicator?.destroy(); this._indicator = null; this._settings = null; } _place() { this._indicator = new ClaudeStatusIndicator(this); // Centre box, index 1 by default: immediately right of the clock, // which is the centre box's only occupant. The status area on the // right is where you look for the system's own state; sessions belong // next to the thing you already glance at. An index past the end of // the box lands at the end, so a large one is a way of saying "last". Main.panel.addToStatusArea(this.uuid, this._indicator, this._settings.get_int('panel-position'), this._settings.get_string('panel-box')); } _replace() { // The indicator's own destroy handler is what unregisters it from the // status area, so this must happen before the next addToStatusArea -- // that call throws on a uuid that is still registered. this._indicator?.destroy(); this._indicator = null; this._place(); } }