Breaking: Migrate extension to the new ESM system of GNOME 45

Migrate with the help of, among others, the following resources:
https://blogs.gnome.org/shell-dev/2023/09/02/extensions-in-gnome-45/
https://gjs.guide/extensions/upgrading/gnome-shell-45.html

Only support GNOME Shell version 45, since only 45 is compatible with
the new ESM system.

Since panel._originalAddToPanelBox is no longer valid, just overwrite
using the prototype on disable.

Add "sourceType": "module" to eslintrc.yml to get rid of:
"Parsing error: 'import' and 'export' may appear only with 'sourceType:
module'"
See here:
https://eslint.org/docs/latest/use/configure/language-options#specifying-parser-options
This commit is contained in:
Julian 2023-10-02 03:56:48 +02:00
parent 62e9609b2d
commit a1188d5684
Signed by: julian
GPG Key ID: 094C2AC34192FA11
10 changed files with 85 additions and 102 deletions

View File

@ -3,6 +3,7 @@ env:
extends: 'eslint:recommended' extends: 'eslint:recommended'
parserOptions: parserOptions:
ecmaVersion: 2022 ecmaVersion: 2022
sourceType: module
rules: rules:
indent: indent:
- error - error
@ -49,5 +50,4 @@ rules:
- error - error
- always - always
globals: globals:
imports: readonly
log: readonly log: readonly

View File

