mirror of
https://github.com/zoriya/fairy.git
synced 2025-12-06 05:36:09 +00:00
177 lines
5.1 KiB
JavaScript
177 lines
5.1 KiB
JavaScript
"use strict";
|
|
|
|
const Gio = imports.gi.Gio;
|
|
const St = imports.gi.St;
|
|
|
|
const GObject = imports.gi.GObject;
|
|
const Main = imports.ui.main;
|
|
const Meta = imports.gi.Meta;
|
|
const Shell = imports.gi.Shell;
|
|
const PanelMenu = imports.ui.panelMenu;
|
|
const PopupMenu = imports.ui.popupMenu;
|
|
const Clutter = imports.gi.Clutter;
|
|
|
|
const ExtensionUtils = imports.misc.extensionUtils;
|
|
const Me = ExtensionUtils.getCurrentExtension();
|
|
|
|
var Indicator = GObject.registerClass(
|
|
class Indicator extends GObject.Object {
|
|
_init() {
|
|
super._init();
|
|
|
|
this._layoutIcons = {
|
|
tiling: Gio.icon_new_for_string(`${Me.path}/icons/tiling.svg`),
|
|
monocle: Gio.icon_new_for_string(`${Me.path}/icons/monocle.svg`),
|
|
floating: Gio.icon_new_for_string(`${Me.path}/icons/floating.svg`),
|
|
deck: Gio.icon_new_for_string(`${Me.path}/icons/deck.svg`),
|
|
};
|
|
this._destroyed = true;
|
|
}
|
|
|
|
endInit(ext) {
|
|
this._state = ext._state;
|
|
this._settings = ext._settings;
|
|
this._renderer = ext._renderer;
|
|
this._keybinds = ext._keybinds;
|
|
}
|
|
|
|
_createSelectableItem(title, cb) {
|
|
const menuItem = new PopupMenu.PopupMenuItem(title, {});
|
|
menuItem.connect("activate", cb);
|
|
return menuItem;
|
|
}
|
|
|
|
enable() {
|
|
const tagIndicatorName = `${Me.metadata.name} Tag Indicator`;
|
|
this._tagIndicator = new PanelMenu.Button(0.0, tagIndicatorName);
|
|
this._settings.bind(
|
|
"show-tags",
|
|
this._tagIndicator,
|
|
"visible",
|
|
Gio.SettingsBindFlags.DEFAULT
|
|
);
|
|
|
|
const indicatorName = `${Me.metadata.name} Layout Indicator`;
|
|
this._layoutIndicator = new PanelMenu.Button(0.0, indicatorName);
|
|
this._icon = new St.Icon({
|
|
gicon: this._layoutIcons.tiling,
|
|
style_class: "system-status-icon",
|
|
});
|
|
this._layoutIndicator.add_child(this._icon);
|
|
|
|
this._layoutPanelItems = {
|
|
tiling: this._createSelectableItem("Tiling", () =>
|
|
this._keybinds.switchLayout("tiling")
|
|
),
|
|
monocle: this._createSelectableItem("Monocle", () =>
|
|
this._keybinds.switchLayout("monocle")
|
|
),
|
|
floating: this._createSelectableItem("Floating", () =>
|
|
this._keybinds.switchLayout("floating")
|
|
),
|
|
deck: this._createSelectableItem("Deck", () =>
|
|
this._keybinds.switchLayout("deck")
|
|
),
|
|
};
|
|
this._nmasterPanelItem = new PopupMenu.PopupMenuItem("nmaster", {});
|
|
this._mfactPanelItem = new PopupMenu.PopupMenuItem("mfact", {});
|
|
this._layoutIndicator.menu.addMenuItem(this._layoutPanelItems.tiling);
|
|
this._layoutIndicator.menu.addMenuItem(this._layoutPanelItems.monocle);
|
|
this._layoutIndicator.menu.addMenuItem(this._layoutPanelItems.floating);
|
|
this._layoutIndicator.menu.addMenuItem(this._layoutPanelItems.deck);
|
|
this._layoutIndicator.menu.addMenuItem(
|
|
new PopupMenu.PopupSeparatorMenuItem()
|
|
);
|
|
this._layoutIndicator.menu.addMenuItem(this._nmasterPanelItem);
|
|
this._layoutIndicator.menu.addMenuItem(this._mfactPanelItem);
|
|
|
|
this._settings.bind(
|
|
"show-layout",
|
|
this._layoutIndicator,
|
|
"visible",
|
|
Gio.SettingsBindFlags.DEFAULT
|
|
);
|
|
|
|
Main.panel.addToStatusArea(
|
|
indicatorName,
|
|
this._layoutIndicator,
|
|
1,
|
|
"left"
|
|
);
|
|
Main.panel.addToStatusArea(
|
|
tagIndicatorName,
|
|
this._tagIndicator,
|
|
1,
|
|
"left"
|
|
);
|
|
this._destroyed = false;
|
|
this.update();
|
|
|
|
this._settings.connect("changed", () => this.update());
|
|
}
|
|
|
|
disable() {
|
|
this._destroyed = true;
|
|
this._tagIndicator.destroy();
|
|
this._tagIndicator = null;
|
|
|
|
this._layoutPanelItems = {};
|
|
this._nmasterPanelItem = null;
|
|
this._mfactPanelItem = null;
|
|
this._layoutIndicator.destroy();
|
|
this._layoutIndicator = null;
|
|
this._icon = null;
|
|
|
|
this._settings.disconnect("changed");
|
|
}
|
|
|
|
update() {
|
|
if (this._destroyed) return;
|
|
|
|
const mon = global.display.get_primary_monitor();
|
|
const state = this._state.monitors[mon];
|
|
|
|
// TODO: Retrieve the following two from the settings.
|
|
const tagName = this._settings.get_strv("tag-names");
|
|
const activeColor = this._settings.get_string("active-tags-color");
|
|
|
|
this._tagIndicator.destroy_all_children();
|
|
let tagBox = new St.BoxLayout();
|
|
this._tagIndicator.add_child(tagBox);
|
|
for (let tagNbr = 0; tagNbr < 9; tagNbr++) {
|
|
const tag = 0b1 << tagNbr;
|
|
const active = state.tags & tag;
|
|
const hasWindow =
|
|
this._state.windows.find((x) => x.monitor == mon && x.tags & tag) !==
|
|
undefined;
|
|
if (!active && !hasWindow) continue;
|
|
const style = "width: 30px;";
|
|
const tagBtn = new St.Button({
|
|
can_focus: true,
|
|
style: active ? `${style} background-color: ${activeColor};` : style,
|
|
});
|
|
tagBtn.set_child(
|
|
new St.Label({
|
|
x_align: Clutter.ActorAlign.CENTER,
|
|
y_align: Clutter.ActorAlign.CENTER,
|
|
text: tagName[tagNbr] ?? (tagNbr + 1).toString(),
|
|
})
|
|
);
|
|
tagBtn.connect("clicked", () => this._renderer.setTags(mon, tag));
|
|
tagBox.add_child(tagBtn);
|
|
}
|
|
|
|
this._icon.gicon = this._layoutIcons[state.layout];
|
|
for (const [key, value] of Object.entries(this._layoutPanelItems)) {
|
|
value.setOrnament(
|
|
key === state.layout
|
|
? PopupMenu.Ornament.DOT
|
|
: PopupMenu.Ornament.NONE
|
|
);
|
|
}
|
|
this._nmasterPanelItem.label.text = `nmaster: ${state.nmaster}`;
|
|
this._mfactPanelItem.label.text = `mfact: ${state.mfact}%`;
|
|
}
|
|
}
|
|
);
|