mirror of
https://gitlab.gnome.org/julianschacher/top-bar-organizer.git
synced 2025-10-27 15:19:09 +00:00
164 lines
6.6 KiB
JavaScript
164 lines
6.6 KiB
JavaScript
"use strict";
|
|
/* exported init */
|
|
|
|
const ExtensionUtils = imports.misc.extensionUtils;
|
|
const Me = ExtensionUtils.getCurrentExtension();
|
|
|
|
const Main = imports.ui.main;
|
|
const Panel = imports.ui.panel;
|
|
|
|
const BoxOrderManager = Me.imports.extensionModules.BoxOrderManager;
|
|
|
|
class Extension {
|
|
constructor() {
|
|
}
|
|
|
|
enable() {
|
|
this.settings = ExtensionUtils.getSettings();
|
|
|
|
this._boxOrderManager = new BoxOrderManager.BoxOrderManager();
|
|
|
|
/// Stuff to do on startup(extension enable).
|
|
// Initially handle new top bar items and order top bar boxes.
|
|
this.#handleNewItemsAndOrderTopBar();
|
|
|
|
// Overwrite `Panel._addToPanelBox` method with one handling new items
|
|
// and also handle AppIndicators getting ready, to handle new items.
|
|
this.#overwritePanelAddToPanelBox();
|
|
this._boxOrderManager.connect("appIndicatorReady", () => {
|
|
this.#handleNewItemsAndOrderTopBar();
|
|
});
|
|
|
|
// Handle changes of configured box orders.
|
|
this._settingsHandlerIds = [];
|
|
const addConfiguredBoxOrderChangeHandler = (box) => {
|
|
let handlerId = this.settings.connect(`changed::${box}-box-order`, () => {
|
|
this.#handleNewItemsAndOrderTopBar();
|
|
});
|
|
this._settingsHandlerIds.push(handlerId);
|
|
};
|
|
addConfiguredBoxOrderChangeHandler("left");
|
|
addConfiguredBoxOrderChangeHandler("center");
|
|
addConfiguredBoxOrderChangeHandler("right");
|
|
}
|
|
|
|
disable() {
|
|
// Revert the overwrite of `Panel._addToPanelBox`.
|
|
Panel.Panel.prototype._addToPanelBox = Panel.Panel.prototype._originalAddToPanelBox;
|
|
// Set `Panel._originalAddToPanelBox` to `undefined`.
|
|
Panel._originalAddToPanelBox = undefined;
|
|
|
|
// Disconnect signals.
|
|
for (const handlerId of this._settingsHandlerIds) {
|
|
this.settings.disconnect(handlerId);
|
|
}
|
|
this._boxOrderManager.disconnectSignals();
|
|
|
|
this.settings = null;
|
|
this._boxOrderManager = null;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
/// Methods used on extension enable. ///
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* Overwrite `Panel._addToPanelBox` with a custom method, which simply calls
|
|
* the original one and handles new items and orders the top bar afterwards.
|
|
*/
|
|
#overwritePanelAddToPanelBox() {
|
|
// Add the original `Panel._addToPanelBox` method as
|
|
// `Panel._originalAddToPanelBox`.
|
|
Panel.Panel.prototype._originalAddToPanelBox = Panel.Panel.prototype._addToPanelBox;
|
|
|
|
const handleNewItemsAndOrderTopBar = () => {
|
|
this.#handleNewItemsAndOrderTopBar();
|
|
};
|
|
|
|
// Overwrite `Panel._addToPanelBox`.
|
|
Panel.Panel.prototype._addToPanelBox = function(role, indicator, position, box) {
|
|
// Simply call the original `_addToPanelBox` and order the top bar
|
|
// and handle new items afterwards.
|
|
this._originalAddToPanelBox(role, indicator, position, box);
|
|
handleNewItemsAndOrderTopBar();
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
/// Helper methods holding logic needed by other methods. ///
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
/**
|
|
* This method orders the top bar items of the specified box according to
|
|
* the configured box orders.
|
|
* @param {string} box - The box to order.
|
|
*/
|
|
#orderTopBarItems(box) {
|
|
// Get the valid box order.
|
|
const validBoxOrder = this._boxOrderManager.createValidBoxOrder(box);
|
|
|
|
// Get the relevant box of `Main.panel`.
|
|
let panelBox;
|
|
switch (box) {
|
|
case "left":
|
|
panelBox = Main.panel._leftBox;
|
|
break;
|
|
case "center":
|
|
panelBox = Main.panel._centerBox;
|
|
break;
|
|
case "right":
|
|
panelBox = Main.panel._rightBox;
|
|
break;
|
|
}
|
|
|
|
/// Go through the items (or rather their roles) of the validBoxOrder
|
|
/// and order the panelBox accordingly.
|
|
for (let i = 0; i < validBoxOrder.length; i++) {
|
|
const role = validBoxOrder[i];
|
|
// Get the indicator container associated with the current role.
|
|
const associatedIndicatorContainer = Main.panel.statusArea[role].container;
|
|
|
|
associatedIndicatorContainer.get_parent().remove_child(associatedIndicatorContainer);
|
|
if (box === "right") {
|
|
// If the target panel box is the right panel box, insert the
|
|
// indicator container at index `-1`, which just adds it to the
|
|
// end (correct order is ensured, since `validBoxOrder` is
|
|
// sorted correctly and we're looping over it in order).
|
|
// This way unaccounted-for indicator containers will be at the
|
|
// left, which is preferred, since the box is logically
|
|
// right-to-left.
|
|
// The same applies for indicator containers, which are just
|
|
// temporarily unaccounted for (like for indicator containers of
|
|
// not yet ready app indicators), since them being at the right
|
|
// for a probably temporary stay causes all the indicator
|
|
// containers to shift.
|
|
panelBox.insert_child_at_index(associatedIndicatorContainer, -1);
|
|
} else {
|
|
panelBox.insert_child_at_index(associatedIndicatorContainer, i);
|
|
}
|
|
}
|
|
// To handle the case, where the box order got set to a permutation
|
|
// of an outdated box order, it would be wise, if the caller updated the
|
|
// box order now to include the items present in the top bar.
|
|
}
|
|
|
|
/**
|
|
* This method handles all new items currently present in the top bar and
|
|
* orders the items of all top bar boxes.
|
|
*/
|
|
#handleNewItemsAndOrderTopBar() {
|
|
this._boxOrderManager.saveNewTopBarItems();
|
|
this.#orderTopBarItems("left");
|
|
this.#orderTopBarItems("center");
|
|
this.#orderTopBarItems("right");
|
|
// In `this.#orderTopBarItems` it says to update the box orders to
|
|
// include potentially new items, since the ordering might have been
|
|
// based on an outdated box order. However, since we already handle new
|
|
// top bar items at the beginning of this method, this isn't a concern.
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
return new Extension();
|
|
}
|