@ -1,22 +1,16 @@
"use strict"; "use strict";
/* exported init */
const ExtensionUtils = imports.misc.extensionUtils; import * as Main from "resource:///org/gnome/shell/ui/main.js";
const Me = ExtensionUtils.getCurrentExtension(); import * as Panel from "resource:///org/gnome/shell/ui/panel.js";
import { Extension } from "resource:///org/gnome/shell/extensions/extension.js";
const Main = imports.ui.main; import BoxOrderManager from "./extensionModules/BoxOrderManager.js";
const Panel = imports.ui.panel;
const BoxOrderManager = Me.imports.extensionModules.BoxOrderManager;
class Extension {
constructor() {
}
export default class TopBarOrganizerExtension extends Extension {
enable() { enable() {
this._settings = ExtensionUtils.getSettings(); this._settings = this.getSettings();
this._boxOrderManager = new BoxOrderManager.BoxOrderManager(); this._boxOrderManager = new BoxOrderManager({}, this._settings);
/// Stuff to do on startup(extension enable). /// Stuff to do on startup(extension enable).
// Initially handle new top bar items and order top bar boxes. // Initially handle new top bar items and order top bar boxes.
@ -46,7 +40,7 @@ class Extension {
// Revert the overwrite of `Panel._addToPanelBox`. // Revert the overwrite of `Panel._addToPanelBox`.
Panel.Panel.prototype._addToPanelBox = Panel.Panel.prototype._originalAddToPanelBox; Panel.Panel.prototype._addToPanelBox = Panel.Panel.prototype._originalAddToPanelBox;
// Set `Panel._originalAddToPanelBox` to `undefined`. // Set `Panel._originalAddToPanelBox` to `undefined`.
Panel._originalAddToPanelBox = undefined; Panel.Panel.prototype._originalAddToPanelBox = undefined;
// Disconnect signals. // Disconnect signals.
for (const handlerId of this._settingsHandlerIds) { for (const handlerId of this._settingsHandlerIds) {
@ -177,7 +171,3 @@ class Extension {
// top bar items at the beginning of this method, this isn't a concern. // top bar items at the beginning of this method, this isn't a concern.
} }
} }
function init() {
return new Extension();
}

View File

@ -1,11 +1,8 @@
"use strict"; "use strict";
/* exported BoxOrderManager */
const GObject = imports.gi.GObject; import GObject from "gi://GObject";
const ExtensionUtils = imports.misc.extensionUtils; import * as Main from "resource:///org/gnome/shell/ui/main.js";
const Main = imports.ui.main;
/** /**
* This class provides methods get, set and interact with box orders, while * This class provides methods get, set and interact with box orders, while
@ -13,7 +10,7 @@ const Main = imports.ui.main;
* what is really useable by the other extension code. * what is really useable by the other extension code.
* It's basically a heavy wrapper around the box orders stored in the settings. * It's basically a heavy wrapper around the box orders stored in the settings.
*/ */
var BoxOrderManager = GObject.registerClass({ const BoxOrderManager = GObject.registerClass({
Signals: { Signals: {
"appIndicatorReady": {} "appIndicatorReady": {}
} }
@ -22,13 +19,13 @@ var BoxOrderManager = GObject.registerClass({
#appIndicatorItemApplicationRoleMap; #appIndicatorItemApplicationRoleMap;
#settings; #settings;
constructor(params = {}) { constructor(params = {}, settings) {
super(params); super(params);
this.#appIndicatorReadyHandlerIdMap = new Map(); this.#appIndicatorReadyHandlerIdMap = new Map();
this.#appIndicatorItemApplicationRoleMap = new Map(); this.#appIndicatorItemApplicationRoleMap = new Map();
this.#settings = ExtensionUtils.getSettings(); this.#settings = settings;
} }
/** /**
@ -271,3 +268,5 @@ var BoxOrderManager = GObject.registerClass({
saveBoxOrderToSettings(boxOrders.right, "right"); saveBoxOrderToSettings(boxOrders.right, "right");
} }
}); });
export default BoxOrderManager;

View File

@ -3,7 +3,7 @@
"name": "Top Bar Organizer", "name": "Top Bar Organizer",
"description": "Organize the items of the top (menu)bar.", "description": "Organize the items of the top (menu)bar.",
"version": 9, "version": 9,
"shell-version": [ "42", "43", "44" ], "shell-version": [ "45" ],
"settings-schema": "org.gnome.shell.extensions.top-bar-organizer", "settings-schema": "org.gnome.shell.extensions.top-bar-organizer",
"url": "https://gitlab.gnome.org/julianschacher/top-bar-organizer" "url": "https://gitlab.gnome.org/julianschacher/top-bar-organizer"
} }

View File

@ -1,35 +1,32 @@
"use strict"; "use strict";
/* exported buildPrefsWidget, init */
const Gtk = imports.gi.Gtk; import Gtk from "gi://Gtk";
const Gdk = imports.gi.Gdk; import Gdk from "gi://Gdk";
const ExtensionUtils = imports.misc.extensionUtils; import { ExtensionPreferences } from "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js";
const Me = ExtensionUtils.getCurrentExtension();
const PrefsPage = Me.imports.prefsModules.PrefsPage; import PrefsPage from "./prefsModules/PrefsPage.js";
function buildPrefsWidget() { export default class TopBarOrganizerPreferences extends ExtensionPreferences {
const provider = new Gtk.CssProvider(); getPreferencesWidget() {
provider.load_from_path(Me.dir.get_path() + "/css/prefs.css"); const provider = new Gtk.CssProvider();
const defaultGdkDisplay = Gdk.Display.get_default(); provider.load_from_path(this.metadata.dir.get_path() + "/css/prefs.css");
Gtk.StyleContext.add_provider_for_display( const defaultGdkDisplay = Gdk.Display.get_default();
defaultGdkDisplay, Gtk.StyleContext.add_provider_for_display(
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
const prefsPage = new PrefsPage.PrefsPage();
prefsPage.connect("destroy", () => {
Gtk.StyleContext.remove_provider_for_display(
defaultGdkDisplay, defaultGdkDisplay,
provider provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
); );
});
return prefsPage; const prefsPage = new PrefsPage();
}
function init() { prefsPage.connect("destroy", () => {
Gtk.StyleContext.remove_provider_for_display(
defaultGdkDisplay,
provider
);
});
return prefsPage;
}
} }

View File

@ -1,18 +1,15 @@
"use strict"; "use strict";
/* exported PrefsBoxOrderItemRow */
const Gtk = imports.gi.Gtk; import Gtk from "gi://Gtk";
const Gdk = imports.gi.Gdk; import Gdk from "gi://Gdk";
const Gio = imports.gi.Gio; import Gio from "gi://Gio";
const GObject = imports.gi.GObject; import GObject from "gi://GObject";
const Adw = imports.gi.Adw; import Adw from "gi://Adw";
import GLib from "gi://GLib";
const ExtensionUtils = imports.misc.extensionUtils; const PrefsBoxOrderItemRow = GObject.registerClass({
const Me = ExtensionUtils.getCurrentExtension();
var PrefsBoxOrderItemRow = GObject.registerClass({
GTypeName: "PrefsBoxOrderItemRow", GTypeName: "PrefsBoxOrderItemRow",
Template: Me.dir.get_child("ui").get_child("prefs-box-order-item-row.ui").get_uri(), Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-box-order-item-row.ui", GLib.UriFlags.NONE),
InternalChildren: [ InternalChildren: [
"item-name-display-label" "item-name-display-label"
] ]
@ -144,3 +141,5 @@ var PrefsBoxOrderItemRow = GObject.registerClass({
} }
} }
}); });
export default PrefsBoxOrderItemRow;

View File

@ -1,18 +1,17 @@
"use strict"; "use strict";
/* exported PrefsBoxOrderListBox */
const Gtk = imports.gi.Gtk; import Gtk from "gi://Gtk";
const GObject = imports.gi.GObject; import GObject from "gi://GObject";
import GLib from "gi://GLib";
const ExtensionUtils = imports.misc.extensionUtils; import { ExtensionPreferences } from "resource:///org/gnome/Shell/Extensions/js/extensions/prefs.js";
const Me = ExtensionUtils.getCurrentExtension();
const PrefsBoxOrderItemRow = Me.imports.prefsModules.PrefsBoxOrderItemRow; import PrefsBoxOrderItemRow from "./PrefsBoxOrderItemRow.js";
const PrefsBoxOrderListEmptyPlaceholder = Me.imports.prefsModules.PrefsBoxOrderListEmptyPlaceholder; import PrefsBoxOrderListEmptyPlaceholder from "./PrefsBoxOrderListEmptyPlaceholder.js";
var PrefsBoxOrderListBox = GObject.registerClass({ const PrefsBoxOrderListBox = GObject.registerClass({
GTypeName: "PrefsBoxOrderListBox", GTypeName: "PrefsBoxOrderListBox",
Template: Me.dir.get_child("ui").get_child("prefs-box-order-list-box.ui").get_uri(), Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-box-order-list-box.ui", GLib.UriFlags.NONE),
Properties: { Properties: {
BoxOrder: GObject.ParamSpec.string( BoxOrder: GObject.ParamSpec.string(
"box-order", "box-order",
@ -32,11 +31,11 @@ var PrefsBoxOrderListBox = GObject.registerClass({
super(params); super(params);
// Load the settings. // Load the settings.
this.#settings = ExtensionUtils.getSettings(); this.#settings = ExtensionPreferences.lookupByURL(import.meta.url).getSettings();
// Add a placeholder widget for the case, where no GtkListBoxRows are // Add a placeholder widget for the case, where no GtkListBoxRows are
// present. // present.
this.set_placeholder(new PrefsBoxOrderListEmptyPlaceholder.PrefsBoxOrderListEmptyPlaceholder()); this.set_placeholder(new PrefsBoxOrderListEmptyPlaceholder());
} }
get boxOrder() { get boxOrder() {
@ -48,13 +47,13 @@ var PrefsBoxOrderListBox = GObject.registerClass({
// Load the settings here as well, since a `CONSTRUCT_ONLY` property // Load the settings here as well, since a `CONSTRUCT_ONLY` property
// apparently can't access `this.#settings`. // apparently can't access `this.#settings`.
const settings = ExtensionUtils.getSettings(); const settings = ExtensionPreferences.lookupByURL(import.meta.url).getSettings();
// Get the actual box order for the given box order name from settings. // Get the actual box order for the given box order name from settings.
const boxOrder = settings.get_strv(this._boxOrder); const boxOrder = settings.get_strv(this._boxOrder);
// Populate this GtkListBox with GtkListBoxRows for the items of the // Populate this GtkListBox with GtkListBoxRows for the items of the
// given configured box order. // given configured box order.
for (const item of boxOrder) { for (const item of boxOrder) {
const listBoxRow = new PrefsBoxOrderItemRow.PrefsBoxOrderItemRow({}, item); const listBoxRow = new PrefsBoxOrderItemRow({}, item);
this.append(listBoxRow); this.append(listBoxRow);
} }
@ -79,3 +78,5 @@ var PrefsBoxOrderListBox = GObject.registerClass({
this.#settings.set_strv(this.boxOrder, currentBoxOrder); this.#settings.set_strv(this.boxOrder, currentBoxOrder);
} }
}); });
export default PrefsBoxOrderListBox;

View File

@ -1,15 +1,12 @@
"use strict"; "use strict";
/* exported PrefsBoxOrderListEmptyPlaceholder */
const Gtk = imports.gi.Gtk; import Gtk from "gi://Gtk";
const GObject = imports.gi.GObject; import GObject from "gi://GObject";
import GLib from "gi://GLib";
const ExtensionUtils = imports.misc.extensionUtils; const PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({
const Me = ExtensionUtils.getCurrentExtension();
var PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({
GTypeName: "PrefsBoxOrderListEmptyPlaceholder", GTypeName: "PrefsBoxOrderListEmptyPlaceholder",
Template: Me.dir.get_child("ui").get_child("prefs-box-order-list-empty-placeholder.ui").get_uri() Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-box-order-list-empty-placeholder.ui", GLib.UriFlags.NONE)
}, class PrefsBoxOrderListEmptyPlaceholder extends Gtk.Box { }, class PrefsBoxOrderListEmptyPlaceholder extends Gtk.Box {
// Handle a new drop on `this` properly. // Handle a new drop on `this` properly.
// `value` is the thing getting dropped. // `value` is the thing getting dropped.
@ -29,3 +26,5 @@ var PrefsBoxOrderListEmptyPlaceholder = GObject.registerClass({
valueListBox.saveBoxOrderToSettings(); valueListBox.saveBoxOrderToSettings();
} }
}); });
export default PrefsBoxOrderListEmptyPlaceholder;

View File

@ -1,22 +1,18 @@
"use strict"; "use strict";
/* exported PrefsPage */
const Gtk = imports.gi.Gtk; import Gtk from "gi://Gtk";
const GObject = imports.gi.GObject; import GObject from "gi://GObject";
const Adw = imports.gi.Adw; import Adw from "gi://Adw";
import GLib from "gi://GLib";
const ExtensionUtils = imports.misc.extensionUtils; import ScrollManager from "./ScrollManager.js";
const Me = ExtensionUtils.getCurrentExtension();
const ScrollManager = Me.imports.prefsModules.ScrollManager;
// Imports to make UI file work. // Imports to make UI file work.
/* exported PrefsBoxOrderListBox */ import PrefsBoxOrderListBox from "./PrefsBoxOrderListBox.js";
const PrefsBoxOrderListBox = Me.imports.prefsModules.PrefsBoxOrderListBox;
var PrefsPage = GObject.registerClass({ const PrefsPage = GObject.registerClass({
GTypeName: "PrefsPage", GTypeName: "PrefsPage",
Template: Me.dir.get_child("ui").get_child("prefs-page.ui").get_uri() Template: GLib.uri_resolve_relative(import.meta.url, "../ui/prefs-page.ui", GLib.UriFlags.NONE)
}, class PrefsPage extends Adw.PreferencesPage { }, class PrefsPage extends Adw.PreferencesPage {
constructor(params = {}) { constructor(params = {}) {
super(params); super(params);
@ -34,7 +30,7 @@ var PrefsPage = GObject.registerClass({
// Pass `this.get_first_child()` to the ScrollManager, since this // Pass `this.get_first_child()` to the ScrollManager, since this
// `PrefsPage` extends an `Adw.PreferencesPage` and the first child of // `PrefsPage` extends an `Adw.PreferencesPage` and the first child of
// an `Adw.PreferencesPage` is the built-in `Gtk.ScrolledWindow`. // an `Adw.PreferencesPage` is the built-in `Gtk.ScrolledWindow`.
const scrollManager = new ScrollManager.ScrollManager(this.get_first_child()); const scrollManager = new ScrollManager(this.get_first_child());
/// Setup GtkDropControllerMotion event controller and make use of its /// Setup GtkDropControllerMotion event controller and make use of its
/// events. /// events.
@ -86,3 +82,5 @@ var PrefsPage = GObject.registerClass({
this.add_controller(controller); this.add_controller(controller);
} }
}); });
export default PrefsPage;

View File

@ -1,8 +1,8 @@
"use strict"; "use strict";
/* exported ScrollManager */
const GLib = imports.gi.GLib;
var ScrollManager = class ScrollManager { import GLib from "gi://GLib";
export default class ScrollManager {
#gtkScrolledWindow; #gtkScrolledWindow;
#scrollUp; #scrollUp;
#scrollDown; #scrollDown;
@ -86,4 +86,4 @@ var ScrollManager = class ScrollManager {
this.stopScrollUp(); this.stopScrollUp();
this.stopScrollDown(); this.stopScrollDown();
} }
}; }