diff --git a/README.md b/README.md index 2bede97..ffab986 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,16 @@ In particular this extension is a graphic interface for [envycontrol](https://gi journalctl -f -o cat /usr/bin/gnome-shell ``` -### For looking updates using wayland (it opens a new wayland session in a window) +### For debugging using wayland +- To show all messages: +``` +export G_MESSAGES_DEBUG=all +``` +- To set window size: +``` +export MUTTER_DEBUG_DUMMY_MODE_SPECS=1366X768 +``` +- To open a new wayland session in a window: ``` dbus-run-session -- gnome-shell --nested --wayland ``` @@ -60,6 +69,6 @@ gnome-extensions pack GPU_profile_selector@lorenzo9904.gmail.com \ ## TODO - In "AttachedToBatteryView" change the title by getting it directly from envycontrol. - Automatically install envycontrol tool during extension installation phase. -- Detect if envycontrol is not installed instead of prompting a restart in anycase. +- Detect if envycontrol is not installed instead of prompting a restart popup in anycase. - Add a setting for allowing user to choose where to place the extension view between topbar and menu panel. - Change the big V close the gpu profile with icon. diff --git a/extension.js b/extension.js index 2dc9787..3650044 100644 --- a/extension.js +++ b/extension.js @@ -1,41 +1,36 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js'; -import GLib from 'gi:://GLib'; -import St from 'gi://St'; -import GObject from 'gi://GObject'; -import Gio from 'gi://Gio'; -import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'; -import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; -import {Utility} from './lib/Utility.js'; -import {TopBarView} from './ui/TopBarView.js'; -import {AttachedToBatteryView} from './ui/AttachedToBatteryView.js'; +import * as Extension from 'resource:///org/gnome/shell/extensions/extension.js'; -import * as Util from 'resource:///org/gnome/shell/misc/util.js'; -import Clutter from 'gi://Clutter'; +import * as Utility from './lib/Utility.js'; +import * as TopBarView from './ui/TopBarView.js'; +import * as AttachedToBatteryView from './ui/AttachedToBatteryView.js'; -import * as Extension from 'resource:///org/gnome/shell/extensions/extension.js'; export default class GpuSelector extends Extension.Extension { enable() { - all_settings = this.getSettings('org.gnome.shell.extensions.GPU_profile_selector'); - // if there is no battery, there is no power management panel, so the extension moves to TopBar - if (Utility.isBatteryPlugged() && all_settings.get_boolean("force-topbar-view") !== true) { - this.extensionViewTopbar = false - this.extensionView = AttachedToBatteryView.getAttachedToBatteryView(all_settings); + let all_settings = this.getSettings('org.gnome.shell.extensions.GPU_profile_selector'); + // Deprecated: if there is no battery, there is no power management panel, so the extension moves to TopBar + // if (Utility.isBatteryPlugged() && all_settings.get_boolean("force-topbar-view") !== true) { + if (all_settings.get_boolean("force-topbar-view") !== true) { + // init the indicator object + this._indicator = new AttachedToBatteryView.AttachedToBatteryView(this); + // add the toggle items to indicator + this._indicator.quickSettingsItems.push(new AttachedToBatteryView.AttachedToBatteryToggle(this)); + // Add to status area in quicksettings panel + Main.panel.statusArea.quickSettings.addExternalIndicator(this._indicator); } else { - this.extensionViewTopbar = true - this.extensionView = new TopBarView.TopBarView(all_settings); - Main.panel.addToStatusArea("GPU_SELECTOR", this.extensionView, 1); - this.extensionView.enable(); + // init the indicator object + this._indicator = new TopBarView.TopBarView(this); + // Add to status area panel + Main.panel.addToStatusArea("GPU_SELECTOR", this._indicator, 1); } + // enable indicator + this._indicator.enable(); } disable() { - this.extensionView.disable(); - // also topbar popup must be destroyed - if (this.extensionViewTopbar !== null && this.extensionViewTopbar) { - this.extensionViewTopbar = null - this.extensionView.destroy(); - } - this.extensionView = null; + this._indicator.disable(); + this._indicator.destroy(); + this._indicator = null; } } diff --git a/lib/Utility.js b/lib/Utility.js index ecf073e..34b8c20 100644 --- a/lib/Utility.js +++ b/lib/Utility.js @@ -36,6 +36,7 @@ export function capitalizeFirstLetter(string) { return string.charAt(0).toUpperCase() + string.slice(1); } +// DEPRECATED: not usefull anymore export function isBatteryPlugged() { const directory = Gio.File.new_for_path('/sys/class/power_supply/'); // Synchronous, blocking method diff --git a/ui/AttachedToBatteryView.js b/ui/AttachedToBatteryView.js index 4ba333d..ac18ad4 100644 --- a/ui/AttachedToBatteryView.js +++ b/ui/AttachedToBatteryView.js @@ -1,41 +1,25 @@ import * as Main from 'resource:///org/gnome/shell/ui/main.js'; -import GLib from 'gi:://GLib'; -import St from 'gi://St'; import GObject from 'gi://GObject'; -import Gio from 'gi://Gio'; -import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'; import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; -import * as Util from 'resource:///org/gnome/shell/misc/util.js'; -import Clutter from 'gi://Clutter'; import * as QuickSettings from 'resource:///org/gnome/shell/ui/quickSettings.js'; -const QuickSettingsMenu = Main.panel.statusArea.quickSettings; - import * as Utility from '../lib/Utility.js'; -const ICON_SIZE = 6; -const AttachedToBatteryToggle = GObject.registerClass( +export const AttachedToBatteryToggle = GObject.registerClass( class AttachedToBatteryToggle extends QuickSettings.QuickMenuToggle { - constructor(all_settings) { - super(); - this.all_settings = all_settings; - } - - _init() { + _init(extensionObject) { super._init({ - label: Utility.capitalizeFirstLetter(Utility.getCurrentProfile()), - gicon : Gio.icon_new_for_string(Me.dir.get_path() + Utility.EXTENSION_ICON_FILE_NAME), title: Utility.capitalizeFirstLetter(Utility.getCurrentProfile()), - toggleMode: true, + iconName: 'selection-mode-symbolic', + toggleMode: false, // disable the possibility to click the button }); + this.all_settings = extensionObject.getSettings('org.gnome.shell.extensions.GPU_profile_selector'); - // This function is unique to this class. It adds a nice header with an - // icon, title and optional subtitle. It's recommended you do so for - // consistency with other menus. + // This function is unique to this class. It adds a nice header with an icon, title and optional subtitle. this.menu.setHeader('selection-mode-symbolic', Utility.capitalizeFirstLetter(Utility.getCurrentProfile()), 'Choose a GPU mode'); - // You may also add sections of items to the menu + // add a sections of items to the menu this._itemsSection = new PopupMenu.PopupMenuSection(); this._itemsSection.addAction('Nvidia', () => { Utility.switchNvidia(this.all_settings); @@ -57,30 +41,24 @@ class AttachedToBatteryToggle extends QuickSettings.QuickMenuToggle { // Add an entry-point for more settings this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); const settingsItem = this.menu.addAction('More Settings', - () => ExtensionUtils.openPrefs()); + () => extensionObject.openPreferences()); // Ensure the settings are unavailable when the screen is locked settingsItem.visible = Main.sessionMode.allowSettings; - this.menu._settingsActions[Extension.uuid] = settingsItem; + this.menu._settingsActions[extensionObject.uuid] = settingsItem; } }); -const AttachedToBatteryView = GObject.registerClass( +export const AttachedToBatteryView = GObject.registerClass( class AttachedToBatteryView extends QuickSettings.SystemIndicator { - _init(all_settings) { + _init(extensionObject) { super._init(); - // Create the icon for the indicator + } + + enable() { this._indicator = this._addIndicator(); - //this._indicator.gicon = Gio.icon_new_for_string(Me.dir.get_path() + Utility.ICON_SELECTOR_FILE_NAME); + this._indicator.icon_name = 'selection-mode-symbolic' //Gio.icon_new_for_string(Me.dir.get_path() + Utility.ICON_SELECTOR_FILE_NAME); this._indicator.visible = false; - - // Create the toggle and associate it with the indicator, being sure to - // destroy it along with the indicator - this.quickSettingsItems.push(new AttachedToBatteryToggle(all_settings)); - - // Add the indicator to the panel and the toggle to the menu - QuickSettingsMenu._indicators.add_child(this); - QuickSettingsMenu._addItems(this.quickSettingsItems); } disable() { @@ -89,7 +67,3 @@ class AttachedToBatteryView extends QuickSettings.SystemIndicator { super.destroy(); } }); - -export function getAttachedToBatteryView(all_settings) { - return new AttachedToBatteryView(all_settings); -} diff --git a/ui/TopBarView.js b/ui/TopBarView.js index c097890..9000c3c 100644 --- a/ui/TopBarView.js +++ b/ui/TopBarView.js @@ -1,37 +1,34 @@ -import * as Main from 'resource:///org/gnome/shell/ui/main.js'; -import GLib from 'gi:://GLib'; import St from 'gi://St'; import GObject from 'gi://GObject'; import Gio from 'gi://Gio'; import * as PanelMenu from 'resource:///org/gnome/shell/ui/panelMenu.js'; import * as PopupMenu from 'resource:///org/gnome/shell/ui/popupMenu.js'; -import * as Util from 'resource:///org/gnome/shell/misc/util.js'; -import Clutter from 'gi://Clutter'; import * as Utility from '../lib/Utility.js'; + const ICON_SIZE = 6; const ICON_INTEL_FILE_NAME = '/img/intel_icon_plain.svg'; const ICON_NVIDIA_FILE_NAME = '/img/nvidia_icon_plain.svg'; const ICON_HYBRID_FILE_NAME = '/img/hybrid_icon_plain.svg'; -const TopBarView = GObject.registerClass( +export const TopBarView = GObject.registerClass( class TopBarView extends PanelMenu.Button { - _init(all_settings) { + _init(extensionObject) { super._init(0); - // Load settings - this._all_settings = all_settings; + this._all_settings = extensionObject.getSettings('org.gnome.shell.extensions.GPU_profile_selector'); + this._extension_path = extensionObject.path; } enable() { this.icon_selector = new St.Icon({ - gicon : Gio.icon_new_for_string(Me.dir.get_path() + Utility.EXTENSION_ICON_FILE_NAME), + gicon : Gio.icon_new_for_string(this._extension_path + Utility.EXTENSION_ICON_FILE_NAME), style_class : 'system-status-icon', icon_size: ICON_SIZE }); - // init integrated GPU profile menu item and its click listener + // init integrated GPU profile menu item and its click listeners this.integrated_menu_item = new PopupMenu.PopupMenuItem('Integrated'); this.integrated_menu_item_id = this.integrated_menu_item.connect('activate', () => { // view stuff @@ -40,7 +37,7 @@ class TopBarView extends PanelMenu.Button { this.integrated_menu_item.add_child(this.icon_selector); this.remove_child(this.icon_top); this.icon_top = new St.Icon({ - gicon : Gio.icon_new_for_string(Me.dir.get_path() + ICON_INTEL_FILE_NAME), + gicon : Gio.icon_new_for_string(this._extension_path + ICON_INTEL_FILE_NAME), style_class: 'system-status-icon', }); this.add_child(this.icon_top); @@ -48,7 +45,7 @@ class TopBarView extends PanelMenu.Button { Utility.switchIntegrated(); }); - // init hybrid GPU profile menu item and its click listener + // init hybrid GPU profile menu item and its click listeners this.hybrid_menu_item = new PopupMenu.PopupMenuItem('Hybrid'); this.hybrid_menu_item_id = this.hybrid_menu_item.connect('activate', () => { // view stuff @@ -57,7 +54,7 @@ class TopBarView extends PanelMenu.Button { this.hybrid_menu_item.add_child(this.icon_selector); this.remove_child(this.icon_top); this.icon_top = new St.Icon({ - gicon : Gio.icon_new_for_string(Me.dir.get_path() + ICON_HYBRID_FILE_NAME), + gicon : Gio.icon_new_for_string(this._extension_path + ICON_HYBRID_FILE_NAME), style_class: 'system-status-icon', }); this.add_child(this.icon_top); @@ -65,7 +62,7 @@ class TopBarView extends PanelMenu.Button { Utility.switchHybrid(this._all_settings); }); - // init nvidia GPU profile menu item and its click listener + // init nvidia GPU profile menu item and its click listeners this.nvidia_menu_item = new PopupMenu.PopupMenuItem('Nvidia'); this.nvidia_menu_item_id = this.nvidia_menu_item.connect('activate', () => { // view stuff @@ -74,7 +71,7 @@ class TopBarView extends PanelMenu.Button { this.nvidia_menu_item.add_child(this.icon_selector); this.remove_child(this.icon_top); this.icon_top = new St.Icon({ - gicon : Gio.icon_new_for_string(Me.dir.get_path() + ICON_NVIDIA_FILE_NAME), + gicon : Gio.icon_new_for_string(this._extension_path + ICON_NVIDIA_FILE_NAME), style_class: 'system-status-icon', }); this.add_child(this.icon_top); @@ -96,7 +93,7 @@ class TopBarView extends PanelMenu.Button { this.nvidia_menu_item.remove_child(this.icon_selector); this.integrated_menu_item.add_child(this.icon_selector); this.icon_top = new St.Icon({ - gicon : Gio.icon_new_for_string(Me.dir.get_path() + ICON_INTEL_FILE_NAME), + gicon : Gio.icon_new_for_string(this._extension_path + ICON_INTEL_FILE_NAME), style_class: 'system-status-icon', }); } else if(gpu_profile === Utility.GPU_PROFILE_HYBRID) { @@ -104,7 +101,7 @@ class TopBarView extends PanelMenu.Button { this.nvidia_menu_item.remove_child(this.icon_selector); this.hybrid_menu_item.add_child(this.icon_selector); this.icon_top = new St.Icon({ - gicon : Gio.icon_new_for_string(Me.dir.get_path() + ICON_HYBRID_FILE_NAME), + gicon : Gio.icon_new_for_string(this._extension_path + ICON_HYBRID_FILE_NAME), style_class: 'system-status-icon', }); } else { @@ -112,7 +109,7 @@ class TopBarView extends PanelMenu.Button { this.hybrid_menu_item.remove_child(this.icon_selector); this.nvidia_menu_item.add_child(this.icon_selector); this.icon_top = new St.Icon({ - gicon : Gio.icon_new_for_string(Me.dir.get_path() + ICON_NVIDIA_FILE_NAME), + gicon : Gio.icon_new_for_string(this._extension_path + ICON_NVIDIA_FILE_NAME), style_class: 'system-status-icon', }); }