diff --git a/src/extension.js b/src/extension.js index 205f938..45bc08e 100644 --- a/src/extension.js +++ b/src/extension.js @@ -20,20 +20,21 @@ "use strict"; const ExtensionUtils = imports.misc.extensionUtils; +const Me = ExtensionUtils.getCurrentExtension(); const Main = imports.ui.main; const Panel = imports.ui.panel; +const AppIndicatorKStatusNotifierItemManager = Me.imports.extensionModules.AppIndicatorKStatusNotifierItemManager; + class Extension { constructor() { this.settings = ExtensionUtils.getSettings(); } enable() { - // Create an application-role map for associating roles with - // applications. - // This is needed to handle AppIndicator/KStatusNotifierItem items. - this._applicationRoleMap = new Map(); + // Create an instance of AppIndicatorKStatusNotifierItemManager to handle AppIndicator/KStatusNotifierItem items. + this._appIndicatorKStatusNotifierItemManager = new AppIndicatorKStatusNotifierItemManager.AppIndicatorKStatusNotifierItemManager(); this._addNewItemsToBoxOrders(); this._orderTopBarItemsOfAllBoxes(); @@ -146,17 +147,17 @@ class Extension { switch (box) { case "left": boxOrder = this.settings.get_strv("left-box-order"); - this._handleAppIndicatorKStatusNotifierItemItem(indicator.container, role, boxOrder, boxOrders); + this._appIndicatorKStatusNotifierItemManager.handleAppIndicatorKStatusNotifierItemItem(indicator.container, role, boxOrder, boxOrders); this.settings.set_strv("left-box-order", boxOrder); break; case "center": boxOrder = this.settings.get_strv("center-box-order"); - this._handleAppIndicatorKStatusNotifierItemItem(indicator.container, role, boxOrder, boxOrders); + this._appIndicatorKStatusNotifierItemManager.handleAppIndicatorKStatusNotifierItemItem(indicator.container, role, boxOrder, boxOrders); this.settings.set_strv("center-box-order", boxOrder); break; case "right": boxOrder = this.settings.get_strv("right-box-order"); - this._handleAppIndicatorKStatusNotifierItemItem(indicator.container, role, boxOrder, boxOrders, true); + this._appIndicatorKStatusNotifierItemManager.handleAppIndicatorKStatusNotifierItemItem(indicator.container, role, boxOrder, boxOrders, true); this.settings.set_strv("right-box-order", boxOrder); break; } @@ -164,9 +165,9 @@ class Extension { // Get the resolved box orders for all boxes. const resolvedBoxOrders = { - left: this._createResolvedBoxOrder("left"), - center: this._createResolvedBoxOrder("center"), - right: this._createResolvedBoxOrder("right"), + left: this._appIndicatorKStatusNotifierItemManager.createResolvedBoxOrder(this.settings.get_strv("left-box-order")), + center: this._appIndicatorKStatusNotifierItemManager.createResolvedBoxOrder(this.settings.get_strv("center-box-order")), + right: this._appIndicatorKStatusNotifierItemManager.createResolvedBoxOrder(this.settings.get_strv("right-box-order")), }; // Also get the restricted valid box order of the target box. const restrictedValidBoxOrderOfTargetBox = this._createRestrictedValidBoxOrder(box); @@ -346,7 +347,7 @@ class Extension { // Handle an AppIndicator/KStatusNotifierItem item differently. if (associatedRole.startsWith("appindicator-")) { - this._handleAppIndicatorKStatusNotifierItemItem(indicatorContainer, associatedRole, boxOrder, boxOrders, box === "right"); + this._appIndicatorKStatusNotifierItemManager.handleAppIndicatorKStatusNotifierItemItem(indicatorContainer, associatedRole, boxOrder, boxOrders, box === "right"); continue; } @@ -386,7 +387,7 @@ class Extension { */ _createValidBoxOrder(box) { // Get a resolved box order. - let boxOrder = this._createResolvedBoxOrder(box); + let boxOrder = this._appIndicatorKStatusNotifierItemManager.createResolvedBoxOrder(this.settings.get_strv(`${box}-box-order`)); // Get the indicator containers (of the items) currently present in the // Gnome Shell top bar. @@ -436,7 +437,7 @@ class Extension { // Get a resolved box order and get the indicator containers (of the // items) which are currently present in the Gnome Shell top bar in the // specified box. - let boxOrder = this._createResolvedBoxOrder(box); + let boxOrder = this._appIndicatorKStatusNotifierItemManager.createResolvedBoxOrder(this.settings.get_strv(`${box}-box-order`)); let boxIndicatorContainers; switch (box) { case "left": @@ -532,95 +533,6 @@ class Extension { // 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. } - - /** - * Handle an AppIndicator/KStatusNotifierItem item. - * - * This function basically does the following two things: - * - Associate the role of the given item with the application of the - * AppIndicator/KStatusNotifierItem. - * - Add a placeholder for the roles associated with the application of the - * AppIndiciator/KStatusNotifierItem to the box order, if needed. - * - * Note: The caller is responsible for saving the updated box order to - * settings. - * @param {} indicatorContainer - The container of the indicator of the - * AppIndicator/KStatusNotifierItem item. - * @param {string} role - The role of the AppIndicator/KStatusNotifierItem - * item. - * @param {string[]} - The box order the placeholder should be added to, if - * needed. - * @param {BoxOrders} boxOrders - An object containing the box orders, which - * is currently getting worked on. - * @param {boolean} - Whether to add the placeholder to the beginning of the - * box order. - */ - _handleAppIndicatorKStatusNotifierItemItem(indicatorContainer, role, boxOrder, boxOrders, atToBeginning = false) { - // Get the application the AppIndicator/KStatusNotifierItem is - // associated with. - const application = indicatorContainer.get_child()._indicator.id; - - // Associate the role with the application. - let roles = this._applicationRoleMap.get(application); - if (roles) { - // If the application already has an array of associated roles, just - // add the role to it, if needed. - if (!roles.includes(role)) roles.push(role); - } else { - // Otherwise create a new array. - this._applicationRoleMap.set(application, [ role ]); - } - - // Store a placeholder for the roles associated with the application in - // the box order, if needed. - // (Then later the placeholder can be replaced with the relevant roles - // using `this._applicationRoleMap`.) - const placeholder = `appindicator-kstatusnotifieritem-${application}`; - if (!boxOrders.left.includes(placeholder) - && !boxOrders.center.includes(placeholder) - && !boxOrders.right.includes(placeholder)) { - if (atToBeginning) { - boxOrder.unshift(placeholder); - } else { - boxOrder.push(placeholder); - } - } - } - - /** - * This function returns a box order for the specified box, where the - * placeholders are replaced with the relevant roles. - * @param {string} box - The box of which to get the resolved box order. - */ - _createResolvedBoxOrder(box) { - const boxOrder = this.settings.get_strv(`${box}-box-order`); - - let resolvedBoxOrder = [ ]; - for (const item of boxOrder) { - // If the item isn't a placeholder, just add it to the new resolved - // box order. - if (!item.startsWith("appindicator-kstatusnotifieritem-")) { - resolvedBoxOrder.push(item); - continue; - } - - /// If the item is a placeholder, replace it. - // First get the application this placeholder is associated with. - const application = item.replace("appindicator-kstatusnotifieritem-", ""); - - // Then get the roles associated with the application. - let roles = this._applicationRoleMap.get(application); - - // Continue, if there are no roles. - if (!roles) continue; - // Otherwise add the roles - for (const role of roles) { - resolvedBoxOrder.push(role); - } - } - - return resolvedBoxOrder; - } } function init() { diff --git a/src/extensionModules/AppIndicatorKStatusNotifierItemManager.js b/src/extensionModules/AppIndicatorKStatusNotifierItemManager.js new file mode 100644 index 0000000..e4c3e85 --- /dev/null +++ b/src/extensionModules/AppIndicatorKStatusNotifierItemManager.js @@ -0,0 +1,121 @@ +/* + * This file is part of Top-Bar-Organizer (a Gnome Shell Extension for + * organizing your Gnome Shell top bar). + * Copyright (C) 2021 Julian Schacher + * + * Top-Bar-Organizer is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +/* exported AppIndicatorKStatusNotifierItemManager */ +"use strict"; + +var AppIndicatorKStatusNotifierItemManager = class AppIndicatorKStatusNotifierItemManager { + constructor() { + // Create an application-role map for associating roles with + // applications. + // This is needed so that this class can handle/manage + // AppIndicator/KStatusNotifierItem items. + this._applicationRoleMap = new Map(); + } + + /** + * Handle an AppIndicator/KStatusNotifierItem item. + * + * This function basically does the following two things: + * - Associate the role of the given item with the application of the + * AppIndicator/KStatusNotifierItem. + * - Add a placeholder for the roles associated with the application of the + * AppIndiciator/KStatusNotifierItem to the box order, if needed. + * + * Note: The caller is responsible for saving the updated box order to + * settings. + * @param {} indicatorContainer - The container of the indicator of the + * AppIndicator/KStatusNotifierItem item. + * @param {string} role - The role of the AppIndicator/KStatusNotifierItem + * item. + * @param {string[]} - The box order the placeholder should be added to, if + * needed. + * @param {BoxOrders} boxOrders - An object containing the box orders, which + * is currently getting worked on. + * @param {boolean} - Whether to add the placeholder to the beginning of the + * box order. + */ + handleAppIndicatorKStatusNotifierItemItem(indicatorContainer, role, boxOrder, boxOrders, atToBeginning = false) { + // Get the application the AppIndicator/KStatusNotifierItem is + // associated with. + const application = indicatorContainer.get_child()._indicator.id; + + // Associate the role with the application. + let roles = this._applicationRoleMap.get(application); + if (roles) { + // If the application already has an array of associated roles, just + // add the role to it, if needed. + if (!roles.includes(role)) roles.push(role); + } else { + // Otherwise create a new array. + this._applicationRoleMap.set(application, [ role ]); + } + + // Store a placeholder for the roles associated with the application in + // the box order, if needed. + // (Then later the `this.createResolvedBoxOrder` method can be used to + // get a box order, where the placeholder/s get/s replaced with the + // relevant roles (by using `this._applicationRoleMap`).) + const placeholder = `appindicator-kstatusnotifieritem-${application}`; + if (!boxOrders.left.includes(placeholder) + && !boxOrders.center.includes(placeholder) + && !boxOrders.right.includes(placeholder)) { + if (atToBeginning) { + boxOrder.unshift(placeholder); + } else { + boxOrder.push(placeholder); + } + } + } + + /** + * This function takes a box order and returns a box order, where all + * placeholders got replaced with their relevant roles. + * @param {string[]} boxOrder - The box order of which to replace the + * placeholders. + * @returns {string[]} A resolved box order, where all placeholders got + * replaced with their relevant roles. + */ + createResolvedBoxOrder(boxOrder) { + let resolvedBoxOrder = [ ]; + for (const item of boxOrder) { + // If the item isn't a placeholder, just add it to the new resolved + // box order. + if (!item.startsWith("appindicator-kstatusnotifieritem-")) { + resolvedBoxOrder.push(item); + continue; + } + + /// If the item is a placeholder, replace it. + // First get the application this placeholder is associated with. + const application = item.replace("appindicator-kstatusnotifieritem-", ""); + + // Then get the roles associated with the application. + let roles = this._applicationRoleMap.get(application); + + // Continue, if there are no roles. + if (!roles) continue; + // Otherwise add the roles + for (const role of roles) { + resolvedBoxOrder.push(role); + } + } + + return resolvedBoxOrder; + } +};