extensions: Turn extensions into modules

As gnome-shell is moving to ESM, it will now load extensions as
standard modules instead of using legacy imports. The change boils
down to exporting the Extension class as default, but we can also
start using standard imports for introspected modules now, so do
that at the same time.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/259>
This commit is contained in:
Florian Müllner
2023-06-02 12:45:30 +02:00
parent 701b14ecbf
commit cf007dd472
21 changed files with 149 additions and 184 deletions
+11 -11
View File
@@ -1,9 +1,14 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
/* exported init enable disable */
const {
Atk, Clutter, Gio, GLib, GMenu, GObject, Gtk, Meta, Shell, St,
} = imports.gi;
import Atk from 'gi://Atk';
import Clutter from 'gi://Clutter';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GMenu from 'gi://GMenu';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk';
import Meta from 'gi://Meta';
import Shell from 'gi://Shell';
import St from 'gi://St';
const {EventEmitter} = imports.misc.signals;
const DND = imports.ui.dnd;
@@ -677,7 +682,7 @@ class ApplicationsButton extends PanelMenu.Button {
}
}
class Extension {
export default class Extension {
constructor() {
ExtensionUtils.initTranslations();
}
@@ -695,8 +700,3 @@ class Extension {
delete this._appsMenuButton;
}
}
/** */
function init() {
return new Extension();
}
+2 -8
View File
@@ -1,8 +1,7 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
// Start apps on custom workspaces
/* exported init enable disable */
const {Shell} = imports.gi;
import Shell from 'gi://Shell';
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
@@ -105,7 +104,7 @@ class WindowMover {
}
}
class Extension {
export default class Extension {
enable() {
this._prevCheckWorkspaces = Main.wm._workspaceTracker._checkWorkspaces;
Main.wm._workspaceTracker._checkWorkspaces =
@@ -143,8 +142,3 @@ class Extension {
/* eslint-enable no-invalid-this */
}
}
/** */
function init() {
return new Extension();
}
+16 -11
View File
@@ -1,8 +1,11 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
// Start apps on custom workspaces
/* exported init buildPrefsWidget */
const {Adw, Gio, GLib, GObject, Gtk} = imports.gi;
import Adw from 'gi://Adw';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk';
const ExtensionUtils = imports.misc.extensionUtils;
@@ -338,14 +341,16 @@ class NewRuleDialog extends Gtk.AppChooserDialog {
}
}
/** */
function init() {
ExtensionUtils.initTranslations();
}
export default class ExtensionPreferences {
constructor() {
ExtensionUtils.initTranslations();
}
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() {
return new AutoMoveSettingsWidget();
fillPreferencesWindow(window) {
const page = new Adw.PreferencesPage();
window.add(page);
const group = new AutoMoveSettingsWidget();
page.add(group);
}
}
+6 -8
View File
@@ -1,6 +1,9 @@
/* exported init enable disable */
// Drive menu extension
const {Clutter, Gio, GObject, Shell, St} = imports.gi;
import Clutter from 'gi://Clutter';
import Gio from 'gi://Gio';
import GObject from 'gi://GObject';
import Shell from 'gi://Shell';
import St from 'gi://St';
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
@@ -212,7 +215,7 @@ class DriveMenu extends PanelMenu.Button {
}
}
class Extension {
export default class Extension {
constructor() {
ExtensionUtils.initTranslations();
}
@@ -227,8 +230,3 @@ class Extension {
delete this._indicator;
}
}
/** */
function init() {
return new Extension();
}
+1 -7
View File
@@ -1,7 +1,6 @@
/* exported init */
const AppDisplay = imports.ui.appDisplay;
class Extension {
export default class Extension {
constructor() {
this._appIconProto = AppDisplay.AppIcon.prototype;
this._activateOriginal = this._appIconProto.activate;
@@ -18,8 +17,3 @@ class Extension {
this._appIconProto.activate = this._activateOriginal;
}
}
/** */
function init() {
return new Extension();
}
+2 -8
View File
@@ -1,4 +1,3 @@
/* exported init */
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,11 +15,11 @@
* SPDX-License-Identifier: GPL-2.0-or-later
*/
const {St} = imports.gi;
import St from 'gi://St';
const Main = imports.ui.main;
class Extension {
export default class Extension {
_updateColorScheme(scheme) {
Main.sessionMode.colorScheme = scheme;
St.Settings.get().notify('color-scheme');
@@ -35,8 +34,3 @@ class Extension {
this._updateColorScheme(this._savedColorScheme);
}
}
/** */
function init() {
return new Extension();
}
@@ -1,6 +1,5 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported enable disable */
const {Clutter} = imports.gi;
import Clutter from 'gi://Clutter';
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
@@ -236,7 +235,7 @@ class NaturalLayoutStrategy extends Workspace.LayoutStrategy {
}
}
class Extension {
export default class Extension {
constructor() {
this._savedMethods = new Map();
}
@@ -324,8 +323,3 @@ class Extension {
this._savedMethods.clear();
}
}
/** */
function init() {
return new Extension();
}
+6 -12
View File
@@ -1,15 +1,14 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
/* exported init enable disable */
const {Clutter, GObject, St} = imports.gi;
import Clutter from 'gi://Clutter';
import GObject from 'gi://GObject';
import St from 'gi://St';
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Me = ExtensionUtils.getCurrentExtension();
const PlaceDisplay = Me.imports.placeDisplay;
import {PlacesManager} from './placeDisplay.js';
const _ = ExtensionUtils.gettext;
const N_ = x => x;
@@ -100,7 +99,7 @@ class PlacesMenu extends PanelMenu.Button {
});
this.add_actor(label);
this.placesManager = new PlaceDisplay.PlacesManager();
this.placesManager = new PlacesManager();
this._sections = { };
@@ -138,7 +137,7 @@ class PlacesMenu extends PanelMenu.Button {
}
}
class Extension {
export default class Extension {
constructor() {
ExtensionUtils.initTranslations();
}
@@ -157,8 +156,3 @@ class Extension {
delete this._indicator;
}
}
/** */
function init() {
return new Extension();
}
+5 -5
View File
@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported PlacesManager */
const {Gio, GLib, Shell} = imports.gi;
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import Shell from 'gi://Shell';
const {EventEmitter} = imports.misc.signals;
const ExtensionUtils = imports.misc.extensionUtils;
@@ -248,7 +248,7 @@ const DEFAULT_DIRECTORIES = [
GLib.UserDirectory.DIRECTORY_VIDEOS,
];
var PlacesManager = class extends EventEmitter {
export class PlacesManager extends EventEmitter {
constructor() {
super();
@@ -546,4 +546,4 @@ var PlacesManager = class extends EventEmitter {
get(kind) {
return this._places[kind];
}
};
}
@@ -1,4 +1,3 @@
/* exported enable disable */
/* Screenshot Window Sizer for Gnome Shell
*
* Copyright (c) 2013 Owen Taylor <otaylor@redhat.com>
@@ -19,14 +18,17 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
const {Clutter, Meta, Shell, St} = imports.gi;
import Clutter from 'gi://Clutter';
import Meta from 'gi://Meta';
import Shell from 'gi://Shell';
import St from 'gi://St';
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const MESSAGE_FADE_TIME = 2000;
class Extension {
export default class Extension {
SIZES = [
[624, 351],
[800, 450],
@@ -163,8 +165,3 @@ class Extension {
Main.wm.removeKeybinding('cycle-screenshot-sizes-backward');
}
}
/** */
function init() {
return new Extension();
}
+5 -14
View File
@@ -1,18 +1,16 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
// Load shell theme from ~/.local/share/themes/name/gnome-shell
/* exported init */
const {Gio} = imports.gi;
import Gio from 'gi://Gio';
const ExtensionUtils = imports.misc.extensionUtils;
const Main = imports.ui.main;
const Me = ExtensionUtils.getCurrentExtension();
const Util = Me.imports.util;
import {getThemeDirs, getModeThemeDirs} from './util.js';
const SETTINGS_KEY = 'name';
class ThemeManager {
export default class ThemeManager {
enable() {
this._settings = ExtensionUtils.getSettings();
this._settings.connect(`changed::${SETTINGS_KEY}`, this._changeTheme.bind(this));
@@ -32,10 +30,10 @@ class ThemeManager {
let themeName = this._settings.get_string(SETTINGS_KEY);
if (themeName) {
const stylesheetPaths = Util.getThemeDirs()
const stylesheetPaths = getThemeDirs()
.map(dir => `${dir}/${themeName}/gnome-shell/gnome-shell.css`);
stylesheetPaths.push(...Util.getModeThemeDirs()
stylesheetPaths.push(...getModeThemeDirs()
.map(dir => `${dir}/${themeName}.css`));
stylesheet = stylesheetPaths.find(path => {
@@ -52,10 +50,3 @@ class ThemeManager {
Main.loadTheme();
}
}
/**
* @returns {ThemeManager} - the extension state object
*/
function init() {
return new ThemeManager();
}
+15 -14
View File
@@ -1,15 +1,17 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init buildPrefsWidget */
// we use async/await here to not block the mainloop, not to parallelize
/* eslint-disable no-await-in-loop */
const {Adw, Gio, GLib, GObject, Gtk} = imports.gi;
import Adw from 'gi://Adw';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk';
const ExtensionUtils = imports.misc.extensionUtils;
const Me = ExtensionUtils.getCurrentExtension();
const Util = Me.imports.util;
import {getThemeDirs, getModeThemeDirs} from './util.js';
Gio._promisify(Gio.File.prototype, 'enumerate_children_async');
Gio._promisify(Gio.File.prototype, 'query_info_async');
@@ -39,7 +41,7 @@ class UserThemePrefsWidget extends Adw.PreferencesGroup {
}
async _collectThemes() {
for (const dirName of Util.getThemeDirs()) {
for (const dirName of getThemeDirs()) {
const dir = Gio.File.new_for_path(dirName);
for (const name of await this._enumerateDir(dir)) {
if (this._rows.has(name))
@@ -60,7 +62,7 @@ class UserThemePrefsWidget extends Adw.PreferencesGroup {
}
}
for (const dirName of Util.getModeThemeDirs()) {
for (const dirName of getModeThemeDirs()) {
const dir = Gio.File.new_for_path(dirName);
for (const filename of await this._enumerateDir(dir)) {
if (!filename.endsWith('.css'))
@@ -125,13 +127,12 @@ class ThemeRow extends Adw.ActionRow {
}
}
/** */
function init() {
}
export default class ExtensionPreferences {
fillPreferencesWindow(window) {
const page = new Adw.PreferencesPage();
window.add(page);
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() {
return new UserThemePrefsWidget();
const group = new UserThemePrefsWidget();
page.add(group);
}
}
+3 -4
View File
@@ -1,12 +1,11 @@
/* exported getThemeDirs getModeThemeDirs */
const {GLib} = imports.gi;
import GLib from 'gi://GLib';
const fn = (...args) => GLib.build_filenamev(args);
/**
* @returns {string[]} - an ordered list of theme directories
*/
function getThemeDirs() {
export function getThemeDirs() {
return [
fn(GLib.get_home_dir(), '.themes'),
fn(GLib.get_user_data_dir(), 'themes'),
@@ -17,7 +16,7 @@ function getThemeDirs() {
/**
* @returns {string[]} - an ordered list of mode theme directories
*/
function getModeThemeDirs() {
export function getModeThemeDirs() {
return GLib.get_system_data_dirs()
.map(dir => fn(dir, 'gnome-shell', 'theme'));
}
+11 -12
View File
@@ -1,5 +1,11 @@
/* exported init */
const {Clutter, Gio, GLib, GObject, Gtk, Meta, Shell, St} = imports.gi;
import Clutter from 'gi://Clutter';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk';
import Meta from 'gi://Meta';
import Shell from 'gi://Shell';
import St from 'gi://St';
const DND = imports.ui.dnd;
const ExtensionUtils = imports.misc.extensionUtils;
@@ -8,8 +14,8 @@ const Overview = imports.ui.overview;
const PopupMenu = imports.ui.popupMenu;
const Me = ExtensionUtils.getCurrentExtension();
const {WindowPicker, WindowPickerToggle} = Me.imports.windowPicker;
const {WorkspaceIndicator} = Me.imports.workspaceIndicator;
import {WindowPicker, WindowPickerToggle} from './windowPicker.js';
import {WorkspaceIndicator} from './workspaceIndicator.js';
const _ = ExtensionUtils.gettext;
@@ -1149,7 +1155,7 @@ class WindowList extends St.Widget {
}
}
class Extension {
export default class Extension {
constructor() {
ExtensionUtils.initTranslations();
@@ -1279,10 +1285,3 @@ class Tooltip extends St.Label {
});
}
}
/**
* @returns {Extension} - the extension's state object
*/
function init() {
return new Extension();
}
+14 -13
View File
@@ -1,17 +1,14 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init buildPrefsWidget */
const {Adw, Gio, GLib, GObject, Gtk} = imports.gi;
import Adw from 'gi://Adw';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk';
const ExtensionUtils = imports.misc.extensionUtils;
const _ = ExtensionUtils.gettext;
/** */
function init() {
ExtensionUtils.initTranslations();
}
class WindowListPrefsWidget extends Adw.PreferencesPage {
static {
GObject.registerClass(this);
@@ -84,9 +81,13 @@ class WindowListPrefsWidget extends Adw.PreferencesPage {
}
}
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() {
return new WindowListPrefsWidget();
export default class ExtensionPreferences {
constructor() {
ExtensionUtils.initTranslations();
}
fillPreferencesWindow(window) {
const page = new WindowListPrefsWidget();
window.add(page);
}
}
+8 -6
View File
@@ -1,5 +1,7 @@
/* exported WindowPicker, WindowPickerToggle */
const {Clutter, GObject, Shell, St} = imports.gi;
import Clutter from 'gi://Clutter';
import GObject from 'gi://GObject';
import Shell from 'gi://Shell';
import St from 'gi://St';
const Layout = imports.ui.layout;
const Main = imports.ui.main;
@@ -149,7 +151,7 @@ class MyWorkspaceBackground extends Workspace.WorkspaceBackground {
}
}
var WindowPicker = class WindowPicker extends Clutter.Actor {
export class WindowPicker extends Clutter.Actor {
static [GObject.signals] = {
'open-state-changed': {param_types: [GObject.TYPE_BOOLEAN]},
};
@@ -324,9 +326,9 @@ var WindowPicker = class WindowPicker extends Clutter.Actor {
global.stage.disconnect(this._stageKeyPressId);
this._stageKeyPressId = 0;
}
};
}
var WindowPickerToggle = class WindowPickerToggle extends St.Button {
export class WindowPickerToggle extends St.Button {
static {
GObject.registerClass(this);
}
@@ -361,4 +363,4 @@ var WindowPickerToggle = class WindowPickerToggle extends St.Button {
this.checked = Main.windowPicker.visible;
});
}
};
}
+7 -4
View File
@@ -1,5 +1,8 @@
/* exported WorkspaceIndicator */
const {Clutter, Gio, GObject, Meta, St} = imports.gi;
import Clutter from 'gi://Clutter';
import Gio from 'gi://Gio';
import GObject from 'gi://GObject';
import Meta from 'gi://Meta';
import St from 'gi://St';
const DND = imports.ui.dnd;
const ExtensionUtils = imports.misc.extensionUtils;
@@ -252,7 +255,7 @@ class WorkspaceThumbnail extends St.Button {
}
}
var WorkspaceIndicator = class WorkspaceIndicator extends PanelMenu.Button {
export class WorkspaceIndicator extends PanelMenu.Button {
static {
GObject.registerClass(this);
}
@@ -447,4 +450,4 @@ var WorkspaceIndicator = class WorkspaceIndicator extends PanelMenu.Button {
let newIndex = this._currentWorkspace + diff;
this._activate(newIndex);
}
};
}
+5 -10
View File
@@ -1,6 +1,8 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
/* exported init */
const {Clutter, Graphene, GObject, St} = imports.gi;
import Clutter from 'gi://Clutter';
import Graphene from 'gi://Graphene';
import GObject from 'gi://GObject';
import St from 'gi://St';
const Main = imports.ui.main;
const OverviewControls = imports.ui.overviewControls;
@@ -251,7 +253,7 @@ class MyWorkspacesView extends WorkspacesView.WorkspacesView {
}
}
class Extension {
export default class Extension {
constructor() {
this._origWorkspace = Workspace.Workspace;
this._origWorkspacesView = WorkspacesView.WorkspacesView;
@@ -267,10 +269,3 @@ class Extension {
WorkspacesView.WorkspacesView = this._origWorkspacesView;
}
}
/**
* @returns {Extension} - the extension's state object
*/
function init() {
return new Extension();
}
+6 -9
View File
@@ -1,7 +1,9 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init enable disable */
const {Clutter, Gio, GObject, Meta, St} = imports.gi;
import Clutter from 'gi://Clutter';
import Gio from 'gi://Gio';
import GObject from 'gi://GObject';
import Meta from 'gi://Meta';
import St from 'gi://St';
const DND = imports.ui.dnd;
const ExtensionUtils = imports.misc.extensionUtils;
@@ -454,7 +456,7 @@ class WorkspaceIndicator extends PanelMenu.Button {
}
}
class Extension {
export default class Extension {
constructor() {
ExtensionUtils.initTranslations();
}
@@ -469,8 +471,3 @@ class Extension {
delete this._indicator;
}
}
/** */
function init() {
return new Extension();
}
+17 -12
View File
@@ -1,7 +1,10 @@
// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*-
/* exported init buildPrefsWidget */
const {Adw, Gio, GLib, GObject, Gtk, Pango} = imports.gi;
import Adw from 'gi://Adw';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk';
import Pango from 'gi://Pango';
const ExtensionUtils = imports.misc.extensionUtils;
@@ -256,14 +259,16 @@ class NewWorkspaceRow extends Adw.PreferencesRow {
}
}
/** */
function init() {
ExtensionUtils.initTranslations();
}
export default class ExtensionPreferences {
constructor() {
ExtensionUtils.initTranslations();
}
/**
* @returns {Gtk.Widget} - the prefs widget
*/
function buildPrefsWidget() {
return new WorkspaceSettingsWidget();
fillPreferencesWindow(window) {
const page = new Adw.PreferencesPage();
window.add(page);
const group = new WorkspaceSettingsWidget();
page.add(group);
}
}
+2
View File
@@ -10,3 +10,5 @@ rules:
prefer-arrow-callback: error
globals:
global: readonly
parserOptions:
sourceType: module