mirror of
https://github.com/edu4rdshl/gnome-shell.git
synced 2026-07-17 23:24:51 +00:00
ESM Part 1
This commit is contained in:
parent
ff88b5ab91
commit
91d6953ee6
163 changed files with 4763 additions and 2846 deletions
|
|
@ -66,7 +66,7 @@ library. These headers are not installed, distributed or introspected.
|
|||
Use UpperCamelCase when importing modules to distinguish them from ordinary
|
||||
variables, e.g.
|
||||
```javascript
|
||||
const GLib = imports.gi.GLib;
|
||||
import GLib from 'gi://GLib';
|
||||
```
|
||||
Imports should be categorized into one of two places. The top-most import block
|
||||
should contain only "environment imports". These are either modules from
|
||||
|
|
@ -118,7 +118,7 @@ See [What's new in JavaScript 1.7](https://developer.mozilla.org/en/JavaScript/N
|
|||
There are many approaches to classes in JavaScript. We use standard ES6 classes
|
||||
whenever possible, that is when not inheriting from GObjects.
|
||||
```javascript
|
||||
var IconLabelMenuItem = class extends PopupMenu.PopupMenuBaseItem {
|
||||
export class IconLabelMenuItem extends PopupMenu.PopupMenuBaseItem {
|
||||
constructor(icon, label) {
|
||||
super({ reactive: false });
|
||||
this.actor.add_child(icon);
|
||||
|
|
|
|||
|
|
@ -1,29 +1,34 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported AuthPrompt */
|
||||
|
||||
const { Clutter, GLib, GObject, Pango, Shell, St } = imports.gi;
|
||||
const { Clutter, GLib, GObject, Pango, Shell } = imports.gi;
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const Batch = imports.gdm.batch;
|
||||
const GdmUtil = imports.gdm.util;
|
||||
const OVirt = imports.gdm.oVirt;
|
||||
const Vmware = imports.gdm.vmware;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
const Util = imports.misc.util;
|
||||
import St from 'gi://St';
|
||||
import Gdm from 'gi://Gdm';
|
||||
|
||||
var DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
|
||||
var DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
|
||||
import * as Animation from '../ui/animation.js';
|
||||
import * as Batch from './batch.js';
|
||||
import * as GdmUtil from './util.js';
|
||||
import * as OVirt from './oVirt.js';
|
||||
import * as Vmware from './vmware.js';
|
||||
import * as ShellEntry from '../ui/shellEntry.js';
|
||||
import * as UserWidget from '../ui/userWidget.js';
|
||||
import * as Util from '../misc/util.js';
|
||||
|
||||
var MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
|
||||
export let DEFAULT_BUTTON_WELL_ICON_SIZE = 16;
|
||||
export let DEFAULT_BUTTON_WELL_ANIMATION_DELAY = 1000;
|
||||
export let DEFAULT_BUTTON_WELL_ANIMATION_TIME = 300;
|
||||
|
||||
var AuthPromptMode = {
|
||||
export let MESSAGE_FADE_OUT_ANIMATION_TIME = 500;
|
||||
|
||||
/** @enum {number} */
|
||||
export const AuthPromptMode = {
|
||||
UNLOCK_ONLY: 0,
|
||||
UNLOCK_OR_LOG_IN: 1,
|
||||
};
|
||||
|
||||
var AuthPromptStatus = {
|
||||
/** @enum {number} */
|
||||
export const AuthPromptStatus = {
|
||||
NOT_VERIFYING: 0,
|
||||
VERIFYING: 1,
|
||||
VERIFICATION_FAILED: 2,
|
||||
|
|
@ -32,13 +37,14 @@ var AuthPromptStatus = {
|
|||
VERIFICATION_IN_PROGRESS: 5,
|
||||
};
|
||||
|
||||
var BeginRequestType = {
|
||||
/** @enum {number} */
|
||||
export const BeginRequestType = {
|
||||
PROVIDE_USERNAME: 0,
|
||||
DONT_PROVIDE_USERNAME: 1,
|
||||
REUSE_USERNAME: 2,
|
||||
};
|
||||
|
||||
var AuthPrompt = GObject.registerClass({
|
||||
export const AuthPrompt = GObject.registerClass({
|
||||
Signals: {
|
||||
'cancelled': {},
|
||||
'failed': {},
|
||||
|
|
@ -47,6 +53,10 @@ var AuthPrompt = GObject.registerClass({
|
|||
'reset': { param_types: [GObject.TYPE_UINT] },
|
||||
},
|
||||
}, class AuthPrompt extends St.BoxLayout {
|
||||
/**
|
||||
* @param {Gdm.Client} gdmClient
|
||||
* @param {AuthPromptMode} mode
|
||||
*/
|
||||
_init(gdmClient, mode) {
|
||||
super._init({
|
||||
style_class: 'login-dialog-prompt-layout',
|
||||
|
|
@ -583,6 +593,9 @@ var AuthPrompt = GObject.registerClass({
|
|||
this._entry.clutter_text.insert_unichar(unichar);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ userName?: string | null, hold?: Batch.Hold | null }} [params]
|
||||
*/
|
||||
begin(params = {}) {
|
||||
let { userName = null, hold = null } = params;
|
||||
|
||||
|
|
|
|||
|
|
@ -45,10 +45,10 @@
|
|||
*/
|
||||
/* exported ConcurrentBatch, ConsecutiveBatch */
|
||||
|
||||
const { GObject } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import GObject from 'gi://GObject';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
var Task = class extends Signals.EventEmitter {
|
||||
export class Task extends Signals.EventEmitter {
|
||||
constructor(scope, handler) {
|
||||
super();
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ var Task = class extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var Hold = class extends Task {
|
||||
export class Hold extends Task {
|
||||
constructor() {
|
||||
super(null, () => this);
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ var Hold = class extends Task {
|
|||
}
|
||||
};
|
||||
|
||||
var Batch = class extends Task {
|
||||
export class Batch extends Task {
|
||||
constructor(scope, tasks) {
|
||||
super();
|
||||
|
||||
|
|
@ -173,7 +173,7 @@ var Batch = class extends Task {
|
|||
}
|
||||
};
|
||||
|
||||
var ConcurrentBatch = class extends Batch {
|
||||
export class ConcurrentBatch extends Batch {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
|
||||
|
|
@ -187,7 +187,7 @@ var ConcurrentBatch = class extends Batch {
|
|||
}
|
||||
};
|
||||
|
||||
var ConsecutiveBatch = class extends Batch {
|
||||
export class ConsecutiveBatch extends Batch {
|
||||
process() {
|
||||
let hold = this.runTask();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported CredentialManager */
|
||||
|
||||
const Signals = imports.misc.signals;
|
||||
import * as Signals from "../misc/signals.js";
|
||||
|
||||
var CredentialManager = class CredentialManager extends Signals.EventEmitter {
|
||||
export class CredentialManager extends Signals.EventEmitter {
|
||||
constructor(service) {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -17,28 +17,40 @@
|
|||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { AccountsService, Atk, Clutter, Gdm, Gio,
|
||||
GLib, GObject, Meta, Pango, Shell, St } = imports.gi;
|
||||
import AccountsService from 'gi://AccountsService';
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gdm from 'gi://Gdm';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Pango from 'gi://Pango';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const AuthPrompt = imports.gdm.authPrompt;
|
||||
const Batch = imports.gdm.batch;
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||
const GdmUtil = imports.gdm.util;
|
||||
const Layout = imports.ui.layout;
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Realmd = imports.gdm.realmd;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
import * as AuthPrompt from './authPrompt.js';
|
||||
import * as Batch from './batch.js';
|
||||
import * as BoxPointer from '../ui/boxpointer.js';
|
||||
import * as CtrlAltTab from '../ui/ctrlAltTab.js';
|
||||
import * as GdmUtil from './util.js';
|
||||
import * as Layout from '../ui/layout.js';
|
||||
import * as LoginManager from "../misc/loginManager.js";
|
||||
import Main from '../ui/main.js';
|
||||
import * as PopupMenu from '../ui/popupMenu.js';
|
||||
import * as Realmd from './realmd.js';
|
||||
import * as UserWidget from '../ui/userWidget.js';
|
||||
|
||||
const _FADE_ANIMATION_TIME = 250;
|
||||
const _SCROLL_ANIMATION_TIME = 500;
|
||||
const _TIMED_LOGIN_IDLE_THRESHOLD = 5.0;
|
||||
|
||||
var UserListItem = GObject.registerClass({
|
||||
export const UserListItem = GObject.registerClass({
|
||||
Signals: { 'activate': {} },
|
||||
}, class UserListItem extends St.Button {
|
||||
/**
|
||||
* @param {AccountsService.User} user
|
||||
*/
|
||||
_init(user) {
|
||||
let layout = new St.BoxLayout({
|
||||
vertical: true,
|
||||
|
|
@ -152,7 +164,7 @@ var UserListItem = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var UserList = GObject.registerClass({
|
||||
export const UserList = GObject.registerClass({
|
||||
Signals: {
|
||||
'activate': { param_types: [UserListItem.$gtype] },
|
||||
'item-added': { param_types: [UserListItem.$gtype] },
|
||||
|
|
@ -304,7 +316,7 @@ var UserList = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var SessionMenuButton = GObject.registerClass({
|
||||
export const SessionMenuButton = GObject.registerClass({
|
||||
Signals: { 'session-activated': { param_types: [GObject.TYPE_STRING] } },
|
||||
}, class SessionMenuButton extends St.Bin {
|
||||
_init() {
|
||||
|
|
@ -400,12 +412,15 @@ var SessionMenuButton = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var LoginDialog = GObject.registerClass({
|
||||
export const LoginDialog = GObject.registerClass({
|
||||
Signals: {
|
||||
'failed': {},
|
||||
'wake-up-screen': {},
|
||||
},
|
||||
}, class LoginDialog extends St.Widget {
|
||||
/**
|
||||
* @param {Clutter.Actor} parentActor
|
||||
*/
|
||||
_init(parentActor) {
|
||||
super._init({ style_class: 'login-dialog', visible: false });
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getOVirtCredentialsManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Credential = imports.gdm.credentialManager;
|
||||
import Gio from 'gi://Gio';
|
||||
import * as Credential from './credentialManager.js';
|
||||
|
||||
var SERVICE_NAME = 'gdm-ovirtcred';
|
||||
export const SERVICE_NAME = 'gdm-ovirtcred';
|
||||
|
||||
const OVirtCredentialsIface = `
|
||||
<node>
|
||||
|
|
@ -17,6 +16,7 @@ const OVirtCredentialsIface = `
|
|||
|
||||
const OVirtCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(OVirtCredentialsIface);
|
||||
|
||||
/** @type {OVirtCredentialsManager | null} */
|
||||
let _oVirtCredentialsManager = null;
|
||||
|
||||
function OVirtCredentials() {
|
||||
|
|
@ -30,7 +30,7 @@ function OVirtCredentials() {
|
|||
return self;
|
||||
}
|
||||
|
||||
var OVirtCredentialsManager = class OVirtCredentialsManager extends Credential.CredentialManager {
|
||||
export class OVirtCredentialsManager extends Credential.CredentialManager {
|
||||
constructor() {
|
||||
super(SERVICE_NAME);
|
||||
this._credentials = OVirtCredentials();
|
||||
|
|
@ -41,7 +41,7 @@ var OVirtCredentialsManager = class OVirtCredentialsManager extends Credential.C
|
|||
}
|
||||
};
|
||||
|
||||
function getOVirtCredentialsManager() {
|
||||
export function getOVirtCredentialsManager() {
|
||||
if (!_oVirtCredentialsManager)
|
||||
_oVirtCredentialsManager = new OVirtCredentialsManager();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Manager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Signals = imports.misc.signals;
|
||||
import Gio from 'gi://Gio';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
const ProviderIface = loadInterfaceXML("org.freedesktop.realmd.Provider");
|
||||
const Provider = Gio.DBusProxy.makeProxyWrapper(ProviderIface);
|
||||
|
|
@ -15,7 +15,7 @@ const Service = Gio.DBusProxy.makeProxyWrapper(ServiceIface);
|
|||
const RealmIface = loadInterfaceXML("org.freedesktop.realmd.Realm");
|
||||
const Realm = Gio.DBusProxy.makeProxyWrapper(RealmIface);
|
||||
|
||||
var Manager = class extends Signals.EventEmitter {
|
||||
export class Manager extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -3,15 +3,18 @@
|
|||
DISABLE_USER_LIST_KEY, fadeInActor, fadeOutActor, cloneAndFadeOutActor,
|
||||
ShellUserVerifier */
|
||||
|
||||
const { Clutter, Gdm, Gio, GLib } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gdm from 'gi://Gdm';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const Batch = imports.gdm.batch;
|
||||
const OVirt = imports.gdm.oVirt;
|
||||
const Vmware = imports.gdm.vmware;
|
||||
const Main = imports.ui.main;
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
const SmartcardManager = imports.misc.smartcardManager;
|
||||
import * as Batch from './batch.js';
|
||||
import * as OVirt from './oVirt.js';
|
||||
import * as Vmware from './vmware.js';
|
||||
import Main from '../ui/main.js';
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
import * as SmartcardManager from '../misc/smartcardManager.js';
|
||||
|
||||
const FprintManagerIface = loadInterfaceXML('net.reactivated.Fprint.Manager');
|
||||
const FprintManagerProxy = Gio.DBusProxy.makeProxyWrapper(FprintManagerIface);
|
||||
|
|
@ -27,29 +30,29 @@ Gio._promisify(Gdm.UserVerifierProxy.prototype,
|
|||
Gio._promisify(Gdm.UserVerifierProxy.prototype,
|
||||
'call_begin_verification', 'call_begin_verification_finish');
|
||||
|
||||
var PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||
var FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||
var SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
||||
var FADE_ANIMATION_TIME = 160;
|
||||
var CLONE_FADE_ANIMATION_TIME = 250;
|
||||
export const PASSWORD_SERVICE_NAME = 'gdm-password';
|
||||
export const FINGERPRINT_SERVICE_NAME = 'gdm-fingerprint';
|
||||
export const SMARTCARD_SERVICE_NAME = 'gdm-smartcard';
|
||||
export const FADE_ANIMATION_TIME = 160;
|
||||
export const CLONE_FADE_ANIMATION_TIME = 250;
|
||||
|
||||
var LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
||||
var PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication';
|
||||
var FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
|
||||
var SMARTCARD_AUTHENTICATION_KEY = 'enable-smartcard-authentication';
|
||||
var BANNER_MESSAGE_KEY = 'banner-message-enable';
|
||||
var BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
|
||||
var ALLOWED_FAILURES_KEY = 'allowed-failures';
|
||||
export const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
||||
export const PASSWORD_AUTHENTICATION_KEY = 'enable-password-authentication';
|
||||
export const FINGERPRINT_AUTHENTICATION_KEY = 'enable-fingerprint-authentication';
|
||||
export const SMARTCARD_AUTHENTICATION_KEY = 'enable-smartcard-authentication';
|
||||
export const BANNER_MESSAGE_KEY = 'banner-message-enable';
|
||||
export const BANNER_MESSAGE_TEXT_KEY = 'banner-message-text';
|
||||
export const ALLOWED_FAILURES_KEY = 'allowed-failures';
|
||||
|
||||
var LOGO_KEY = 'logo';
|
||||
var DISABLE_USER_LIST_KEY = 'disable-user-list';
|
||||
export const LOGO_KEY = 'logo';
|
||||
export const DISABLE_USER_LIST_KEY = 'disable-user-list';
|
||||
|
||||
// Give user 48ms to read each character of a PAM message
|
||||
var USER_READ_TIME = 48;
|
||||
export const USER_READ_TIME = 48;
|
||||
const FINGERPRINT_ERROR_TIMEOUT_WAIT = 15;
|
||||
|
||||
var MessageType = {
|
||||
// Keep messages in order by priority
|
||||
/** @enum {number} */
|
||||
export const MessageType = {
|
||||
NONE: 0,
|
||||
HINT: 1,
|
||||
INFO: 2,
|
||||
|
|
@ -62,7 +65,7 @@ const FingerprintReaderType = {
|
|||
SWIPE: 2,
|
||||
};
|
||||
|
||||
function fadeInActor(actor) {
|
||||
export function fadeInActor(actor) {
|
||||
if (actor.opacity == 255 && actor.visible)
|
||||
return null;
|
||||
|
||||
|
|
@ -86,7 +89,7 @@ function fadeInActor(actor) {
|
|||
return hold;
|
||||
}
|
||||
|
||||
function fadeOutActor(actor) {
|
||||
export function fadeOutActor(actor) {
|
||||
if (!actor.visible || actor.opacity == 0) {
|
||||
actor.opacity = 0;
|
||||
actor.hide();
|
||||
|
|
@ -108,7 +111,7 @@ function fadeOutActor(actor) {
|
|||
return hold;
|
||||
}
|
||||
|
||||
function cloneAndFadeOutActor(actor) {
|
||||
export function cloneAndFadeOutActor(actor) {
|
||||
// Immediately hide actor so its sibling can have its space
|
||||
// and position, but leave a non-reactive clone on-screen,
|
||||
// so from the user's point of view it smoothly fades away
|
||||
|
|
@ -136,7 +139,7 @@ function cloneAndFadeOutActor(actor) {
|
|||
return hold;
|
||||
}
|
||||
|
||||
var ShellUserVerifier = class extends Signals.EventEmitter {
|
||||
export class ShellUserVerifier extends Signals.EventEmitter {
|
||||
constructor(client, params = {}) {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getVmwareCredentialsManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Credential = imports.gdm.credentialManager;
|
||||
import Gio from 'gi://Gio';
|
||||
import * as Credential from './credentialManager.js';
|
||||
|
||||
const dbusPath = '/org/vmware/viewagent/Credentials';
|
||||
const dbusInterface = 'org.vmware.viewagent.Credentials';
|
||||
|
||||
var SERVICE_NAME = 'gdm-vmwcred';
|
||||
export const SERVICE_NAME = 'gdm-vmwcred';
|
||||
|
||||
const VmwareCredentialsIface = '<node> \
|
||||
<interface name="' + dbusInterface + '"> \
|
||||
|
|
@ -20,6 +19,7 @@ const VmwareCredentialsIface = '<node> \
|
|||
|
||||
const VmwareCredentialsInfo = Gio.DBusInterfaceInfo.new_for_xml(VmwareCredentialsIface);
|
||||
|
||||
/** @type {VmwareCredentialsManager | null} */
|
||||
let _vmwareCredentialsManager = null;
|
||||
|
||||
function VmwareCredentials() {
|
||||
|
|
@ -33,7 +33,7 @@ function VmwareCredentials() {
|
|||
return self;
|
||||
}
|
||||
|
||||
var VmwareCredentialsManager = class VmwareCredentialsManager extends Credential.CredentialManager {
|
||||
export class VmwareCredentialsManager extends Credential.CredentialManager {
|
||||
constructor() {
|
||||
super(SERVICE_NAME);
|
||||
this._credentials = VmwareCredentials();
|
||||
|
|
@ -44,7 +44,7 @@ var VmwareCredentialsManager = class VmwareCredentialsManager extends Credential
|
|||
}
|
||||
};
|
||||
|
||||
function getVmwareCredentialsManager() {
|
||||
export function getVmwareCredentialsManager() {
|
||||
if (!_vmwareCredentialsManager)
|
||||
_vmwareCredentialsManager = new VmwareCredentialsManager();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
<file>misc/config.js</file>
|
||||
<file>misc/extensionUtils.js</file>
|
||||
<file>misc/fileUtils.js</file>
|
||||
<file>misc/fileUtilsModule.js</file>
|
||||
<file>misc/gnomeSession.js</file>
|
||||
<file>misc/history.js</file>
|
||||
<file>misc/ibusManager.js</file>
|
||||
|
|
@ -120,7 +121,7 @@
|
|||
<file>ui/workspacesView.js</file>
|
||||
<file>ui/xdndHandler.js</file>
|
||||
|
||||
<file>ui/components/__init__.js</file>
|
||||
<file>ui/components.js</file>
|
||||
<file>ui/components/autorunManager.js</file>
|
||||
<file>ui/components/automountManager.js</file>
|
||||
<file>ui/components/networkAgent.js</file>
|
||||
|
|
|
|||
19
js/misc/config.d.ts
vendored
Normal file
19
js/misc/config.d.ts
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
/* The name of this package (not localized) */
|
||||
export const PACKAGE_NAME: string;
|
||||
/* The version of this package */
|
||||
export const PACKAGE_VERSION: string;
|
||||
/* 1 if gnome-bluetooth is available, 0 otherwise */
|
||||
export const HAVE_BLUETOOTH: boolean;
|
||||
/* 1 if networkmanager is available, 0 otherwise */
|
||||
export const HAVE_NETWORKMANAGER: boolean;
|
||||
/* gettext package */
|
||||
export const GETTEXT_PACKAGE: string;
|
||||
/* locale dir */
|
||||
export const LOCALEDIR: string;
|
||||
/* other standard directories */
|
||||
export const LIBEXECDIR: string;
|
||||
export const PKGDATADIR: string;
|
||||
/* g-i package versions */
|
||||
export const LIBMUTTER_API_VERSION: string;
|
||||
|
|
@ -18,4 +18,4 @@ var LOCALEDIR = '@datadir@/locale';
|
|||
var LIBEXECDIR = '@libexecdir@';
|
||||
var PKGDATADIR = '@datadir@/@PACKAGE_NAME@';
|
||||
/* g-i package versions */
|
||||
var LIBMUTTER_API_VERSION = '@LIBMUTTER_API_VERSION@'
|
||||
var LIBMUTTER_API_VERSION = '@LIBMUTTER_API_VERSION@';
|
||||
|
|
|
|||
|
|
@ -7,18 +7,19 @@
|
|||
// Common utils for the extension system and the extension
|
||||
// preferences tool
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
|
||||
const Gettext = imports.gettext;
|
||||
import * as Gettext from 'gettext';
|
||||
|
||||
const Config = imports.misc.config;
|
||||
|
||||
var ExtensionType = {
|
||||
export const ExtensionType = {
|
||||
SYSTEM: 1,
|
||||
PER_USER: 2,
|
||||
};
|
||||
|
||||
var ExtensionState = {
|
||||
export const ExtensionState = {
|
||||
ENABLED: 1,
|
||||
DISABLED: 2,
|
||||
ERROR: 3,
|
||||
|
|
@ -41,13 +42,36 @@ const SERIALIZED_PROPERTIES = [
|
|||
'canChange',
|
||||
];
|
||||
|
||||
let extension;
|
||||
/** @type {typeof import('../ui/main.js').default} */
|
||||
let Main;
|
||||
|
||||
export function _setCurrentExtension(currentExtension) {
|
||||
extension = currentExtension;
|
||||
}
|
||||
|
||||
/** @param {typeof import('../ui/main.js').default} main */
|
||||
export function _setMain(main) {
|
||||
Main = main;
|
||||
}
|
||||
|
||||
/** @typedef {object} Extension */
|
||||
|
||||
/**
|
||||
* getCurrentExtension:
|
||||
*
|
||||
* @returns {?object} - The current extension, or null if not called from
|
||||
* @returns {Extension} - The current extension, or null if not called from
|
||||
* an extension.
|
||||
*/
|
||||
function getCurrentExtension() {
|
||||
export function getCurrentExtension() {
|
||||
if (extension) {
|
||||
return extension;
|
||||
}
|
||||
|
||||
if (!Main) {
|
||||
throw new Error(`getCurrentExtension cannot be called before ExtensionUtils._setMain`);
|
||||
}
|
||||
|
||||
let stack = new Error().stack.split('\n');
|
||||
let extensionStackLine;
|
||||
|
||||
|
|
@ -74,7 +98,6 @@ function getCurrentExtension() {
|
|||
|
||||
// local import, as the module is used from outside the gnome-shell process
|
||||
// as well (not this function though)
|
||||
let extensionManager = imports.ui.main.extensionManager;
|
||||
|
||||
let path = match[1];
|
||||
let file = Gio.File.new_for_path(path);
|
||||
|
|
@ -82,7 +105,7 @@ function getCurrentExtension() {
|
|||
// Walk up the directory tree, looking for an extension with
|
||||
// the same UUID as a directory name.
|
||||
while (file != null) {
|
||||
let extension = extensionManager.lookup(file.get_basename());
|
||||
let extension = Main.extensionManager.lookup(file.get_basename());
|
||||
if (extension !== undefined)
|
||||
return extension;
|
||||
file = file.get_parent();
|
||||
|
|
@ -98,7 +121,7 @@ function getCurrentExtension() {
|
|||
* Initialize Gettext to load translations from extensionsdir/locale.
|
||||
* If @domain is not provided, it will be taken from metadata['gettext-domain']
|
||||
*/
|
||||
function initTranslations(domain) {
|
||||
export function initTranslations(domain) {
|
||||
let extension = getCurrentExtension();
|
||||
|
||||
if (!extension)
|
||||
|
|
@ -176,13 +199,13 @@ function callExtensionGettextFunc(func, ...args) {
|
|||
/**
|
||||
* getSettings:
|
||||
* @param {string=} schema - the GSettings schema id
|
||||
* @returns {Gio.Settings} - a new settings object for @schema
|
||||
* @returns {import("gi://Gio").Settings} - a new settings object for @schema
|
||||
*
|
||||
* Builds and returns a GSettings schema for @schema, using schema files
|
||||
* in extensionsdir/schemas. If @schema is omitted, it is taken from
|
||||
* metadata['settings-schema'].
|
||||
*/
|
||||
function getSettings(schema) {
|
||||
export function getSettings(schema) {
|
||||
let extension = getCurrentExtension();
|
||||
|
||||
if (!extension)
|
||||
|
|
@ -198,8 +221,8 @@ function getSettings(schema) {
|
|||
let schemaSource;
|
||||
if (schemaDir.query_exists(null)) {
|
||||
schemaSource = GioSSS.new_from_directory(schemaDir.get_path(),
|
||||
GioSSS.get_default(),
|
||||
false);
|
||||
GioSSS.get_default(),
|
||||
false);
|
||||
} else {
|
||||
schemaSource = GioSSS.get_default();
|
||||
}
|
||||
|
|
@ -216,15 +239,14 @@ function getSettings(schema) {
|
|||
*
|
||||
* Open the preference dialog of the current extension
|
||||
*/
|
||||
function openPrefs() {
|
||||
export function openPrefs() {
|
||||
const extension = getCurrentExtension();
|
||||
|
||||
if (!extension)
|
||||
throw new Error('openPrefs() can only be called from extensions');
|
||||
|
||||
try {
|
||||
const extensionManager = imports.ui.main.extensionManager;
|
||||
extensionManager.openExtensionPrefs(extension.uuid, '', {});
|
||||
Main.extensionManager.openExtensionPrefs(extension.uuid, '', {});
|
||||
} catch (e) {
|
||||
if (e.name === 'ImportError')
|
||||
throw new Error('openPrefs() cannot be called from preferences');
|
||||
|
|
@ -232,34 +254,37 @@ function openPrefs() {
|
|||
}
|
||||
}
|
||||
|
||||
function isOutOfDate(extension) {
|
||||
export function isOutOfDate(extension) {
|
||||
const [major] = Config.PACKAGE_VERSION.split('.');
|
||||
return !extension.metadata['shell-version'].some(v => v.startsWith(major));
|
||||
}
|
||||
|
||||
function serializeExtension(extension) {
|
||||
let obj = { ...extension.metadata };
|
||||
export function serializeExtension(extension) {
|
||||
let obj = {};
|
||||
Object.assign(obj, extension.metadata);
|
||||
|
||||
SERIALIZED_PROPERTIES.forEach(prop => {
|
||||
obj[prop] = extension[prop];
|
||||
});
|
||||
|
||||
/** @type {{ [key: string]: GLib.Variant<'b' | 's' | 'd'>}} */
|
||||
let res = {};
|
||||
for (let key in obj) {
|
||||
let val = obj[key];
|
||||
/** @type {'s' | 'd' | 'b'} */
|
||||
let type;
|
||||
switch (typeof val) {
|
||||
case 'string':
|
||||
type = 's';
|
||||
break;
|
||||
case 'number':
|
||||
type = 'd';
|
||||
break;
|
||||
case 'boolean':
|
||||
type = 'b';
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
case 'string':
|
||||
type = 's';
|
||||
break;
|
||||
case 'number':
|
||||
type = 'd';
|
||||
break;
|
||||
case 'boolean':
|
||||
type = 'b';
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
res[key] = GLib.Variant.new(type, val);
|
||||
}
|
||||
|
|
@ -267,7 +292,7 @@ function serializeExtension(extension) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function deserializeExtension(variant) {
|
||||
export function deserializeExtension(variant) {
|
||||
let res = { metadata: {} };
|
||||
for (let prop in variant) {
|
||||
let val = variant[prop].unpack();
|
||||
|
|
@ -282,11 +307,4 @@ function deserializeExtension(variant) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function installImporter(extension) {
|
||||
let oldSearchPath = imports.searchPath.slice(); // make a copy
|
||||
imports.searchPath = [extension.dir.get_parent().get_path()];
|
||||
// importing a "subdir" creates a new importer object that doesn't affect
|
||||
// the global one
|
||||
extension.imports = imports[extension.uuid];
|
||||
imports.searchPath = oldSearchPath;
|
||||
}
|
||||
// extension.dir.get_parent().get_path()
|
||||
|
|
|
|||
117
js/misc/fileUtilsModule.js
Normal file
117
js/misc/fileUtilsModule.js
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
|
||||
const Config = imports.misc.config;
|
||||
|
||||
export function collectFromDatadirs(subdir, includeUserDir, processFile) {
|
||||
let dataDirs = GLib.get_system_data_dirs();
|
||||
if (includeUserDir)
|
||||
dataDirs.unshift(GLib.get_user_data_dir());
|
||||
|
||||
for (let i = 0; i < dataDirs.length; i++) {
|
||||
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', subdir]);
|
||||
let dir = Gio.File.new_for_path(path);
|
||||
|
||||
let fileEnum;
|
||||
try {
|
||||
fileEnum = dir.enumerate_children('standard::name,standard::type',
|
||||
Gio.FileQueryInfoFlags.NONE, null);
|
||||
} catch (e) {
|
||||
fileEnum = null;
|
||||
}
|
||||
if (fileEnum != null) {
|
||||
let info;
|
||||
while ((info = fileEnum.next_file(null)))
|
||||
processFile(fileEnum.get_child(info), info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function recursivelyDeleteDir(dir, deleteParent) {
|
||||
let children = dir.enumerate_children('standard::name,standard::type',
|
||||
Gio.FileQueryInfoFlags.NONE, null);
|
||||
|
||||
let info;
|
||||
while ((info = children.next_file(null)) != null) {
|
||||
let type = info.get_file_type();
|
||||
let child = dir.get_child(info.get_name());
|
||||
if (type == Gio.FileType.REGULAR)
|
||||
child.delete(null);
|
||||
else if (type == Gio.FileType.DIRECTORY)
|
||||
recursivelyDeleteDir(child, true);
|
||||
}
|
||||
|
||||
if (deleteParent)
|
||||
dir.delete(null);
|
||||
}
|
||||
|
||||
export function recursivelyMoveDir(srcDir, destDir) {
|
||||
let children = srcDir.enumerate_children('standard::name,standard::type',
|
||||
Gio.FileQueryInfoFlags.NONE, null);
|
||||
|
||||
if (!destDir.query_exists(null))
|
||||
destDir.make_directory_with_parents(null);
|
||||
|
||||
let info;
|
||||
while ((info = children.next_file(null)) != null) {
|
||||
let type = info.get_file_type();
|
||||
let srcChild = srcDir.get_child(info.get_name());
|
||||
let destChild = destDir.get_child(info.get_name());
|
||||
if (type == Gio.FileType.REGULAR)
|
||||
srcChild.move(destChild, Gio.FileCopyFlags.NONE, null, null);
|
||||
else if (type == Gio.FileType.DIRECTORY)
|
||||
recursivelyMoveDir(srcChild, destChild);
|
||||
}
|
||||
}
|
||||
|
||||
let _ifaceResource = null;
|
||||
function ensureIfaceResource() {
|
||||
if (_ifaceResource)
|
||||
return;
|
||||
|
||||
// don't use global.datadir so the method is usable from tests/tools
|
||||
let dir = GLib.getenv('GNOME_SHELL_DATADIR') || Config.PKGDATADIR;
|
||||
let path = `${dir}/gnome-shell-dbus-interfaces.gresource`;
|
||||
_ifaceResource = Gio.Resource.load(path);
|
||||
_ifaceResource._register();
|
||||
}
|
||||
|
||||
export function loadInterfaceXML(iface) {
|
||||
ensureIfaceResource();
|
||||
|
||||
let uri = `resource:///org/gnome/shell/dbus-interfaces/${iface}.xml`;
|
||||
let f = Gio.File.new_for_uri(uri);
|
||||
|
||||
try {
|
||||
let [ok_, bytes] = f.load_contents(null);
|
||||
return imports.byteArray.toString(bytes);
|
||||
} catch (e) {
|
||||
log(`Failed to load D-Bus interface ${iface}`);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function loadSubInterfaceXML(iface, ifaceFile) {
|
||||
let xml = loadInterfaceXML(ifaceFile);
|
||||
if (!xml)
|
||||
return null;
|
||||
|
||||
let ifaceStartTag = `<interface name="${iface}">`;
|
||||
let ifaceStopTag = '</interface>';
|
||||
let ifaceStartIndex = xml.indexOf(ifaceStartTag);
|
||||
let ifaceEndIndex = xml.indexOf(ifaceStopTag, ifaceStartIndex + 1) + ifaceStopTag.length;
|
||||
|
||||
let xmlHeader = '<!DOCTYPE node PUBLIC\n' +
|
||||
'\'-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\'\n' +
|
||||
'\'http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\'>\n' +
|
||||
'<node>\n';
|
||||
let xmlFooter = '</node>';
|
||||
|
||||
return (
|
||||
xmlHeader +
|
||||
xml.substr(ifaceStartIndex, ifaceEndIndex - ifaceStartIndex) +
|
||||
xmlFooter);
|
||||
}
|
||||
|
|
@ -1,21 +1,22 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported PresenceStatus, Presence, Inhibitor, SessionManager, InhibitFlags */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
import Gio from 'gi://Gio';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from "../misc/fileUtilsModule.js";
|
||||
|
||||
const PresenceIface = loadInterfaceXML('org.gnome.SessionManager.Presence');
|
||||
|
||||
var PresenceStatus = {
|
||||
/** @enum {number} */
|
||||
export const PresenceStatus = {
|
||||
AVAILABLE: 0,
|
||||
INVISIBLE: 1,
|
||||
BUSY: 2,
|
||||
IDLE: 3,
|
||||
};
|
||||
|
||||
var PresenceProxy = Gio.DBusProxy.makeProxyWrapper(PresenceIface);
|
||||
function Presence(initCallback, cancellable) {
|
||||
export const PresenceProxy = Gio.DBusProxy.makeProxyWrapper(PresenceIface);
|
||||
export function Presence(initCallback, cancellable) {
|
||||
return new PresenceProxy(Gio.DBus.session, 'org.gnome.SessionManager',
|
||||
'/org/gnome/SessionManager/Presence', initCallback, cancellable);
|
||||
}
|
||||
|
|
@ -25,18 +26,18 @@ function Presence(initCallback, cancellable) {
|
|||
// of new inhibitors)
|
||||
const InhibitorIface = loadInterfaceXML('org.gnome.SessionManager.Inhibitor');
|
||||
var InhibitorProxy = Gio.DBusProxy.makeProxyWrapper(InhibitorIface);
|
||||
function Inhibitor(objectPath, initCallback, cancellable) {
|
||||
export function Inhibitor(objectPath, initCallback, cancellable) {
|
||||
return InhibitorProxy(Gio.DBus.session, 'org.gnome.SessionManager', objectPath, initCallback, cancellable);
|
||||
}
|
||||
|
||||
// Not the full interface, only the methods we use
|
||||
const SessionManagerIface = loadInterfaceXML('org.gnome.SessionManager');
|
||||
var SessionManagerProxy = Gio.DBusProxy.makeProxyWrapper(SessionManagerIface);
|
||||
function SessionManager(initCallback, cancellable) {
|
||||
export function SessionManager(initCallback, cancellable) {
|
||||
return SessionManagerProxy(Gio.DBus.session, 'org.gnome.SessionManager', '/org/gnome/SessionManager', initCallback, cancellable);
|
||||
}
|
||||
|
||||
var InhibitFlags = {
|
||||
export const InhibitFlags = {
|
||||
LOGOUT: 1 << 0,
|
||||
SWITCH: 1 << 1,
|
||||
SUSPEND: 1 << 2,
|
||||
|
|
|
|||
|
|
@ -1,12 +1,22 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported HistoryManager */
|
||||
|
||||
const Signals = imports.misc.signals;
|
||||
const Clutter = imports.gi.Clutter;
|
||||
import * as Signals from './signals.js';
|
||||
import Clutter from 'gi://Clutter';
|
||||
|
||||
var DEFAULT_LIMIT = 512;
|
||||
|
||||
var HistoryManager = class extends Signals.EventEmitter {
|
||||
/**
|
||||
* @typedef {object} HistoryManagerParams
|
||||
* @property {string | null} gsettingsKey
|
||||
* @property {number} limit
|
||||
* @property {Clutter.Text} entry
|
||||
*/
|
||||
|
||||
export class HistoryManager extends Signals.EventEmitter {
|
||||
/**
|
||||
* @param {Partial<HistoryManagerParams>} params
|
||||
*/
|
||||
constructor(params = {}) {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getIBusManager */
|
||||
|
||||
const { Gio, GLib, IBus, Meta } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import IBus from 'gi://IBus';
|
||||
import Meta from 'gi://Meta';
|
||||
import * as Signals from './signals.js';
|
||||
|
||||
const IBusCandidatePopup = imports.ui.ibusCandidatePopup;
|
||||
import * as IBusCandidatePopup from '../ui/ibusCandidatePopup.js';
|
||||
|
||||
Gio._promisify(IBus.Bus.prototype,
|
||||
'list_engines_async', 'list_engines_async_finish');
|
||||
|
|
@ -18,6 +20,7 @@ Gio._promisify(IBus.Bus.prototype,
|
|||
// Ensure runtime version matches
|
||||
_checkIBusVersion(1, 5, 2);
|
||||
|
||||
/** @type {IBusManager | null} */
|
||||
let _ibusManager = null;
|
||||
|
||||
function _checkIBusVersion(requiredMajor, requiredMinor, requiredMicro) {
|
||||
|
|
@ -32,13 +35,13 @@ function _checkIBusVersion(requiredMajor, requiredMinor, requiredMicro) {
|
|||
requiredMajor, requiredMinor, requiredMicro);
|
||||
}
|
||||
|
||||
function getIBusManager() {
|
||||
export function getIBusManager() {
|
||||
if (_ibusManager == null)
|
||||
_ibusManager = new IBusManager();
|
||||
return _ibusManager;
|
||||
}
|
||||
|
||||
var IBusManager = class extends Signals.EventEmitter {
|
||||
export class IBusManager extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported InputMethod */
|
||||
const { Clutter, GLib, Gio, GObject, IBus } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import IBus from 'gi://IBus';
|
||||
|
||||
const Keyboard = imports.ui.status.keyboard;
|
||||
import * as Keyboard from '../ui/status/keyboard.js';
|
||||
|
||||
Gio._promisify(IBus.Bus.prototype,
|
||||
'create_input_context_async', 'create_input_context_async_finish');
|
||||
|
||||
var HIDE_PANEL_TIME = 50;
|
||||
export let HIDE_PANEL_TIME = 50;
|
||||
|
||||
var InputMethod = GObject.registerClass(
|
||||
export const InputMethod = GObject.registerClass(
|
||||
class InputMethod extends Clutter.InputMethod {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
/* exported IntrospectService */
|
||||
const { Gio, GLib, Meta, Shell, St } = imports.gi;
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const APP_ALLOWLIST = [
|
||||
'org.freedesktop.impl.portal.desktop.gtk',
|
||||
|
|
@ -8,12 +12,12 @@ const APP_ALLOWLIST = [
|
|||
|
||||
const INTROSPECT_DBUS_API_VERSION = 3;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
const { DBusSenderChecker } = imports.misc.util;
|
||||
import { loadInterfaceXML } from "./fileUtilsModule.js";
|
||||
import { DBusSenderChecker } from "./util.js";
|
||||
|
||||
const IntrospectDBusIface = loadInterfaceXML('org.gnome.Shell.Introspect');
|
||||
|
||||
var IntrospectService = class {
|
||||
export class IntrospectService {
|
||||
constructor() {
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(IntrospectDBusIface,
|
||||
this);
|
||||
|
|
@ -131,6 +135,7 @@ var IntrospectService = class {
|
|||
GetWindowsAsync(params, invocation) {
|
||||
let focusWindow = global.display.get_focus_window();
|
||||
let apps = this._appSystem.get_running();
|
||||
/** @type {{ [key: number]: { [key: string]: GLib.Variant }}} */
|
||||
let windowsList = {};
|
||||
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/* exported getCompletions, getCommonPrefix, getDeclaredConstants */
|
||||
|
||||
// Returns a list of potential completions for text. Completions either
|
||||
// follow a dot (e.g. foo.ba -> bar) or they are picked from globalCompletionList (e.g. fo -> foo)
|
||||
|
|
@ -7,7 +6,7 @@
|
|||
// consist of global constants that might not carry over from the calling environment.
|
||||
//
|
||||
// This function is likely the one you want to call from external modules
|
||||
function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
export function getCompletions(text, commandHeader, globalCompletionList) {
|
||||
let methods = [];
|
||||
let expr_, base;
|
||||
let attrHead = '';
|
||||
|
|
@ -108,7 +107,7 @@ function findTheBrace(expr, offset, ...braces) {
|
|||
// There is no guarantee of correct javascript syntax between the return
|
||||
// value and offset. This function is meant to take a string like
|
||||
// "foo(Obj.We.Are.Completing" and allow you to extract "Obj.We.Are.Completing"
|
||||
function getExpressionOffset(expr, offset) {
|
||||
export function getExpressionOffset(expr, offset) {
|
||||
while (offset >= 0) {
|
||||
let currChar = expr.charAt(offset);
|
||||
|
||||
|
|
@ -132,7 +131,7 @@ function isValidPropertyName(w) {
|
|||
|
||||
// To get all properties (enumerable and not), we need to walk
|
||||
// the prototype chain ourselves
|
||||
function getAllProps(obj) {
|
||||
export function getAllProps(obj) {
|
||||
if (obj === null || obj === undefined)
|
||||
return [];
|
||||
|
||||
|
|
@ -144,7 +143,7 @@ function getAllProps(obj) {
|
|||
// e.g., expr="({ foo: null, bar: null, 4: null })" will
|
||||
// return ["foo", "bar", ...] but the list will not include "4",
|
||||
// since methods accessed with '.' notation must star with a letter or _.
|
||||
function getPropertyNamesFromExpression(expr, commandHeader = '') {
|
||||
export function getPropertyNamesFromExpression(expr, commandHeader = '') {
|
||||
let obj = {};
|
||||
if (!isUnsafeExpression(expr)) {
|
||||
try {
|
||||
|
|
@ -170,7 +169,7 @@ function getPropertyNamesFromExpression(expr, commandHeader = '') {
|
|||
}
|
||||
|
||||
// Given a list of words, returns the longest prefix they all have in common
|
||||
function getCommonPrefix(words) {
|
||||
export function getCommonPrefix(words) {
|
||||
let word = words[0];
|
||||
for (let i = 0; i < word.length; i++) {
|
||||
for (let w = 1; w < words.length; w++) {
|
||||
|
|
@ -221,7 +220,7 @@ function isUnsafeExpression(str) {
|
|||
}
|
||||
|
||||
// Returns a list of global keywords derived from str
|
||||
function getDeclaredConstants(str) {
|
||||
export function getDeclaredConstants(str) {
|
||||
let ret = [];
|
||||
str.split(';').forEach(s => {
|
||||
let base_, keyword;
|
||||
|
|
|
|||
|
|
@ -1,42 +1,43 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getKeyboardManager, holdKeyboard, releaseKeyboard */
|
||||
|
||||
const { GLib, GnomeDesktop } = imports.gi;
|
||||
import GLib from 'gi://GLib';
|
||||
import GnomeDesktop from 'gi://GnomeDesktop';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
import Main from "../ui/main.js";
|
||||
|
||||
var DEFAULT_LOCALE = 'en_US';
|
||||
var DEFAULT_LAYOUT = 'us';
|
||||
var DEFAULT_VARIANT = '';
|
||||
export let DEFAULT_LOCALE = 'en_US';
|
||||
export let DEFAULT_LAYOUT = 'us';
|
||||
export let DEFAULT_VARIANT = '';
|
||||
|
||||
let _xkbInfo = null;
|
||||
|
||||
function getXkbInfo() {
|
||||
export function getXkbInfo() {
|
||||
if (_xkbInfo == null)
|
||||
_xkbInfo = new GnomeDesktop.XkbInfo();
|
||||
return _xkbInfo;
|
||||
}
|
||||
|
||||
/** @type {KeyboardManager | null} */
|
||||
let _keyboardManager = null;
|
||||
|
||||
function getKeyboardManager() {
|
||||
export function getKeyboardManager() {
|
||||
if (_keyboardManager == null)
|
||||
_keyboardManager = new KeyboardManager();
|
||||
return _keyboardManager;
|
||||
}
|
||||
|
||||
function releaseKeyboard() {
|
||||
export function releaseKeyboard() {
|
||||
if (Main.modalCount > 0)
|
||||
global.display.unfreeze_keyboard(global.get_current_time());
|
||||
else
|
||||
global.display.ungrab_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
function holdKeyboard() {
|
||||
export function holdKeyboard() {
|
||||
global.display.freeze_keyboard(global.get_current_time());
|
||||
}
|
||||
|
||||
var KeyboardManager = class {
|
||||
export class KeyboardManager {
|
||||
constructor() {
|
||||
// The XKB protocol doesn't allow for more that 4 layouts in a
|
||||
// keymap. Wayland doesn't impose this limit and libxkbcommon can
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported canLock, getLoginManager, registerSessionWithGDM */
|
||||
|
||||
const { GLib, Gio } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import GLib from 'gi://GLib';
|
||||
import Gio from 'gi://Gio';
|
||||
import * as Signals from './signals.js';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from "./fileUtilsModule.js";
|
||||
|
||||
const SystemdLoginManagerIface = loadInterfaceXML('org.freedesktop.login1.Manager');
|
||||
const SystemdLoginSessionIface = loadInterfaceXML('org.freedesktop.login1.Session');
|
||||
|
|
@ -32,7 +32,7 @@ function versionCompare(required, reference) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function canLock() {
|
||||
export function canLock() {
|
||||
try {
|
||||
let params = GLib.Variant.new('(ss)', ['org.gnome.DisplayManager.Manager', 'Version']);
|
||||
let result = Gio.DBus.system.call_sync('org.gnome.DisplayManager',
|
||||
|
|
@ -49,8 +49,7 @@ function canLock() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
async function registerSessionWithGDM() {
|
||||
export async function registerSessionWithGDM() {
|
||||
log("Registering session with GDM");
|
||||
try {
|
||||
await Gio.DBus.system.call(
|
||||
|
|
@ -68,6 +67,7 @@ async function registerSessionWithGDM() {
|
|||
}
|
||||
}
|
||||
|
||||
/** @type {LoginManagerSystemd | LoginManagerDummy | null} */
|
||||
let _loginManager = null;
|
||||
|
||||
/**
|
||||
|
|
@ -76,7 +76,7 @@ let _loginManager = null;
|
|||
* @returns {object} - the LoginManager singleton
|
||||
*
|
||||
*/
|
||||
function getLoginManager() {
|
||||
export function getLoginManager() {
|
||||
if (_loginManager == null) {
|
||||
if (haveSystemd())
|
||||
_loginManager = new LoginManagerSystemd();
|
||||
|
|
@ -87,7 +87,7 @@ function getLoginManager() {
|
|||
return _loginManager;
|
||||
}
|
||||
|
||||
var LoginManagerSystemd = class extends Signals.EventEmitter {
|
||||
export class LoginManagerSystemd extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -205,7 +205,7 @@ var LoginManagerSystemd = class extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var LoginManagerDummy = class extends Signals.EventEmitter {
|
||||
export class LoginManagerDummy extends Signals.EventEmitter {
|
||||
getCurrentSessionProxy(_callback) {
|
||||
// we could return a DummySession object that fakes whatever callers
|
||||
// expect (at the time of writing: connect() and connectSignal()
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported ModemBase, ModemGsm, ModemCdma, BroadbandModem */
|
||||
|
||||
const { Gio, GObject, NM, NMA } = imports.gi;
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import NM from 'gi://NM';
|
||||
import NMA from 'gi://NMA';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from "./fileUtilsModule.js";
|
||||
|
||||
// _getMobileProvidersDatabase:
|
||||
//
|
||||
|
|
@ -98,7 +101,7 @@ const ModemGsmNetworkProxy = Gio.DBusProxy.makeProxyWrapper(ModemGsmNetworkInter
|
|||
const ModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager.Modem.Cdma');
|
||||
const ModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(ModemCdmaInterface);
|
||||
|
||||
var ModemBase = GObject.registerClass({
|
||||
export const ModemBase = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT,
|
||||
Properties: {
|
||||
'operator-name': GObject.ParamSpec.string(
|
||||
|
|
@ -111,8 +114,8 @@ var ModemBase = GObject.registerClass({
|
|||
0, 100, 0),
|
||||
},
|
||||
}, class ModemBase extends GObject.Object {
|
||||
_init() {
|
||||
super._init();
|
||||
_init(...args) {
|
||||
super._init(...args);
|
||||
this._operatorName = null;
|
||||
this._signalQuality = 0;
|
||||
}
|
||||
|
|
@ -140,7 +143,7 @@ var ModemBase = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ModemGsm = GObject.registerClass(
|
||||
export const ModemGsm = GObject.registerClass(
|
||||
class ModemGsm extends ModemBase {
|
||||
_init(path) {
|
||||
super._init();
|
||||
|
|
@ -174,7 +177,7 @@ class ModemGsm extends ModemBase {
|
|||
}
|
||||
});
|
||||
|
||||
var ModemCdma = GObject.registerClass(
|
||||
export const ModemCdma = GObject.registerClass(
|
||||
class ModemCdma extends ModemBase {
|
||||
_init(path) {
|
||||
super._init();
|
||||
|
|
@ -226,7 +229,7 @@ const BroadbandModem3gppProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModem3gp
|
|||
const BroadbandModemCdmaInterface = loadInterfaceXML('org.freedesktop.ModemManager1.Modem.ModemCdma');
|
||||
const BroadbandModemCdmaProxy = Gio.DBusProxy.makeProxyWrapper(BroadbandModemCdmaInterface);
|
||||
|
||||
var BroadbandModem = GObject.registerClass({
|
||||
export const BroadbandModem = GObject.registerClass({
|
||||
Properties: {
|
||||
'capabilities': GObject.ParamSpec.flags(
|
||||
'capabilities', 'capabilities', 'capabilities',
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported ObjectManager */
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import * as Signals from './signals.js';
|
||||
|
||||
// Specified in the D-Bus specification here:
|
||||
// http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-objectmanager
|
||||
|
|
@ -25,7 +26,7 @@ const ObjectManagerIface = `
|
|||
|
||||
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
|
||||
|
||||
var ObjectManager = class extends Signals.EventEmitter {
|
||||
export class ObjectManager extends Signals.EventEmitter {
|
||||
constructor(params = {}) {
|
||||
super();
|
||||
|
||||
|
|
@ -243,6 +244,9 @@ var ObjectManager = class extends Signals.EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string[]} interfaces
|
||||
*/
|
||||
_registerInterfaces(interfaces) {
|
||||
for (let i = 0; i < interfaces.length; i++) {
|
||||
let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
|
||||
|
|
|
|||
6
js/misc/params.d.ts
vendored
Normal file
6
js/misc/params.d.ts
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
export type Anyify<D extends { [key: string]: any }> = { [key in keyof D]?: any };
|
||||
|
||||
export function parse<D extends { [key: string]: any }, P extends { [key: string]: any }>(params: P, defaults: D, allowExtras: true): D & typeof params;
|
||||
export function parse<D extends { [key: string]: any }, P extends Anyify<D>>(params: P, defaults: D, allowExtras: false): D;
|
||||
export function parse<D extends { [key: string]: any }, P extends Anyify<D>>(params: P, defaults: D): D;
|
||||
export function parse<D extends { [key: string]: any }, P extends Anyify<D> | { [key: string]: any }>(params: P, defaults: D, allowExtras: boolean): D | D & typeof params;
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
//
|
||||
// Return value: a new object, containing the merged parameters from
|
||||
// @params and @defaults
|
||||
function parse(params = {}, defaults, allowExtras) {
|
||||
export function parse(params = {}, defaults, allowExtras) {
|
||||
if (!allowExtras) {
|
||||
for (let prop in params) {
|
||||
if (!(prop in defaults))
|
||||
|
|
|
|||
|
|
@ -21,23 +21,24 @@
|
|||
// along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
/* exported getDefault */
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Shell from 'gi://Shell';
|
||||
|
||||
const { Gio, GObject, Shell } = imports.gi;
|
||||
import gi from 'gi';
|
||||
|
||||
// We require libmalcontent ≥ 0.6.0
|
||||
const HAVE_MALCONTENT = imports.package.checkSymbol(
|
||||
'Malcontent', '0', 'ManagerGetValueFlags');
|
||||
const HAVE_MALCONTENT = true;
|
||||
|
||||
var Malcontent = null;
|
||||
let Malcontent = null;
|
||||
if (HAVE_MALCONTENT) {
|
||||
Malcontent = imports.gi.Malcontent;
|
||||
Malcontent = gi.require('Malcontent');
|
||||
Gio._promisify(Malcontent.Manager.prototype, 'get_app_filter_async', 'get_app_filter_finish');
|
||||
}
|
||||
|
||||
let _singleton = null;
|
||||
|
||||
function getDefault() {
|
||||
export function getDefault() {
|
||||
if (_singleton === null)
|
||||
_singleton = new ParentalControlsManager();
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ function getDefault() {
|
|||
// parental controls settings. It’s possible for the user’s parental controls
|
||||
// to change at runtime if the Parental Controls application is used by an
|
||||
// administrator from within the user’s session.
|
||||
var ParentalControlsManager = GObject.registerClass({
|
||||
export const ParentalControlsManager = GObject.registerClass({
|
||||
Signals: {
|
||||
'app-filter-changed': {},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported PermissionStore */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
import Gio from 'gi://Gio';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from "./fileUtilsModule.js";
|
||||
|
||||
const PermissionStoreIface = loadInterfaceXML('org.freedesktop.impl.portal.PermissionStore');
|
||||
const PermissionStoreProxy = Gio.DBusProxy.makeProxyWrapper(PermissionStoreIface);
|
||||
|
||||
function PermissionStore(initCallback, cancellable) {
|
||||
export function PermissionStore(initCallback, cancellable) {
|
||||
return PermissionStoreProxy(Gio.DBus.session,
|
||||
'org.freedesktop.impl.portal.PermissionStore',
|
||||
'/org/freedesktop/impl/portal/PermissionStore',
|
||||
|
|
|
|||
9
js/misc/signals.d.ts
vendored
Normal file
9
js/misc/signals.d.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
export type EventId = number;
|
||||
|
||||
export class EventEmitter {
|
||||
connect(event: string, handler: (...args: any[]) => any): EventId;
|
||||
disconnect(id: EventId);
|
||||
emit(event: string, ...args: any[]);
|
||||
disconnectAll();
|
||||
signalHandlerIsConnected(event: string);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
/** @type {import("environment").SignalsNamespace} */
|
||||
const Signals = imports.signals;
|
||||
|
||||
var EventEmitter = class EventEmitter {};
|
||||
export class EventEmitter {}
|
||||
|
||||
Signals.addSignalMethods(EventEmitter.prototype);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,9 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getSmartcardManager */
|
||||
|
||||
const Gio = imports.gi.Gio;
|
||||
const Signals = imports.misc.signals;
|
||||
import Gio from 'gi://Gio';
|
||||
import * as Signals from './signals.js';
|
||||
|
||||
const ObjectManager = imports.misc.objectManager;
|
||||
import * as ObjectManager from "./objectManager.js";
|
||||
|
||||
const SmartcardTokenIface = `
|
||||
<node>
|
||||
|
|
@ -16,16 +15,17 @@ const SmartcardTokenIface = `
|
|||
</interface>
|
||||
</node>`;
|
||||
|
||||
/** @type {SmartcardManager | null} */
|
||||
let _smartcardManager = null;
|
||||
|
||||
function getSmartcardManager() {
|
||||
export function getSmartcardManager() {
|
||||
if (_smartcardManager == null)
|
||||
_smartcardManager = new SmartcardManager();
|
||||
|
||||
return _smartcardManager;
|
||||
}
|
||||
|
||||
var SmartcardManager = class extends Signals.EventEmitter {
|
||||
export class SmartcardManager extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
/* exported getDefault */
|
||||
const { AccountsService, Clutter, Gdm, Gio, GLib, GObject, Meta } = imports.gi;
|
||||
import AccountsService from 'gi://AccountsService';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gdm from 'gi://Gdm';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
import * as GnomeSession from "./gnomeSession.js";
|
||||
import * as LoginManager from "./loginManager.js";
|
||||
|
||||
import Main from "../ui/main.js";
|
||||
|
||||
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
|
||||
const LOGIN_SCREEN_SCHEMA = 'org.gnome.login-screen';
|
||||
|
|
@ -23,7 +31,7 @@ const LOCK_ORIENTATION_ACTION_ID = 'lock-orientation';
|
|||
|
||||
let _singleton = null;
|
||||
|
||||
function getDefault() {
|
||||
export function getDefault() {
|
||||
if (_singleton == null)
|
||||
_singleton = new SystemActions();
|
||||
|
||||
|
|
@ -137,7 +145,8 @@ const SystemActions = GObject.registerClass({
|
|||
this._lockdownSettings = new Gio.Settings({ schema_id: LOCKDOWN_SCHEMA });
|
||||
this._orientationSettings = new Gio.Settings({ schema_id: 'org.gnome.settings-daemon.peripherals.touchscreen' });
|
||||
|
||||
this._session = new GnomeSession.SessionManager();
|
||||
// FIXME
|
||||
this._session = GnomeSession.SessionManager();
|
||||
this._loginManager = LoginManager.getLoginManager();
|
||||
this._monitorManager = Meta.MonitorManager.get();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,18 @@
|
|||
ensureActorVisibleInScrollView, wiggle, lerp, GNOMEversionCompare,
|
||||
DBusSenderChecker */
|
||||
|
||||
const { Clutter, Gio, GLib, Shell, St, GnomeDesktop } = imports.gi;
|
||||
const Gettext = imports.gettext;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import GnomeDesktop from 'gi://GnomeDesktop';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
import Main from "../ui/main.js";
|
||||
|
||||
var SCROLL_TIME = 100;
|
||||
import * as Gettext from 'gettext';
|
||||
|
||||
export let SCROLL_TIME = 100;
|
||||
|
||||
const WIGGLE_OFFSET = 6;
|
||||
const WIGGLE_DURATION = 65;
|
||||
|
|
@ -52,7 +58,7 @@ let _desktopSettings = null;
|
|||
// the position within @str where the URL was found.
|
||||
//
|
||||
// Return value: the list of match objects, as described above
|
||||
function findUrls(str) {
|
||||
export function findUrls(str) {
|
||||
let res = [], match;
|
||||
while ((match = _urlRegexp.exec(str)))
|
||||
res.push({ url: match[2], pos: match.index + match[1].length });
|
||||
|
|
@ -64,7 +70,7 @@ function findUrls(str) {
|
|||
//
|
||||
// Runs @argv in the background, handling any errors that occur
|
||||
// when trying to start the program.
|
||||
function spawn(argv) {
|
||||
export function spawn(argv) {
|
||||
try {
|
||||
trySpawn(argv);
|
||||
} catch (err) {
|
||||
|
|
@ -77,7 +83,7 @@ function spawn(argv) {
|
|||
//
|
||||
// Runs @commandLine in the background, handling any errors that
|
||||
// occur when trying to parse or start the program.
|
||||
function spawnCommandLine(commandLine) {
|
||||
export function spawnCommandLine(commandLine) {
|
||||
try {
|
||||
let [success_, argv] = GLib.shell_parse_argv(commandLine);
|
||||
trySpawn(argv);
|
||||
|
|
@ -90,7 +96,7 @@ function spawnCommandLine(commandLine) {
|
|||
// @argv: an argv array
|
||||
//
|
||||
// Runs @argv as if it was an application, handling startup notification
|
||||
function spawnApp(argv) {
|
||||
export function spawnApp(argv) {
|
||||
try {
|
||||
let app = Gio.AppInfo.create_from_commandline(argv.join(' '), null,
|
||||
Gio.AppInfoCreateFlags.SUPPORTS_STARTUP_NOTIFICATION);
|
||||
|
|
@ -108,7 +114,7 @@ function spawnApp(argv) {
|
|||
// Runs @argv in the background. If launching @argv fails,
|
||||
// this will throw an error.
|
||||
function trySpawn(argv) {
|
||||
var success_, pid;
|
||||
let success_, pid;
|
||||
try {
|
||||
[success_, pid] = GLib.spawn_async(null, argv, null,
|
||||
GLib.SpawnFlags.SEARCH_PATH | GLib.SpawnFlags.DO_NOT_REAP_CHILD,
|
||||
|
|
@ -145,7 +151,7 @@ function trySpawn(argv) {
|
|||
//
|
||||
// Runs @commandLine in the background. If launching @commandLine
|
||||
// fails, this will throw an error.
|
||||
function trySpawnCommandLine(commandLine) {
|
||||
export function trySpawnCommandLine(commandLine) {
|
||||
let success_, argv;
|
||||
|
||||
try {
|
||||
|
|
@ -165,7 +171,7 @@ function _handleSpawnError(command, err) {
|
|||
Main.notifyError(title, err.message);
|
||||
}
|
||||
|
||||
function formatTimeSpan(date) {
|
||||
export function formatTimeSpan(date) {
|
||||
let now = GLib.DateTime.new_now_local();
|
||||
|
||||
let timespan = now.difference(date);
|
||||
|
|
@ -205,7 +211,17 @@ function formatTimeSpan(date) {
|
|||
"%d years ago", yearsAgo).format(yearsAgo);
|
||||
}
|
||||
|
||||
function formatTime(time, params = {}) {
|
||||
/**
|
||||
* @typedef {object} FormatTimeProps
|
||||
* @property {boolean} timeOnly
|
||||
* @property {boolean} ampm
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {GLib.DateTime | Date} time
|
||||
* @param {Partial<FormatTimeProps>} params
|
||||
*/
|
||||
export function formatTime(time, params) {
|
||||
let date;
|
||||
// HACK: The built-in Date type sucks at timezones, which we need for the
|
||||
// world clock; it's often more convenient though, so allow either
|
||||
|
|
@ -300,7 +316,7 @@ function formatTime(time, params = {}) {
|
|||
return formattedTime.replace(/([:\u2236])/g, '\u200e$1');
|
||||
}
|
||||
|
||||
function createTimeLabel(date, params) {
|
||||
export function createTimeLabel(date, params) {
|
||||
if (_desktopSettings == null)
|
||||
_desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
||||
|
||||
|
|
@ -356,14 +372,14 @@ function lowerBound(array, val, cmp) {
|
|||
// Inserts @val into @array, preserving the
|
||||
// sorting invariants.
|
||||
// Returns the position at which it was inserted
|
||||
function insertSorted(array, val, cmp) {
|
||||
export function insertSorted(array, val, cmp) {
|
||||
let pos = lowerBound(array, val, cmp);
|
||||
array.splice(pos, 0, val);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
export function ensureActorVisibleInScrollView(scrollView, actor) {
|
||||
let adjustment = scrollView.vscroll.adjustment;
|
||||
let [value, lower_, upper, stepIncrement_, pageIncrement_, pageSize] = adjustment.get_values();
|
||||
|
||||
|
|
@ -399,7 +415,18 @@ function ensureActorVisibleInScrollView(scrollView, actor) {
|
|||
});
|
||||
}
|
||||
|
||||
function wiggle(actor, params = {}) {
|
||||
/**
|
||||
* @typedef {object} WiggleProps
|
||||
* @property {number} offset
|
||||
* @property {number} duration
|
||||
* @property {number} wiggleCount
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Clutter.Actor} actor
|
||||
* @param {Partial<WiggleProps>} [params]
|
||||
*/
|
||||
export function wiggle(actor, params = {}) {
|
||||
if (!St.Settings.get().enable_animations)
|
||||
return;
|
||||
|
||||
|
|
@ -436,7 +463,7 @@ function wiggle(actor, params = {}) {
|
|||
});
|
||||
}
|
||||
|
||||
function lerp(start, end, progress) {
|
||||
export function lerp(start, end, progress) {
|
||||
return start + progress * (end - start);
|
||||
}
|
||||
|
||||
|
|
@ -462,7 +489,7 @@ function _GNOMEversionToNumber(version) {
|
|||
//
|
||||
// Returns an integer less than, equal to, or greater than
|
||||
// zero, if version1 is older, equal or newer than version2
|
||||
function GNOMEversionCompare(version1, version2) {
|
||||
export function GNOMEversionCompare(version1, version2) {
|
||||
const v1Array = version1.split('.');
|
||||
const v2Array = version2.split('.');
|
||||
|
||||
|
|
@ -478,7 +505,7 @@ function GNOMEversionCompare(version1, version2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
var DBusSenderChecker = class {
|
||||
export class DBusSenderChecker {
|
||||
/**
|
||||
* @param {string[]} allowList - list of allowed well-known names
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,12 +1,16 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported WeatherClient */
|
||||
|
||||
const { Geoclue, Gio, GLib, GWeather, Shell } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Geoclue from 'gi://Geoclue';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GWeather from 'gi://GWeather';
|
||||
import Shell from 'gi://Shell';
|
||||
import * as Signals from './signals.js';
|
||||
|
||||
const PermissionStore = imports.misc.permissionStore;
|
||||
import * as PermissionStore from "./permissionStore.js";
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from "./fileUtilsModule.js";
|
||||
|
||||
Gio._promisify(Geoclue.Simple, 'new', 'new_finish');
|
||||
|
||||
|
|
@ -18,10 +22,11 @@ const WEATHER_INTEGRATION_IFACE = 'org.gnome.Shell.WeatherIntegration';
|
|||
|
||||
const WEATHER_APP_ID = 'org.gnome.Weather.desktop';
|
||||
|
||||
// Minimum time between updates to show loading indication
|
||||
var UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
|
||||
export let UPDATE_THRESHOLD = 10 * GLib.TIME_SPAN_MINUTE;
|
||||
|
||||
var WeatherClient = class extends Signals.EventEmitter {
|
||||
// Minimum time between updates to show loading indication
|
||||
|
||||
export class WeatherClient extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -293,7 +298,7 @@ var WeatherClient = class extends Signals.EventEmitter {
|
|||
}
|
||||
|
||||
_onLocationsChanged() {
|
||||
let locations = this._settings.get_value('locations').deep_unpack();
|
||||
let locations = /** @type {GLib.Variant<'av'>} */ (this._settings.get_value('locations')).deep_unpack();
|
||||
let serialized = locations.shift();
|
||||
let mostRecentLocation = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,16 @@
|
|||
*/
|
||||
/* eslint camelcase: ["error", { properties: "never", allow: ["^script_"] }] */
|
||||
|
||||
const { St } = imports.gi;
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Scripting = imports.ui.scripting;
|
||||
import Main from "../ui/main.js";
|
||||
|
||||
import * as MessageTray from "../ui/messageTray.js";
|
||||
import * as Scripting from "../ui/scripting.js";
|
||||
|
||||
// This script tests the most important (basic) functionality of the shell.
|
||||
|
||||
var METRICS = {};
|
||||
export const METRICS = {};
|
||||
|
||||
async function run() {
|
||||
/* eslint-disable no-await-in-loop */
|
||||
|
|
|
|||
|
|
@ -5,17 +5,17 @@
|
|||
clutter_stagePaintDone */
|
||||
/* eslint camelcase: ["error", { properties: "never", allow: ["^script_", "^malloc", "^glx", "^clutter"] }] */
|
||||
|
||||
const System = imports.system;
|
||||
import System from 'system';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const Scripting = imports.ui.scripting;
|
||||
import Main from "../ui/main.js";
|
||||
import * as Scripting from "../ui/scripting.js";
|
||||
|
||||
// This performance script measure the most important (core) performance
|
||||
// metrics for the shell. By looking at the output metrics of this script
|
||||
// someone should be able to get an idea of how well the shell is performing
|
||||
// on a particular system.
|
||||
|
||||
var METRICS = {
|
||||
export const METRICS = {
|
||||
overviewLatencyFirst:
|
||||
{ description: "Time to first frame after triggering overview, first time",
|
||||
units: "us" },
|
||||
|
|
|
|||
|
|
@ -7,11 +7,14 @@
|
|||
script_geditLaunch, script_geditFirstFrame,
|
||||
clutter_stagePaintStart, clutter_paintCompletedTimestamp */
|
||||
/* eslint camelcase: ["error", { properties: "never", allow: ["^script_", "^clutter"] }] */
|
||||
const { Clutter, Gio, Shell } = imports.gi;
|
||||
const Main = imports.ui.main;
|
||||
const Scripting = imports.ui.scripting;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import Shell from 'gi://Shell';
|
||||
|
||||
var METRICS = {
|
||||
import Main from "../ui/main.js";
|
||||
import * as Scripting from "../ui/scripting.js";
|
||||
|
||||
export const METRICS = {
|
||||
timeToDesktop:
|
||||
{ description: "Time from starting graphical.target to desktop showing",
|
||||
units: "us" },
|
||||
|
|
|
|||
|
|
@ -1,22 +1,29 @@
|
|||
/* exported AccessDialogDBus */
|
||||
const { Clutter, Gio, GLib, GObject, 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 Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import * as CheckBox from './checkBox.js';
|
||||
import * as Dialog from './dialog.js';
|
||||
import * as ModalDialog from './modalDialog.js';
|
||||
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
const RequestIface = loadInterfaceXML('org.freedesktop.impl.portal.Request');
|
||||
const AccessIface = loadInterfaceXML('org.freedesktop.impl.portal.Access');
|
||||
|
||||
var DialogResponse = {
|
||||
/** @enum {number} */
|
||||
export const DialogResponse = {
|
||||
OK: 0,
|
||||
CANCEL: 1,
|
||||
CLOSED: 2,
|
||||
};
|
||||
|
||||
var AccessDialog = GObject.registerClass(
|
||||
export const AccessDialog = GObject.registerClass(
|
||||
class AccessDialog extends ModalDialog.ModalDialog {
|
||||
_init(invocation, handle, title, description, body, options) {
|
||||
super._init({ styleClass: 'access-dialog' });
|
||||
|
|
@ -100,6 +107,7 @@ class AccessDialog extends ModalDialog.ModalDialog {
|
|||
this._request.unexport();
|
||||
this._requestExported = false;
|
||||
|
||||
/** @type {{ [key: string]: GLib.Variant<'s'> }} */
|
||||
let results = {};
|
||||
if (response == DialogResponse.OK) {
|
||||
for (let [id, check] of this._choices) {
|
||||
|
|
@ -117,7 +125,7 @@ class AccessDialog extends ModalDialog.ModalDialog {
|
|||
}
|
||||
});
|
||||
|
||||
var AccessDialogDBus = class {
|
||||
export class AccessDialogDBus {
|
||||
constructor() {
|
||||
this._accessDialog = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,24 +2,33 @@
|
|||
/* exported AppSwitcherPopup, GroupCyclerPopup, WindowSwitcherPopup,
|
||||
WindowCyclerPopup */
|
||||
|
||||
const { Atk, Clutter, Gio, GLib, GObject, 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 GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const SwitcherPopup = imports.ui.switcherPopup;
|
||||
|
||||
var APP_ICON_HOVER_TIMEOUT = 200; // milliseconds
|
||||
import Main from './main.js';
|
||||
import * as SwitcherPopup from './switcherPopup.js';
|
||||
|
||||
var THUMBNAIL_DEFAULT_SIZE = 256;
|
||||
var THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||
var THUMBNAIL_FADE_TIME = 100; // milliseconds
|
||||
export let APP_ICON_HOVER_TIMEOUT = 200; // milliseconds
|
||||
|
||||
var WINDOW_PREVIEW_SIZE = 128;
|
||||
var APP_ICON_SIZE = 96;
|
||||
var APP_ICON_SIZE_SMALL = 48;
|
||||
export let THUMBNAIL_DEFAULT_SIZE = 256;
|
||||
export let THUMBNAIL_POPUP_TIME = 500; // milliseconds
|
||||
export let THUMBNAIL_FADE_TIME = 100; // milliseconds
|
||||
|
||||
export let WINDOW_PREVIEW_SIZE = 128;
|
||||
export let APP_ICON_SIZE = 96;
|
||||
export let APP_ICON_SIZE_SMALL = 48;
|
||||
|
||||
const baseIconSizes = [96, 64, 48, 32, 22];
|
||||
|
||||
var AppIconMode = {
|
||||
/** @enum {number} */
|
||||
export const AppIconMode = {
|
||||
THUMBNAIL_ONLY: 1,
|
||||
APP_ICON_ONLY: 2,
|
||||
BOTH: 3,
|
||||
|
|
@ -38,7 +47,7 @@ function _createWindowClone(window, size) {
|
|||
y_expand: true });
|
||||
}
|
||||
|
||||
function getWindows(workspace) {
|
||||
export function getWindows(workspace) {
|
||||
// We ignore skip-taskbar windows in switchers, but if they are attached
|
||||
// to their parent, their position in the MRU list may be more appropriate
|
||||
// than the parent; so start with the complete list ...
|
||||
|
|
@ -51,7 +60,7 @@ function getWindows(workspace) {
|
|||
}).filter((w, i, a) => !w.skip_taskbar && a.indexOf(w) == i);
|
||||
}
|
||||
|
||||
var AppSwitcherPopup = GObject.registerClass(
|
||||
export const AppSwitcherPopup = GObject.registerClass(
|
||||
class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -290,8 +299,8 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
|||
/**
|
||||
* _select:
|
||||
* @param {number} app: index of the app to select
|
||||
* @param {number=} window: index of which of @app's windows to select
|
||||
* @param {bool} forceAppFocus: optional flag, see below
|
||||
* @param {number} [window]: index of which of @app's windows to select
|
||||
* @param {boolean} [forceAppFocus]: optional flag, see below
|
||||
*
|
||||
* Selects the indicated @app, and optional @window, and sets
|
||||
* this._thumbnailsFocused appropriately to indicate whether the
|
||||
|
|
@ -397,13 +406,14 @@ class AppSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
|||
}
|
||||
});
|
||||
|
||||
var CyclerHighlight = GObject.registerClass(
|
||||
export const CyclerHighlight = GObject.registerClass(
|
||||
class CyclerHighlight extends St.Widget {
|
||||
_init() {
|
||||
super._init({ layout_manager: new Clutter.BinLayout() });
|
||||
this._window = null;
|
||||
this._sizeChangedId = 0;
|
||||
|
||||
/** @type {Clutter.Clone<Meta.WindowActor>} */
|
||||
this._clone = new Clutter.Clone();
|
||||
this.add_actor(this._clone);
|
||||
|
||||
|
|
@ -465,7 +475,7 @@ class CyclerHighlight extends St.Widget {
|
|||
|
||||
// We don't show an actual popup, so just provide what SwitcherPopup
|
||||
// expects instead of inheriting from SwitcherList
|
||||
var CyclerList = GObject.registerClass({
|
||||
export const CyclerList = GObject.registerClass({
|
||||
Signals: { 'item-activated': { param_types: [GObject.TYPE_INT] },
|
||||
'item-entered': { param_types: [GObject.TYPE_INT] },
|
||||
'item-removed': { param_types: [GObject.TYPE_INT] },
|
||||
|
|
@ -476,7 +486,7 @@ var CyclerList = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var CyclerPopup = GObject.registerClass({
|
||||
export const CyclerPopup = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT,
|
||||
}, class CyclerPopup extends SwitcherPopup.SwitcherPopup {
|
||||
_init() {
|
||||
|
|
@ -493,6 +503,13 @@ var CyclerPopup = GObject.registerClass({
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Meta.Window[]}
|
||||
*/
|
||||
_getWindows() {
|
||||
throw new GObject.NotImplementedError(`_getWindows in ${this.constructor.name}`);
|
||||
}
|
||||
|
||||
_highlightItem(index, _justOutline) {
|
||||
this._highlight.window = this._items[index];
|
||||
global.window_group.set_child_above_sibling(this._highlight, null);
|
||||
|
|
@ -532,7 +549,7 @@ var CyclerPopup = GObject.registerClass({
|
|||
});
|
||||
|
||||
|
||||
var GroupCyclerPopup = GObject.registerClass(
|
||||
export const GroupCyclerPopup = GObject.registerClass(
|
||||
class GroupCyclerPopup extends CyclerPopup {
|
||||
_init() {
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.app-switcher' });
|
||||
|
|
@ -565,7 +582,7 @@ class GroupCyclerPopup extends CyclerPopup {
|
|||
}
|
||||
});
|
||||
|
||||
var WindowSwitcherPopup = GObject.registerClass(
|
||||
export const WindowSwitcherPopup = GObject.registerClass(
|
||||
class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -623,7 +640,7 @@ class WindowSwitcherPopup extends SwitcherPopup.SwitcherPopup {
|
|||
}
|
||||
});
|
||||
|
||||
var WindowCyclerPopup = GObject.registerClass(
|
||||
export const WindowCyclerPopup = GObject.registerClass(
|
||||
class WindowCyclerPopup extends CyclerPopup {
|
||||
_init() {
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.shell.window-switcher' });
|
||||
|
|
@ -654,12 +671,15 @@ class WindowCyclerPopup extends CyclerPopup {
|
|||
}
|
||||
});
|
||||
|
||||
var AppIcon = GObject.registerClass(
|
||||
export const AppIcon = GObject.registerClass(
|
||||
class AppIcon extends St.BoxLayout {
|
||||
_init(app) {
|
||||
super._init({ style_class: 'alt-tab-app',
|
||||
vertical: true });
|
||||
|
||||
/** @type {Meta.Window[]} */
|
||||
this.cachedWindows = [];
|
||||
|
||||
this.app = app;
|
||||
this.icon = null;
|
||||
this._iconBin = new St.Bin();
|
||||
|
|
@ -679,7 +699,7 @@ class AppIcon extends St.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var AppSwitcher = GObject.registerClass(
|
||||
export const AppSwitcher = GObject.registerClass(
|
||||
class AppSwitcher extends SwitcherPopup.SwitcherList {
|
||||
_init(apps, altTabPopup) {
|
||||
super._init(true);
|
||||
|
|
@ -814,6 +834,8 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
|
|||
} else {
|
||||
this._itemEntered(index);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_enterItem(index) {
|
||||
|
|
@ -884,7 +906,7 @@ class AppSwitcher extends SwitcherPopup.SwitcherList {
|
|||
}
|
||||
});
|
||||
|
||||
var ThumbnailSwitcher = GObject.registerClass(
|
||||
export const ThumbnailSwitcher = GObject.registerClass(
|
||||
class ThumbnailSwitcher extends SwitcherPopup.SwitcherList {
|
||||
_init(windows) {
|
||||
super._init(false);
|
||||
|
|
@ -892,6 +914,7 @@ class ThumbnailSwitcher extends SwitcherPopup.SwitcherList {
|
|||
this._labels = [];
|
||||
this._thumbnailBins = [];
|
||||
this._clones = [];
|
||||
/** @type {Meta.Window[]} */
|
||||
this._windows = windows;
|
||||
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
|
|
@ -979,7 +1002,7 @@ class ThumbnailSwitcher extends SwitcherPopup.SwitcherList {
|
|||
}
|
||||
});
|
||||
|
||||
var WindowIcon = GObject.registerClass(
|
||||
export const WindowIcon = GObject.registerClass(
|
||||
class WindowIcon extends St.BoxLayout {
|
||||
_init(window, mode) {
|
||||
super._init({ style_class: 'alt-tab-app',
|
||||
|
|
@ -987,6 +1010,8 @@ class WindowIcon extends St.BoxLayout {
|
|||
|
||||
this.window = window;
|
||||
|
||||
this._unmanagedSignalId = -1;
|
||||
|
||||
this._icon = new St.Widget({ layout_manager: new Clutter.BinLayout() });
|
||||
|
||||
this.add_child(this._icon);
|
||||
|
|
@ -1037,7 +1062,7 @@ class WindowIcon extends St.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var WindowSwitcher = GObject.registerClass(
|
||||
export const WindowSwitcher = GObject.registerClass(
|
||||
class WindowSwitcher extends SwitcherPopup.SwitcherList {
|
||||
_init(windows, mode) {
|
||||
super._init(true);
|
||||
|
|
@ -1070,6 +1095,9 @@ class WindowSwitcher extends SwitcherPopup.SwitcherList {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let [minHeight, natHeight] = super.vfunc_get_preferred_height(forWidth);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,26 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Animation, AnimatedIcon, Spinner */
|
||||
|
||||
const { Clutter, GLib, GObject, Gio, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Gio from 'gi://Gio';
|
||||
import St from 'gi://St';
|
||||
|
||||
|
||||
var ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
||||
var SPINNER_ANIMATION_TIME = 300;
|
||||
var SPINNER_ANIMATION_DELAY = 1000;
|
||||
export let ANIMATED_ICON_UPDATE_TIMEOUT = 16;
|
||||
export let SPINNER_ANIMATION_TIME = 300;
|
||||
export let SPINNER_ANIMATION_DELAY = 1000;
|
||||
|
||||
var Animation = GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} AnimationParams
|
||||
* @property {Gio.File} file
|
||||
* @property {number} width
|
||||
* @property {number} height
|
||||
* @property {number} speed
|
||||
*/
|
||||
|
||||
export const Animation = GObject.registerClass(
|
||||
class Animation extends St.Bin {
|
||||
_init(file, width, height, speed) {
|
||||
const themeContext = St.ThemeContext.get_for_stage(global.stage);
|
||||
|
|
@ -129,15 +141,26 @@ class Animation extends St.Bin {
|
|||
}
|
||||
});
|
||||
|
||||
var AnimatedIcon = GObject.registerClass(
|
||||
export const AnimatedIcon = GObject.registerClass(
|
||||
class AnimatedIcon extends Animation {
|
||||
_init(file, size) {
|
||||
super._init(file, size, size, ANIMATED_ICON_UPDATE_TIMEOUT);
|
||||
}
|
||||
});
|
||||
|
||||
var Spinner = GObject.registerClass(
|
||||
export const Spinner = GObject.registerClass(
|
||||
class Spinner extends AnimatedIcon {
|
||||
/**
|
||||
* @typedef {object} SpinnerParams
|
||||
* @property {boolean} [animate]
|
||||
* @property {boolean} [hideOnStop]
|
||||
*/
|
||||
|
||||
/**
|
||||
* _init:
|
||||
* @param {number} size
|
||||
* @param {SpinnerParams} [params]
|
||||
*/
|
||||
_init(size, params = {}) {
|
||||
const {
|
||||
animate = false,
|
||||
|
|
|
|||
|
|
@ -1,39 +1,45 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported AppDisplay, AppSearchProvider */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Graphene, Meta,
|
||||
Pango, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Gio from 'gi://Gio';
|
||||
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const { AppMenu } = imports.ui.appMenu;
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const DND = imports.ui.dnd;
|
||||
const GrabHelper = imports.ui.grabHelper;
|
||||
const IconGrid = imports.ui.iconGrid;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const PageIndicators = imports.ui.pageIndicators;
|
||||
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Search = imports.ui.search;
|
||||
const SwipeTracker = imports.ui.swipeTracker;
|
||||
const SystemActions = imports.misc.systemActions;
|
||||
import Graphene from 'gi://Graphene';
|
||||
import Pango from 'gi://Pango';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
var MENU_POPUP_TIMEOUT = 600;
|
||||
var POPDOWN_DIALOG_TIMEOUT = 500;
|
||||
import * as AppFavorites from './appFavorites.js';
|
||||
import * as DND from './dnd.js';
|
||||
import * as GrabHelper from './grabHelper.js';
|
||||
import * as IconGrid from './iconGrid.js';
|
||||
import * as Layout from './layout.js';
|
||||
import Main from './main.js';
|
||||
import * as PageIndicators from './pageIndicators.js';
|
||||
import * as ParentalControlsManager from '../misc/parentalControlsManager.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
import * as Search from './search.js';
|
||||
import * as SwipeTracker from './swipeTracker.js';
|
||||
import * as SystemActions from '../misc/systemActions.js';
|
||||
|
||||
var FOLDER_SUBICON_FRACTION = .4;
|
||||
export const MENU_POPUP_TIMEOUT = 600;
|
||||
export const POPDOWN_DIALOG_TIMEOUT = 500;
|
||||
|
||||
var VIEWS_SWITCH_TIME = 400;
|
||||
var VIEWS_SWITCH_ANIMATION_DELAY = 100;
|
||||
export const FOLDER_SUBICON_FRACTION = .4;
|
||||
|
||||
var SCROLL_TIMEOUT_TIME = 150;
|
||||
export const VIEWS_SWITCH_TIME = 400;
|
||||
export const VIEWS_SWITCH_ANIMATION_DELAY = 100;
|
||||
|
||||
var APP_ICON_SCALE_IN_TIME = 500;
|
||||
var APP_ICON_SCALE_IN_DELAY = 700;
|
||||
export const SCROLL_TIMEOUT_TIME = 150;
|
||||
|
||||
var APP_ICON_TITLE_EXPAND_TIME = 200;
|
||||
var APP_ICON_TITLE_COLLAPSE_TIME = 100;
|
||||
export const APP_ICON_SCALE_IN_TIME = 500;
|
||||
export const APP_ICON_SCALE_IN_DELAY = 700;
|
||||
|
||||
export const APP_ICON_TITLE_EXPAND_TIME = 200;
|
||||
export const APP_ICON_TITLE_COLLAPSE_TIME = 100;
|
||||
|
||||
const FOLDER_DIALOG_ANIMATION_TIME = 200;
|
||||
|
||||
|
|
@ -86,14 +92,9 @@ function _getFolderName(folder) {
|
|||
return name;
|
||||
}
|
||||
|
||||
function _getViewFromIcon(icon) {
|
||||
for (let parent = icon.get_parent(); parent; parent = parent.get_parent()) {
|
||||
if (parent instanceof BaseAppView)
|
||||
return parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {readonly Shell.App[]} apps
|
||||
*/
|
||||
function _findBestFolderName(apps) {
|
||||
let appInfos = apps.map(app => app.get_app_info());
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ function _findBestFolderName(apps) {
|
|||
return null;
|
||||
}
|
||||
|
||||
var BaseAppView = GObject.registerClass({
|
||||
export const BaseAppView = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT,
|
||||
Properties: {
|
||||
'gesture-modes': GObject.ParamSpec.flags(
|
||||
|
|
@ -283,8 +284,9 @@ var BaseAppView = GObject.registerClass({
|
|||
this._box.add_child(this._pageIndicators);
|
||||
|
||||
// Swipe
|
||||
// FIXME
|
||||
this._swipeTracker = new SwipeTracker.SwipeTracker(this._scrollView,
|
||||
Clutter.Orientation.HORIZONTAL, this.gestureModes);
|
||||
Clutter.Orientation.HORIZONTAL);
|
||||
this._swipeTracker.orientation = Clutter.Orientation.HORIZONTAL;
|
||||
this._swipeTracker.connect('begin', this._swipeBegin.bind(this));
|
||||
this._swipeTracker.connect('update', this._swipeUpdate.bind(this));
|
||||
|
|
@ -395,7 +397,7 @@ var BaseAppView = GObject.registerClass({
|
|||
if (hOffset === 0 && vOffset === 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
this._scrollView.update_fade_effect(
|
||||
new Clutter.Margin({
|
||||
left: hOffset,
|
||||
|
|
@ -725,7 +727,7 @@ var BaseAppView = GObject.registerClass({
|
|||
this._swipeTracker.enabled = true;
|
||||
}
|
||||
|
||||
_onDragCancelled() {
|
||||
_onDragCancelled(overview, source) {
|
||||
// At this point, the positions aren't stored yet, thus _redisplay()
|
||||
// will move all items to their original positions
|
||||
this._redisplay();
|
||||
|
|
@ -832,6 +834,13 @@ var BaseAppView = GObject.registerClass({
|
|||
return [page, position];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {AppViewItem["prototype"][]}
|
||||
*/
|
||||
_loadApps() {
|
||||
throw new GObject.NotImplementedError(`_loadApps in ${this.constructor.name}`);
|
||||
}
|
||||
|
||||
_redisplay() {
|
||||
let oldApps = this._orderedItems.slice();
|
||||
let oldAppIds = oldApps.map(icon => icon.id);
|
||||
|
|
@ -1348,7 +1357,7 @@ var BaseAppView = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var PageManager = GObject.registerClass({
|
||||
export const PageManager = GObject.registerClass({
|
||||
Signals: { 'layout-changed': {} },
|
||||
}, class PageManager extends GObject.Object {
|
||||
_init() {
|
||||
|
|
@ -1362,8 +1371,10 @@ var PageManager = GObject.registerClass({
|
|||
}
|
||||
|
||||
_loadPages() {
|
||||
/** @type {GLib.Variant<'aa{sv}'>} */
|
||||
const layout = global.settings.get_value('app-picker-layout');
|
||||
this._pages = layout.recursiveUnpack();
|
||||
/** @type { { [key: string]: { [key: string]: number } }[] } */
|
||||
this._pages = (layout.recursiveUnpack());
|
||||
if (!this._updatingPages)
|
||||
this.emit('layout-changed');
|
||||
}
|
||||
|
|
@ -1385,11 +1396,16 @@ var PageManager = GObject.registerClass({
|
|||
return [page, position];
|
||||
}
|
||||
|
||||
set pages(p) {
|
||||
/**
|
||||
* @param {{ [key: string]: { [key: string]: GLib.Variant<'i'> } }[]} p
|
||||
*/
|
||||
updatePages(p) {
|
||||
/** @type {{ [key: string]: GLib.Variant<'a{sv}'> }[]} */
|
||||
const packedPages = [];
|
||||
|
||||
// Pack the icon properties as a GVariant
|
||||
for (const page of p) {
|
||||
/** @type {{ [key: string]: GLib.Variant<'a{sv}'> }} */
|
||||
const pageData = {};
|
||||
for (const [appId, properties] of Object.entries(page))
|
||||
pageData[appId] = new GLib.Variant('a{sv}', properties);
|
||||
|
|
@ -1409,7 +1425,7 @@ var PageManager = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var AppDisplay = GObject.registerClass(
|
||||
export const AppDisplay = GObject.registerClass(
|
||||
class AppDisplay extends BaseAppView {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -1493,11 +1509,13 @@ class AppDisplay extends BaseAppView {
|
|||
}
|
||||
|
||||
_savePages() {
|
||||
/** @type {{ [key: string]: { [key: string]: GLib.Variant<'i'> } }[]} */
|
||||
const pages = [];
|
||||
|
||||
for (let i = 0; i < this._grid.nPages; i++) {
|
||||
const pageItems =
|
||||
this._grid.getItemsAtPage(i).filter(c => c.visible);
|
||||
/** @type {{ [key: string]: { [key: string]: GLib.Variant<'i'> } }} */
|
||||
const pageData = {};
|
||||
|
||||
pageItems.forEach((item, index) => {
|
||||
|
|
@ -1508,7 +1526,7 @@ class AppDisplay extends BaseAppView {
|
|||
pages.push(pageData);
|
||||
}
|
||||
|
||||
this._pageManager.pages = pages;
|
||||
this._pageManager.updatePages(pages);
|
||||
}
|
||||
|
||||
_ensurePlaceholder(source) {
|
||||
|
|
@ -1752,8 +1770,8 @@ class AppDisplay extends BaseAppView {
|
|||
super._maybeMoveItem(clonedEvent);
|
||||
}
|
||||
|
||||
_onDragBegin(overview, source) {
|
||||
super._onDragBegin(overview, source);
|
||||
_onDragBegin(_overview, source) {
|
||||
super._onDragBegin();
|
||||
|
||||
// When dragging from a folder dialog, the dragged app icon doesn't
|
||||
// exist in AppDisplay. We work around that by adding a placeholder
|
||||
|
|
@ -1778,7 +1796,7 @@ class AppDisplay extends BaseAppView {
|
|||
}
|
||||
|
||||
_onDragCancelled(overview, source) {
|
||||
const view = _getViewFromIcon(source);
|
||||
const view = source._getView();
|
||||
|
||||
if (view instanceof FolderView)
|
||||
return;
|
||||
|
|
@ -1792,7 +1810,7 @@ class AppDisplay extends BaseAppView {
|
|||
|
||||
this._savePages();
|
||||
|
||||
let view = _getViewFromIcon(source);
|
||||
let view = source._getView();
|
||||
if (view instanceof FolderView)
|
||||
view.removeApp(source.app);
|
||||
|
||||
|
|
@ -1860,7 +1878,7 @@ class AppDisplay extends BaseAppView {
|
|||
}
|
||||
});
|
||||
|
||||
var AppSearchProvider = class AppSearchProvider {
|
||||
export class AppSearchProvider {
|
||||
constructor() {
|
||||
this._appSys = Shell.AppSystem.get_default();
|
||||
this.id = 'applications';
|
||||
|
|
@ -1953,17 +1971,38 @@ var AppSearchProvider = class AppSearchProvider {
|
|||
}
|
||||
};
|
||||
|
||||
var AppViewItem = GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} ViewParams
|
||||
* @property {boolean} [isDraggable]
|
||||
* @property {boolean} [expandTitleOnHover]
|
||||
*/
|
||||
|
||||
export const AppViewItem = GObject.registerClass(
|
||||
class AppViewItem extends St.Button {
|
||||
_init(params = {}, isDraggable = true, expandTitleOnHover = true) {
|
||||
/**
|
||||
* @param {Partial<St.Button.ConstructorProperties> & ViewParams} [params]
|
||||
* @param {...any} _args
|
||||
*/
|
||||
_init(params = {}, ..._args) {
|
||||
const {
|
||||
isDraggable = true,
|
||||
expandTitleOnHover = true,
|
||||
...buttonParams
|
||||
} = params;
|
||||
|
||||
super._init({
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||
reactive: true,
|
||||
button_mask: St.ButtonMask.ONE | St.ButtonMask.TWO,
|
||||
can_focus: true,
|
||||
...params,
|
||||
...buttonParams,
|
||||
});
|
||||
|
||||
this._name = '';
|
||||
this._id = '';
|
||||
/** @type {IconGrid.BaseIcon["prototype"] | null} */
|
||||
this.icon = null;
|
||||
|
||||
this._delegate = this;
|
||||
|
||||
if (isDraggable) {
|
||||
|
|
@ -2162,7 +2201,7 @@ class AppViewItem extends St.Button {
|
|||
}
|
||||
});
|
||||
|
||||
var FolderGrid = GObject.registerClass(
|
||||
export const FolderGrid = GObject.registerClass(
|
||||
class FolderGrid extends IconGrid.IconGrid {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -2179,7 +2218,14 @@ class FolderGrid extends IconGrid.IconGrid {
|
|||
}
|
||||
});
|
||||
|
||||
var FolderView = GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} FolderViewParams
|
||||
* @property {import('gi://Gio').Settings} folder
|
||||
* @property {string} id
|
||||
* @property {*} parentView
|
||||
*/
|
||||
|
||||
export const FolderView = GObject.registerClass(
|
||||
class FolderView extends BaseAppView {
|
||||
_init(folder, id, parentView) {
|
||||
super._init({
|
||||
|
|
@ -2411,7 +2457,7 @@ class FolderView extends BaseAppView {
|
|||
}
|
||||
});
|
||||
|
||||
var FolderIcon = GObject.registerClass({
|
||||
export const FolderIcon = GObject.registerClass({
|
||||
Signals: {
|
||||
'apps-changed': {},
|
||||
},
|
||||
|
|
@ -2519,7 +2565,7 @@ var FolderIcon = GObject.registerClass({
|
|||
if (!(source instanceof AppIcon))
|
||||
return false;
|
||||
|
||||
let view = _getViewFromIcon(source);
|
||||
let view = source._getView();
|
||||
if (!view || !(view instanceof AppDisplay))
|
||||
return false;
|
||||
|
||||
|
|
@ -2590,7 +2636,7 @@ var FolderIcon = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var AppFolderDialog = GObject.registerClass({
|
||||
export const AppFolderDialog = GObject.registerClass({
|
||||
Signals: {
|
||||
'open-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
|
||||
},
|
||||
|
|
@ -3079,15 +3125,22 @@ var AppFolderDialog = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var AppIcon = GObject.registerClass({
|
||||
/**
|
||||
* @typedef {ViewParams} AppIconParams */
|
||||
|
||||
export const AppIcon = GObject.registerClass({
|
||||
Signals: {
|
||||
'menu-state-changed': { param_types: [GObject.TYPE_BOOLEAN] },
|
||||
'sync-tooltip': {},
|
||||
},
|
||||
}, class AppIcon extends AppViewItem {
|
||||
_init(app, iconParams = {}) {
|
||||
/**
|
||||
* @param {Shell.App} app
|
||||
* @param {AppIconParams} params
|
||||
*/
|
||||
_init(app, params = {}) {
|
||||
// Get the isDraggable property without passing it on to the BaseIcon:
|
||||
const { isDraggable = true, expandTitleOnHover } = iconParams;
|
||||
const { isDraggable = true, expandTitleOnHover } = params;
|
||||
|
||||
super._init({ style_class: 'app-well-app' }, isDraggable, expandTitleOnHover);
|
||||
|
||||
|
|
@ -3102,8 +3155,11 @@ var AppIcon = GObject.registerClass({
|
|||
|
||||
this._folderPreviewId = 0;
|
||||
|
||||
iconParams['createIcon'] = this._createIcon.bind(this);
|
||||
iconParams['setSizeManually'] = true;
|
||||
const iconParams = {
|
||||
...params,
|
||||
createIcon: this._createIcon.bind(this),
|
||||
setSizeManually: true,
|
||||
};
|
||||
this.icon = new IconGrid.BaseIcon(app.get_name(), iconParams);
|
||||
this._iconContainer.add_child(this.icon);
|
||||
|
||||
|
|
@ -3292,6 +3348,15 @@ var AppIcon = GObject.registerClass({
|
|||
this.icon.animateZoomOutAtPos(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} WorkspaceLaunchParams
|
||||
* @property {number} workspace
|
||||
* @property {number} timestamp
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Partial<WorkspaceLaunchParams>} params
|
||||
*/
|
||||
shellWorkspaceLaunch(params = {}) {
|
||||
let { stack } = new Error();
|
||||
log('shellWorkspaceLaunch is deprecated, use app.open_new_window() instead\n%s'.format(stack));
|
||||
|
|
@ -3332,7 +3397,7 @@ var AppIcon = GObject.registerClass({
|
|||
}
|
||||
|
||||
_canAccept(source) {
|
||||
let view = _getViewFromIcon(source);
|
||||
let view = source._getView();
|
||||
|
||||
return source != this &&
|
||||
(source instanceof this.constructor) &&
|
||||
|
|
@ -3366,12 +3431,20 @@ var AppIcon = GObject.registerClass({
|
|||
}
|
||||
}
|
||||
|
||||
_getView() {
|
||||
for (let parent = this.get_parent(); parent; parent = parent.get_parent()) {
|
||||
if (parent instanceof BaseAppView)
|
||||
return parent;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
acceptDrop(source, actor, x) {
|
||||
const accepted = super.acceptDrop(source, actor, x);
|
||||
if (!accepted)
|
||||
return false;
|
||||
|
||||
let view = _getViewFromIcon(this);
|
||||
let view = this._getView();
|
||||
let apps = [this.id, source.id];
|
||||
|
||||
return view?.createFolder(apps);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getAppFavorites */
|
||||
|
||||
const Shell = imports.gi.Shell;
|
||||
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
||||
const Signals = imports.misc.signals;
|
||||
import Shell from 'gi://Shell';
|
||||
import * as ParentalControlsManager from '../misc/parentalControlsManager.js';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
import Main from './main.js';
|
||||
|
||||
// In alphabetical order
|
||||
const RENAMED_DESKTOP_IDS = {
|
||||
|
|
@ -204,8 +204,8 @@ class AppFavorites extends Signals.EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
var appFavoritesInstance = null;
|
||||
function getAppFavorites() {
|
||||
let appFavoritesInstance = null;
|
||||
export function getAppFavorites() {
|
||||
if (appFavoritesInstance == null)
|
||||
appFavoritesInstance = new AppFavorites();
|
||||
return appFavoritesInstance;
|
||||
|
|
|
|||
|
|
@ -2,12 +2,12 @@
|
|||
/* exported AppMenu */
|
||||
const { Clutter, Gio, GLib, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const Main = imports.ui.main;
|
||||
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
import * as AppFavorites from './appFavorites.js';
|
||||
import Main from './main.js';
|
||||
import * as ParentalControlsManager from '../misc/parentalControlsManager.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
|
||||
var AppMenu = class AppMenu extends PopupMenu.PopupMenu {
|
||||
export class AppMenu extends PopupMenu.PopupMenu {
|
||||
/**
|
||||
* @param {Clutter.Actor} sourceActor - actor the menu is attached to
|
||||
* @param {St.Side} side - arrow side
|
||||
|
|
|
|||
|
|
@ -1,13 +1,20 @@
|
|||
/* exported AudioDeviceSelectionDBus */
|
||||
const { Clutter, Gio, GLib, GObject, 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 Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import * as Dialog from './dialog.js';
|
||||
import Main from './main.js';
|
||||
import * as ModalDialog from './modalDialog.js';
|
||||
|
||||
var AudioDevice = {
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
export const AudioDevice = {
|
||||
HEADPHONES: 1 << 0,
|
||||
HEADSET: 1 << 1,
|
||||
MICROPHONE: 1 << 2,
|
||||
|
|
@ -15,14 +22,20 @@ var AudioDevice = {
|
|||
|
||||
const AudioDeviceSelectionIface = loadInterfaceXML('org.gnome.Shell.AudioDeviceSelection');
|
||||
|
||||
var AudioDeviceSelectionDialog = GObject.registerClass({
|
||||
export const AudioDeviceSelectionDialog = GObject.registerClass({
|
||||
Signals: { 'device-selected': { param_types: [GObject.TYPE_UINT] } },
|
||||
}, class AudioDeviceSelectionDialog extends ModalDialog.ModalDialog {
|
||||
/**
|
||||
* @param {*} devices
|
||||
*/
|
||||
_init(devices) {
|
||||
super._init({ styleClass: 'audio-device-selection-dialog' });
|
||||
|
||||
this._deviceItems = {};
|
||||
|
||||
/** @type {string} */
|
||||
this._sender = null;
|
||||
|
||||
this._buildLayout();
|
||||
|
||||
if (devices & AudioDevice.HEADPHONES)
|
||||
|
|
@ -135,7 +148,7 @@ var AudioDeviceSelectionDialog = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var AudioDeviceSelectionDBus = class AudioDeviceSelectionDBus {
|
||||
export class AudioDeviceSelectionDBus {
|
||||
constructor() {
|
||||
this._audioSelectionDialog = null;
|
||||
|
||||
|
|
|
|||
|
|
@ -94,15 +94,22 @@
|
|||
// MetaBackgroundImage MetaBackgroundImage
|
||||
// MetaBackgroundImage MetaBackgroundImage
|
||||
|
||||
const { Clutter, GDesktopEnums, Gio, GLib, GObject, GnomeDesktop, Meta } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GDesktopEnums from 'gi://GDesktopEnums';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import GnomeDesktop from 'gi://GnomeDesktop';
|
||||
import Meta from 'gi://Meta';
|
||||
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const Main = imports.ui.main;
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
import * as LoginManager from '../misc/loginManager.js';
|
||||
import Main from './main.js';
|
||||
|
||||
Gio._promisify(Gio._LocalFilePrototype, 'query_info_async', 'query_info_finish');
|
||||
|
||||
var DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
||||
export const DEFAULT_BACKGROUND_COLOR = Clutter.Color.from_pixel(0x2e3436ff);
|
||||
|
||||
const BACKGROUND_SCHEMA = 'org.gnome.desktop.background';
|
||||
const PRIMARY_COLOR_KEY = 'primary-color';
|
||||
|
|
@ -111,14 +118,14 @@ const COLOR_SHADING_TYPE_KEY = 'color-shading-type';
|
|||
const BACKGROUND_STYLE_KEY = 'picture-options';
|
||||
const PICTURE_URI_KEY = 'picture-uri';
|
||||
|
||||
var FADE_ANIMATION_TIME = 1000;
|
||||
export let FADE_ANIMATION_TIME = 1000;
|
||||
|
||||
// These parameters affect how often we redraw.
|
||||
// The first is how different (percent crossfaded) the slide show
|
||||
// has to look before redrawing and the second is the minimum
|
||||
// frequency (in seconds) we're willing to wake up
|
||||
var ANIMATION_OPACITY_STEP_INCREMENT = 4.0;
|
||||
var ANIMATION_MIN_WAKEUP_INTERVAL = 1.0;
|
||||
// These parameters affect how often we redraw.
|
||||
// The first is how different (percent crossfaded) the slide show
|
||||
// has to look before redrawing and the second is the minimum
|
||||
// frequency (in seconds) we're willing to wake up
|
||||
export let ANIMATION_OPACITY_STEP_INCREMENT = 4.0;
|
||||
export let ANIMATION_MIN_WAKEUP_INTERVAL = 1.0;
|
||||
|
||||
let _backgroundCache = null;
|
||||
|
||||
|
|
@ -132,12 +139,13 @@ function _fileEqual0(file1, file2) {
|
|||
return file1.equal(file2);
|
||||
}
|
||||
|
||||
var BackgroundCache = class BackgroundCache extends Signals.EventEmitter {
|
||||
export class BackgroundCache extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._fileMonitors = {};
|
||||
this._backgroundSources = {};
|
||||
/** @type {{ [key: string]: Animation["prototype"] }} */
|
||||
this._animations = {};
|
||||
}
|
||||
|
||||
|
|
@ -159,6 +167,16 @@ var BackgroundCache = class BackgroundCache extends Signals.EventEmitter {
|
|||
this._fileMonitors[key] = monitor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} AnimationParams
|
||||
* @property {Gio.File} file
|
||||
* @property {string} settingsSchema
|
||||
* @property {((animation: Animation["prototype"]) => void) | null} onLoaded
|
||||
*/
|
||||
|
||||
/**
|
||||
* @param {Partial<AnimationParams>} [params]
|
||||
*/
|
||||
getAnimation(params = {}) {
|
||||
const {
|
||||
file = null,
|
||||
|
|
@ -219,13 +237,13 @@ var BackgroundCache = class BackgroundCache extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
function getBackgroundCache() {
|
||||
export function getBackgroundCache() {
|
||||
if (!_backgroundCache)
|
||||
_backgroundCache = new BackgroundCache();
|
||||
return _backgroundCache;
|
||||
}
|
||||
|
||||
var Background = GObject.registerClass({
|
||||
export const Background = GObject.registerClass({
|
||||
Signals: { 'loaded': {}, 'bg-changed': {} },
|
||||
}, class Background extends Meta.Background {
|
||||
_init(params = {}) {
|
||||
|
|
@ -248,6 +266,8 @@ var Background = GObject.registerClass({
|
|||
this._cancellable = new Gio.Cancellable();
|
||||
this.isLoaded = false;
|
||||
|
||||
this._changedId = -1;
|
||||
|
||||
this._clock = new GnomeDesktop.WallClock();
|
||||
this._timezoneChangedId = this._clock.connect('notify::timezone',
|
||||
() => {
|
||||
|
|
@ -269,6 +289,17 @@ var Background = GObject.registerClass({
|
|||
this._load();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(background: Background) => void} callback
|
||||
*/
|
||||
onNextChange(callback) {
|
||||
this._changedId = this.connect('bg-changed', (background) => {
|
||||
background.disconnect(this._changedId);
|
||||
|
||||
callback(background);
|
||||
});
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this._cancellable.cancel();
|
||||
this._removeAnimationTimeout();
|
||||
|
|
@ -515,7 +546,7 @@ var Background = GObject.registerClass({
|
|||
|
||||
let _systemBackground;
|
||||
|
||||
var SystemBackground = GObject.registerClass({
|
||||
export const SystemBackground = GObject.registerClass({
|
||||
Signals: { 'loaded': {} },
|
||||
}, class SystemBackground extends Meta.BackgroundActor {
|
||||
_init() {
|
||||
|
|
@ -538,7 +569,7 @@ var SystemBackground = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var BackgroundSource = class BackgroundSource {
|
||||
export class BackgroundSource {
|
||||
constructor(layoutManager, settingsSchema) {
|
||||
// Allow override the background image setting for performance testing
|
||||
this._layoutManager = layoutManager;
|
||||
|
|
@ -601,9 +632,9 @@ var BackgroundSource = class BackgroundSource {
|
|||
style,
|
||||
});
|
||||
|
||||
background._changedId = background.connect('bg-changed', () => {
|
||||
background.disconnect(background._changedId);
|
||||
background.destroy();
|
||||
background.onNextChange((bg) => {
|
||||
bg.destroy();
|
||||
|
||||
delete this._backgrounds[monitorIndex];
|
||||
});
|
||||
|
||||
|
|
@ -627,8 +658,11 @@ var BackgroundSource = class BackgroundSource {
|
|||
}
|
||||
};
|
||||
|
||||
var Animation = GObject.registerClass(
|
||||
export const Animation = GObject.registerClass(
|
||||
class Animation extends GnomeDesktop.BGSlideShow {
|
||||
/**
|
||||
* @param {*} params
|
||||
*/
|
||||
_init(params) {
|
||||
super._init(params);
|
||||
|
||||
|
|
@ -638,6 +672,16 @@ class Animation extends GnomeDesktop.BGSlideShow {
|
|||
this.loaded = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {false}
|
||||
*/
|
||||
load() {
|
||||
throw new GObject.NotImplementedError(`Animation.prototype.load is not supported. Use loadAsync.`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {() => void} callback
|
||||
*/
|
||||
loadAsync(callback) {
|
||||
this.load_async(null, () => {
|
||||
this.loaded = true;
|
||||
|
|
@ -666,7 +710,7 @@ class Animation extends GnomeDesktop.BGSlideShow {
|
|||
}
|
||||
});
|
||||
|
||||
var BackgroundManager = class BackgroundManager extends Signals.EventEmitter {
|
||||
export class BackgroundManager extends Signals.EventEmitter {
|
||||
constructor(params = {}) {
|
||||
super();
|
||||
|
||||
|
|
@ -746,7 +790,7 @@ var BackgroundManager = class BackgroundManager extends Signals.EventEmitter {
|
|||
|
||||
const { background } = newBackgroundActor.content;
|
||||
|
||||
if (background.isLoaded) {
|
||||
if (background instanceof Background && background.isLoaded) {
|
||||
this._swapBackgroundActor();
|
||||
} else {
|
||||
newBackgroundActor.loadedSignalId = background.connect('loaded',
|
||||
|
|
|
|||
|
|
@ -1,13 +1,14 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported addBackgroundMenu */
|
||||
|
||||
const { Clutter, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import St from 'gi://St';
|
||||
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
import * as BoxPointer from './boxpointer.js';
|
||||
import Main from './main.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
|
||||
var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
|
||||
export class BackgroundMenu extends PopupMenu.PopupMenu {
|
||||
constructor(layoutManager) {
|
||||
super(layoutManager.dummyCursor, 0, St.Side.TOP);
|
||||
|
||||
|
|
@ -23,7 +24,7 @@ var BackgroundMenu = class BackgroundMenu extends PopupMenu.PopupMenu {
|
|||
}
|
||||
};
|
||||
|
||||
function addBackgroundMenu(actor, layoutManager) {
|
||||
export function addBackgroundMenu(actor, layoutManager) {
|
||||
actor.reactive = true;
|
||||
actor._backgroundMenu = new BackgroundMenu(layoutManager);
|
||||
actor._backgroundManager = new PopupMenu.PopupMenuManager(actor);
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
||||
/* exported BarLevel */
|
||||
|
||||
const { Atk, Clutter, GObject, St } = imports.gi;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import St from 'gi://St';
|
||||
|
||||
var BarLevel = GObject.registerClass({
|
||||
|
||||
export const BarLevel = GObject.registerClass({
|
||||
Properties: {
|
||||
'value': GObject.ParamSpec.double(
|
||||
'value', 'value', 'value',
|
||||
|
|
@ -19,6 +23,9 @@ var BarLevel = GObject.registerClass({
|
|||
1, 2, 1),
|
||||
},
|
||||
}, class BarLevel extends St.DrawingArea {
|
||||
/**
|
||||
* @param {*} params
|
||||
*/
|
||||
_init(params) {
|
||||
this._maxValue = 1;
|
||||
this._value = 0;
|
||||
|
|
|
|||
|
|
@ -1,18 +1,23 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported BoxPointer */
|
||||
|
||||
const { Clutter, GObject, Meta, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
var PopupAnimation = {
|
||||
import Main from './main.js';
|
||||
|
||||
/** @enum {number} */
|
||||
export const PopupAnimation = {
|
||||
NONE: 0,
|
||||
SLIDE: 1 << 0,
|
||||
FADE: 1 << 1,
|
||||
FULL: ~0,
|
||||
};
|
||||
|
||||
var POPUP_ANIMATION_TIME = 150;
|
||||
export let POPUP_ANIMATION_TIME = 150;
|
||||
|
||||
/**
|
||||
* BoxPointer:
|
||||
|
|
@ -27,9 +32,13 @@ var POPUP_ANIMATION_TIME = 150;
|
|||
* totally inside the monitor workarea if possible.
|
||||
*
|
||||
*/
|
||||
var BoxPointer = GObject.registerClass({
|
||||
export const BoxPointer = GObject.registerClass({
|
||||
Signals: { 'arrow-side-changed': {} },
|
||||
}, class BoxPointer extends St.Widget {
|
||||
/**
|
||||
* @param {*} arrowSide
|
||||
* @param {*} binProperties
|
||||
*/
|
||||
_init(arrowSide, binProperties) {
|
||||
super._init();
|
||||
|
||||
|
|
@ -167,6 +176,12 @@ var BoxPointer = GObject.registerClass({
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean} isWidth
|
||||
* @param {number} minSize
|
||||
* @param {number} natSize
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
_adjustAllocationForArrow(isWidth, minSize, natSize) {
|
||||
let themeNode = this.get_theme_node();
|
||||
let borderWidth = themeNode.get_length('-arrow-border-width');
|
||||
|
|
@ -182,6 +197,9 @@ var BoxPointer = GObject.registerClass({
|
|||
return [minSize, natSize];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let themeNode = this.get_theme_node();
|
||||
forHeight = themeNode.adjust_for_height(forHeight);
|
||||
|
|
|
|||
|
|
@ -1,23 +1,28 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Calendar, CalendarMessageList, DBusEventSource */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, 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 Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const MessageList = imports.ui.messageList;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Mpris = imports.ui.mpris;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Util = imports.misc.util;
|
||||
import Main from './main.js';
|
||||
import * as MessageList from './messageList.js';
|
||||
import * as MessageTray from './messageTray.js';
|
||||
import * as Mpris from './mpris.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
import * as Util from '../misc/util.js';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
var MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
var SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||
const MSECS_IN_DAY = 24 * 60 * 60 * 1000;
|
||||
const SHOW_WEEKDATE_KEY = 'show-weekdate';
|
||||
|
||||
var MESSAGE_ICON_SIZE = -1; // pick up from CSS
|
||||
export let MESSAGE_ICON_SIZE = -1; // pick up from CSS
|
||||
|
||||
var NC_ = (context, str) => '%s\u0004%s'.format(context, str);
|
||||
export const NC_ = (context, str) => '%s\u0004%s'.format(context, str);
|
||||
|
||||
function sameYear(dateA, dateB) {
|
||||
return dateA.getYear() == dateB.getYear();
|
||||
|
|
@ -81,7 +86,7 @@ function _getCalendarDayAbbreviation(dayNumber) {
|
|||
|
||||
// Abstraction for an appointment/event in a calendar
|
||||
|
||||
var CalendarEvent = class CalendarEvent {
|
||||
export class CalendarEvent {
|
||||
constructor(id, date, end, summary, allDay) {
|
||||
this.id = id;
|
||||
this.date = date;
|
||||
|
|
@ -94,7 +99,7 @@ var CalendarEvent = class CalendarEvent {
|
|||
// Interface for appointments/events - e.g. the contents of a calendar
|
||||
//
|
||||
|
||||
var EventSourceBase = GObject.registerClass({
|
||||
export const EventSourceBase = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT,
|
||||
Properties: {
|
||||
'has-calendars': GObject.ParamSpec.boolean(
|
||||
|
|
@ -108,10 +113,16 @@ var EventSourceBase = GObject.registerClass({
|
|||
},
|
||||
Signals: { 'changed': {} },
|
||||
}, class EventSourceBase extends GObject.Object {
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
get isLoading() {
|
||||
throw new GObject.NotImplementedError('isLoading in %s'.format(this.constructor.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
get hasCalendars() {
|
||||
throw new GObject.NotImplementedError('hasCalendars in %s'.format(this.constructor.name));
|
||||
}
|
||||
|
|
@ -123,16 +134,22 @@ var EventSourceBase = GObject.registerClass({
|
|||
throw new GObject.NotImplementedError('requestRange in %s'.format(this.constructor.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {any[]}
|
||||
*/
|
||||
getEvents(_begin, _end) {
|
||||
throw new GObject.NotImplementedError('getEvents in %s'.format(this.constructor.name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
hasEvents(_day) {
|
||||
throw new GObject.NotImplementedError('hasEvents in %s'.format(this.constructor.name));
|
||||
}
|
||||
});
|
||||
|
||||
var EmptyEventSource = GObject.registerClass(
|
||||
export const EmptyEventSource = GObject.registerClass(
|
||||
class EmptyEventSource extends EventSourceBase {
|
||||
get isLoading() {
|
||||
return false;
|
||||
|
|
@ -185,7 +202,7 @@ function _dateIntervalsOverlap(a0, a1, b0, b1) {
|
|||
}
|
||||
|
||||
// an implementation that reads data from a session bus service
|
||||
var DBusEventSource = GObject.registerClass(
|
||||
export const DBusEventSource = GObject.registerClass(
|
||||
class DBusEventSource extends EventSourceBase {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -373,9 +390,11 @@ class DBusEventSource extends EventSourceBase {
|
|||
}
|
||||
});
|
||||
|
||||
var Calendar = GObject.registerClass({
|
||||
export const Calendar = GObject.registerClass({
|
||||
Signals: { 'selected-date-changed': { param_types: [GLib.DateTime.$gtype] } },
|
||||
}, class Calendar extends St.Widget {
|
||||
},
|
||||
/** @extends {St.Widget<Clutter.GridLayout>} */
|
||||
class Calendar extends St.Widget {
|
||||
_init() {
|
||||
this._weekStart = Shell.util_get_week_start();
|
||||
this._settings = new Gio.Settings({ schema_id: 'org.gnome.desktop.calendar' });
|
||||
|
|
@ -719,7 +738,7 @@ var Calendar = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var NotificationMessage = GObject.registerClass(
|
||||
export const NotificationMessage = GObject.registerClass(
|
||||
class NotificationMessage extends MessageList.Message {
|
||||
_init(notification) {
|
||||
super._init(notification.title, notification.bannerBodyText);
|
||||
|
|
@ -784,7 +803,7 @@ class NotificationMessage extends MessageList.Message {
|
|||
}
|
||||
});
|
||||
|
||||
var TimeLabel = GObject.registerClass(
|
||||
export const TimeLabel = GObject.registerClass(
|
||||
class NotificationTimeLabel extends St.Label {
|
||||
_init(datetime) {
|
||||
super._init({
|
||||
|
|
@ -801,7 +820,7 @@ class NotificationTimeLabel extends St.Label {
|
|||
}
|
||||
});
|
||||
|
||||
var NotificationSection = GObject.registerClass(
|
||||
export const NotificationSection = GObject.registerClass(
|
||||
class NotificationSection extends MessageList.MessageListSection {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -882,7 +901,7 @@ class NotificationSection extends MessageList.MessageListSection {
|
|||
}
|
||||
});
|
||||
|
||||
var Placeholder = GObject.registerClass(
|
||||
export const Placeholder = GObject.registerClass(
|
||||
class Placeholder extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({ style_class: 'message-list-placeholder', vertical: true });
|
||||
|
|
@ -918,7 +937,7 @@ class DoNotDisturbSwitch extends PopupMenu.Switch {
|
|||
}
|
||||
});
|
||||
|
||||
var CalendarMessageList = GObject.registerClass(
|
||||
export const CalendarMessageList = GObject.registerClass(
|
||||
class CalendarMessageList extends St.Widget {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -982,6 +1001,7 @@ class CalendarMessageList extends St.Widget {
|
|||
this._clearButton, 'visible',
|
||||
GObject.BindingFlags.INVERT_BOOLEAN);
|
||||
|
||||
/** @type {St.BoxLayout<MessageList.MessageListSection["prototype"]>} */
|
||||
this._sectionList = new St.BoxLayout({ style_class: 'message-list-sections',
|
||||
vertical: true,
|
||||
x_expand: true,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,12 @@
|
|||
/* exported CheckBox */
|
||||
const { Atk, Clutter, GObject, Pango, St } = imports.gi;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import Pango from 'gi://Pango';
|
||||
import St from 'gi://St';
|
||||
|
||||
var CheckBox = GObject.registerClass(
|
||||
|
||||
export const CheckBox = GObject.registerClass(
|
||||
class CheckBox extends St.Button {
|
||||
_init(label) {
|
||||
let container = new St.BoxLayout({
|
||||
|
|
|
|||
|
|
@ -1,21 +1,30 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported CloseDialog */
|
||||
|
||||
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
var FROZEN_WINDOW_BRIGHTNESS = -0.3;
|
||||
var DIALOG_TRANSITION_TIME = 150;
|
||||
var ALIVE_TIMEOUT = 5000;
|
||||
import * as Dialog from './dialog.js';
|
||||
import Main from './main.js';
|
||||
|
||||
var CloseDialog = GObject.registerClass({
|
||||
export let FROZEN_WINDOW_BRIGHTNESS = -0.3;
|
||||
export let DIALOG_TRANSITION_TIME = 150;
|
||||
export let ALIVE_TIMEOUT = 5000;
|
||||
|
||||
export const CloseDialog = GObject.registerClass({
|
||||
Implements: [Meta.CloseDialog],
|
||||
Properties: {
|
||||
'window': GObject.ParamSpec.override('window', Meta.CloseDialog),
|
||||
},
|
||||
}, class CloseDialog extends GObject.Object {
|
||||
/**
|
||||
* @param {Meta.Window} window
|
||||
*/
|
||||
_init(window) {
|
||||
super._init();
|
||||
this._window = window;
|
||||
|
|
@ -30,6 +39,9 @@ var CloseDialog = GObject.registerClass({
|
|||
return this._window;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Meta.Window} window
|
||||
*/
|
||||
set window(window) {
|
||||
this._window = window;
|
||||
}
|
||||
|
|
@ -61,6 +73,7 @@ var CloseDialog = GObject.registerClass({
|
|||
if (this._dialog)
|
||||
return;
|
||||
|
||||
/** @type {Meta.WindowActor} */
|
||||
let windowActor = this._window.get_compositor_private();
|
||||
this._dialog = new Dialog.Dialog(windowActor, 'close-dialog');
|
||||
this._dialog.width = windowActor.width;
|
||||
|
|
@ -86,6 +99,7 @@ var CloseDialog = GObject.registerClass({
|
|||
// We set the effect on the surface actor, so the dialog itself
|
||||
// (which is a child of the MetaWindowActor) does not get the
|
||||
// effect applied itself.
|
||||
/** @type {Meta.WindowActor} */
|
||||
let windowActor = this._window.get_compositor_private();
|
||||
let surfaceActor = windowActor.get_first_child();
|
||||
let effect = new Clutter.BrightnessContrastEffect();
|
||||
|
|
@ -94,15 +108,22 @@ var CloseDialog = GObject.registerClass({
|
|||
}
|
||||
|
||||
_removeWindowEffect() {
|
||||
/** @type {Meta.WindowActor} */
|
||||
let windowActor = this._window.get_compositor_private();
|
||||
let surfaceActor = windowActor.get_first_child();
|
||||
surfaceActor.remove_effect_by_name("gnome-shell-frozen-window");
|
||||
}
|
||||
|
||||
/**
|
||||
* @this {Meta.CloseDialog}
|
||||
*/
|
||||
_onWait() {
|
||||
this.response(Meta.CloseDialogResponse.WAIT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @this {Meta.CloseDialog}
|
||||
*/
|
||||
_onClose() {
|
||||
this.response(Meta.CloseDialogResponse.FORCE_CLOSE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* exported ComponentManager */
|
||||
const Main = imports.ui.main;
|
||||
import Main from './main.js';
|
||||
|
||||
var ComponentManager = class {
|
||||
export class ComponentManager {
|
||||
constructor() {
|
||||
this._allComponents = {};
|
||||
this._enabledComponents = [];
|
||||
|
|
@ -10,12 +10,12 @@ var ComponentManager = class {
|
|||
this._sessionUpdated();
|
||||
}
|
||||
|
||||
_sessionUpdated() {
|
||||
async _sessionUpdated() {
|
||||
let newEnabledComponents = Main.sessionMode.components;
|
||||
|
||||
newEnabledComponents
|
||||
await Promise.all([...newEnabledComponents
|
||||
.filter(name => !this._enabledComponents.includes(name))
|
||||
.forEach(name => this._enableComponent(name));
|
||||
.map(name => this._enableComponent(name))]);
|
||||
|
||||
this._enabledComponents
|
||||
.filter(name => !newEnabledComponents.includes(name))
|
||||
|
|
@ -24,12 +24,12 @@ var ComponentManager = class {
|
|||
this._enabledComponents = newEnabledComponents;
|
||||
}
|
||||
|
||||
_importComponent(name) {
|
||||
let module = imports.ui.components[name];
|
||||
async _importComponent(name) {
|
||||
let module = await import(`./components/${name}.js`);
|
||||
return module.Component;
|
||||
}
|
||||
|
||||
_ensureComponent(name) {
|
||||
async _ensureComponent(name) {
|
||||
let component = this._allComponents[name];
|
||||
if (component)
|
||||
return component;
|
||||
|
|
@ -37,14 +37,14 @@ var ComponentManager = class {
|
|||
if (Main.sessionMode.isLocked)
|
||||
return null;
|
||||
|
||||
let constructor = this._importComponent(name);
|
||||
let constructor = await this._importComponent(name);
|
||||
component = new constructor();
|
||||
this._allComponents[name] = component;
|
||||
return component;
|
||||
}
|
||||
|
||||
_enableComponent(name) {
|
||||
let component = this._ensureComponent(name);
|
||||
async _enableComponent(name) {
|
||||
let component = await this._ensureComponent(name);
|
||||
if (component)
|
||||
component.enable();
|
||||
}
|
||||
|
|
@ -1,25 +1,26 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Component */
|
||||
|
||||
const { Gio, GLib } = imports.gi;
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Main = imports.ui.main;
|
||||
const ShellMountOperation = imports.ui.shellMountOperation;
|
||||
import * as GnomeSession from '../../misc/gnomeSession.js';
|
||||
import Main from './../main.js';
|
||||
import * as ShellMountOperation from './../shellMountOperation.js';
|
||||
|
||||
var GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
|
||||
export let GNOME_SESSION_AUTOMOUNT_INHIBIT = 16;
|
||||
|
||||
// GSettings keys
|
||||
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
||||
const SETTING_ENABLE_AUTOMOUNT = 'automount';
|
||||
|
||||
var AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
||||
export let AUTORUN_EXPIRE_TIMEOUT_SECS = 10;
|
||||
|
||||
var AutomountManager = class {
|
||||
export class AutomountManager {
|
||||
constructor() {
|
||||
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
|
||||
this._activeOperations = new Map();
|
||||
this._session = new GnomeSession.SessionManager();
|
||||
this._session = GnomeSession.SessionManager();
|
||||
this._session.connectSignal('InhibitorAdded',
|
||||
this._InhibitorsChanged.bind(this));
|
||||
this._session.connectSignal('InhibitorRemoved',
|
||||
|
|
@ -130,6 +131,18 @@ var AutomountManager = class {
|
|||
this._checkAndMountVolume(volume);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} VolumeMountProps: An object with the properties:
|
||||
* @property {boolean} [checkSession]
|
||||
* @property {boolean} [useMountOp]
|
||||
* @property {boolean} [allowAutorun]
|
||||
*/
|
||||
|
||||
/**
|
||||
* _checkAndMountVolume:
|
||||
* @param {Gio.Volume} volume
|
||||
* @param {Partial<VolumeMountProps>} [params]
|
||||
*/
|
||||
_checkAndMountVolume(volume, params = {}) {
|
||||
const {
|
||||
checkSession = true,
|
||||
|
|
@ -253,4 +266,4 @@ var AutomountManager = class {
|
|||
GLib.Source.set_name_by_id(id, '[gnome-shell] volume.allowAutorun');
|
||||
}
|
||||
};
|
||||
var Component = AutomountManager;
|
||||
export let Component = AutomountManager;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,17 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Component */
|
||||
|
||||
const { Clutter, Gio, GObject, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import St from 'gi://St';
|
||||
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import * as GnomeSession from '../../misc/gnomeSession.js';
|
||||
import Main from './../main.js';
|
||||
import * as MessageTray from './../messageTray.js';
|
||||
|
||||
import { loadInterfaceXML } from '../../misc/fileUtilsModule.js';
|
||||
|
||||
// GSettings keys
|
||||
const SETTINGS_SCHEMA = 'org.gnome.desktop.media-handling';
|
||||
|
|
@ -16,7 +20,8 @@ const SETTING_START_APP = 'autorun-x-content-start-app';
|
|||
const SETTING_IGNORE = 'autorun-x-content-ignore';
|
||||
const SETTING_OPEN_FOLDER = 'autorun-x-content-open-folder';
|
||||
|
||||
var AutorunSetting = {
|
||||
/** @enum {number} */
|
||||
export const AutorunSetting = {
|
||||
RUN: 0,
|
||||
IGNORE: 1,
|
||||
FILES: 2,
|
||||
|
|
@ -80,7 +85,7 @@ function HotplugSniffer() {
|
|||
'/org/gnome/Shell/HotplugSniffer');
|
||||
}
|
||||
|
||||
var ContentTypeDiscoverer = class {
|
||||
export class ContentTypeDiscoverer {
|
||||
constructor(callback) {
|
||||
this._callback = callback;
|
||||
this._settings = new Gio.Settings({ schema_id: SETTINGS_SCHEMA });
|
||||
|
|
@ -142,9 +147,9 @@ var ContentTypeDiscoverer = class {
|
|||
}
|
||||
};
|
||||
|
||||
var AutorunManager = class {
|
||||
export class AutorunManager {
|
||||
constructor() {
|
||||
this._session = new GnomeSession.SessionManager();
|
||||
this._session = GnomeSession.SessionManager();
|
||||
this._volumeMonitor = Gio.VolumeMonitor.get();
|
||||
|
||||
this._dispatcher = new AutorunDispatcher(this);
|
||||
|
|
@ -160,7 +165,10 @@ var AutorunManager = class {
|
|||
this._volumeMonitor.disconnect(this._mountRemovedId);
|
||||
}
|
||||
|
||||
_onMountAdded(monitor, mount) {
|
||||
/**
|
||||
* @param {Gio.Mount} mount
|
||||
*/
|
||||
_onMountAdded(_, mount) {
|
||||
// don't do anything if our session is not the currently
|
||||
// active one
|
||||
if (!this._session.SessionIsActive)
|
||||
|
|
@ -177,7 +185,10 @@ var AutorunManager = class {
|
|||
}
|
||||
};
|
||||
|
||||
var AutorunDispatcher = class {
|
||||
export class AutorunDispatcher {
|
||||
/**
|
||||
* @param {AutorunManager} manager
|
||||
*/
|
||||
constructor(manager) {
|
||||
this._manager = manager;
|
||||
this._sources = [];
|
||||
|
|
@ -212,6 +223,10 @@ var AutorunDispatcher = class {
|
|||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Gio.Mount} mount
|
||||
* @param {Gio.Application[]} apps
|
||||
*/
|
||||
_addSource(mount, apps) {
|
||||
// if we already have a source showing for this
|
||||
// mount, return
|
||||
|
|
@ -222,6 +237,10 @@ var AutorunDispatcher = class {
|
|||
this._sources.push(new AutorunSource(this._manager, mount, apps));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Gio.Mount} mount
|
||||
* @param {Gio.Application[]} apps
|
||||
*/
|
||||
addMount(mount, apps, contentTypes) {
|
||||
// if autorun is disabled globally, return
|
||||
if (this._settings.get_boolean(SETTING_DISABLE_AUTORUN))
|
||||
|
|
@ -271,7 +290,14 @@ var AutorunDispatcher = class {
|
|||
}
|
||||
};
|
||||
|
||||
var AutorunSource = GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} AutorunSourceParams
|
||||
* @property {AutorunManager} manager
|
||||
* @property {Gio.Mount} mount
|
||||
* @property {Gio.Application[]} apps
|
||||
*/
|
||||
|
||||
export const AutorunSource = GObject.registerClass(
|
||||
class AutorunSource extends MessageTray.Source {
|
||||
_init(manager, mount, apps) {
|
||||
super._init(mount.get_name());
|
||||
|
|
@ -296,8 +322,12 @@ class AutorunSource extends MessageTray.Source {
|
|||
}
|
||||
});
|
||||
|
||||
var AutorunNotification = GObject.registerClass(
|
||||
export const AutorunNotification = GObject.registerClass(
|
||||
class AutorunNotification extends MessageTray.Notification {
|
||||
/**
|
||||
* @param {*} manager
|
||||
* @param {*} source
|
||||
*/
|
||||
_init(manager, source) {
|
||||
super._init(source, source.title);
|
||||
|
||||
|
|
@ -356,4 +386,4 @@ class AutorunNotification extends MessageTray.Notification {
|
|||
}
|
||||
});
|
||||
|
||||
var Component = AutorunManager;
|
||||
export let Component = AutorunManager;
|
||||
|
|
|
|||
|
|
@ -1,15 +1,22 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Component */
|
||||
|
||||
const { Clutter, Gcr, Gio, GObject, Pango, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gcr from 'gi://Gcr';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Pango from 'gi://Pango';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
var KeyringDialog = GObject.registerClass(
|
||||
import * as Dialog from './../dialog.js';
|
||||
import * as ModalDialog from './../modalDialog.js';
|
||||
import * as ShellEntry from './../shellEntry.js';
|
||||
import * as CheckBox from './../checkBox.js';
|
||||
import * as Util from '../../misc/util.js';
|
||||
|
||||
export const KeyringDialog = GObject.registerClass(
|
||||
class KeyringDialog extends ModalDialog.ModalDialog {
|
||||
_init() {
|
||||
super._init({ styleClass: 'prompt-dialog' });
|
||||
|
|
@ -178,7 +185,7 @@ class KeyringDialog extends ModalDialog.ModalDialog {
|
|||
}
|
||||
});
|
||||
|
||||
var KeyringDummyDialog = class {
|
||||
export class KeyringDummyDialog {
|
||||
constructor() {
|
||||
this.prompt = new Shell.KeyringPrompt();
|
||||
this.prompt.connect('show-password', this._cancelPrompt.bind(this));
|
||||
|
|
@ -190,7 +197,7 @@ var KeyringDummyDialog = class {
|
|||
}
|
||||
};
|
||||
|
||||
var KeyringPrompter = GObject.registerClass(
|
||||
export const KeyringPrompter = GObject.registerClass(
|
||||
class KeyringPrompter extends Gcr.SystemPrompter {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -226,4 +233,4 @@ class KeyringPrompter extends Gcr.SystemPrompter {
|
|||
}
|
||||
});
|
||||
|
||||
var Component = KeyringPrompter;
|
||||
export let Component = KeyringPrompter;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,21 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Component */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, NM, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import NM from 'gi://NM';
|
||||
import Pango from 'gi://Pango';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../../misc/signals.js';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
import * as Dialog from './../dialog.js';
|
||||
import Main from './../main.js';
|
||||
import * as MessageTray from './../messageTray.js';
|
||||
import * as ModalDialog from './../modalDialog.js';
|
||||
import * as ShellEntry from './../shellEntry.js';
|
||||
|
||||
Gio._promisify(Shell.NetworkAgent.prototype, 'init_async', 'init_finish');
|
||||
Gio._promisify(Shell.NetworkAgent.prototype,
|
||||
|
|
@ -16,11 +23,21 @@ Gio._promisify(Shell.NetworkAgent.prototype,
|
|||
|
||||
const VPN_UI_GROUP = 'VPN Plugin UI';
|
||||
|
||||
var NetworkSecretDialog = GObject.registerClass(
|
||||
export const NetworkSecretDialog = GObject.registerClass(
|
||||
class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
||||
/**
|
||||
* @param {any | Shell.NetworkAgent} agent
|
||||
* @param {string} requestId
|
||||
* @param {NM.Connection} connection
|
||||
* @param {string} settingName
|
||||
* @param {string[]} hints
|
||||
* @param {number} flags
|
||||
* @param {{ title: string, message: string, secrets: string[] }} [contentOverride]
|
||||
*/
|
||||
_init(agent, requestId, connection, settingName, hints, flags, contentOverride) {
|
||||
super._init({ styleClass: 'prompt-dialog' });
|
||||
|
||||
/** @type {Shell.NetworkAgent} */
|
||||
this._agent = agent;
|
||||
this._requestId = requestId;
|
||||
this._connection = connection;
|
||||
|
|
@ -213,7 +230,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
|||
case 'none': // static WEP
|
||||
secrets.push({
|
||||
label: _('Key'),
|
||||
key: 'wep-key%s'.format(wirelessSecuritySetting.wep_tx_keyidx),
|
||||
key: 'wep-key%s'.format(wirelessSecuritySetting.wep_tx_keyidx.toFixed(0)),
|
||||
value: wirelessSecuritySetting.get_wep_key(wirelessSecuritySetting.wep_tx_keyidx) || '',
|
||||
wep_key_type: wirelessSecuritySetting.wep_key_type,
|
||||
validate: this._validateStaticWep,
|
||||
|
|
@ -298,7 +315,8 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
|||
else
|
||||
setting = this._connection.get_setting_by_name(connectionType);
|
||||
secrets.push({ label: _('Password'), key: 'password',
|
||||
value: setting.value || '', password: true });
|
||||
// TODO: Does not exist: setting.value on NM.Setting
|
||||
value: '', password: true });
|
||||
}
|
||||
|
||||
_getContent() {
|
||||
|
|
@ -354,7 +372,7 @@ class NetworkSecretDialog extends ModalDialog.ModalDialog {
|
|||
}
|
||||
});
|
||||
|
||||
var VPNRequestHandler = class extends Signals.EventEmitter {
|
||||
export class VPNRequestHandler extends Signals.EventEmitter {
|
||||
constructor(agent, requestId, authHelper, serviceType, connection, hints, flags) {
|
||||
super();
|
||||
|
||||
|
|
@ -527,7 +545,6 @@ var VPNRequestHandler = class extends Signals.EventEmitter {
|
|||
let keyfile = new GLib.KeyFile();
|
||||
let data;
|
||||
let contentOverride;
|
||||
|
||||
try {
|
||||
data = new GLib.Bytes(this._dataStdout.peek_buffer());
|
||||
keyfile.load_from_bytes(data, GLib.KeyFileFlags.NONE);
|
||||
|
|
@ -563,7 +580,7 @@ var VPNRequestHandler = class extends Signals.EventEmitter {
|
|||
}
|
||||
} catch (e) {
|
||||
// No output is a valid case it means "both secrets are stored"
|
||||
if (data.length > 0) {
|
||||
if (data.get_size() > 0) {
|
||||
logError(e, 'error while reading VPN plugin output keyfile');
|
||||
|
||||
this._agent.respond(this._requestId, Shell.NetworkAgentResponse.INTERNAL_ERROR);
|
||||
|
|
@ -604,7 +621,7 @@ var VPNRequestHandler = class extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var NetworkAgent = class {
|
||||
export class NetworkAgent {
|
||||
constructor() {
|
||||
this._native = new Shell.NetworkAgent({
|
||||
identifier: 'org.gnome.Shell.NetworkAgent',
|
||||
|
|
@ -807,4 +824,4 @@ var NetworkAgent = class {
|
|||
};
|
||||
}
|
||||
};
|
||||
var Component = NetworkAgent;
|
||||
export let Component = NetworkAgent;
|
||||
|
|
|
|||
|
|
@ -1,16 +1,25 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Component */
|
||||
|
||||
const { AccountsService, Clutter, GLib,
|
||||
GObject, Pango, PolkitAgent, Polkit, Shell, St } = imports.gi;
|
||||
import AccountsService from 'gi://AccountsService';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Pango from 'gi://Pango';
|
||||
import PolkitAgent from 'gi://PolkitAgent';
|
||||
import Polkit from 'gi://Polkit';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
import * as Dialog from './../dialog.js';
|
||||
import Main from './../main.js';
|
||||
import * as ModalDialog from './../modalDialog.js';
|
||||
import * as ShellEntry from './../shellEntry.js';
|
||||
import * as UserWidget from './../userWidget.js';
|
||||
import * as Util from '../../misc/util.js';
|
||||
|
||||
/** @enum {number} */
|
||||
const DialogMode = {
|
||||
AUTH: 0,
|
||||
CONFIRM: 1,
|
||||
|
|
@ -20,9 +29,15 @@ const DIALOG_ICON_SIZE = 64;
|
|||
|
||||
const DELAYED_RESET_TIMEOUT = 200;
|
||||
|
||||
var AuthenticationDialog = GObject.registerClass({
|
||||
export const AuthenticationDialog = GObject.registerClass({
|
||||
Signals: { 'done': { param_types: [GObject.TYPE_BOOLEAN] } },
|
||||
}, class AuthenticationDialog extends ModalDialog.ModalDialog {
|
||||
/**
|
||||
* @param {*} actionId
|
||||
* @param {*} description
|
||||
* @param {*} cookie
|
||||
* @param {*} userNames
|
||||
*/
|
||||
_init(actionId, description, cookie, userNames) {
|
||||
super._init({ styleClass: 'prompt-dialog' });
|
||||
|
||||
|
|
@ -410,7 +425,7 @@ var AuthenticationDialog = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var AuthenticationAgent = GObject.registerClass(
|
||||
export const AuthenticationAgent = GObject.registerClass(
|
||||
class AuthenticationAgent extends Shell.PolkitAuthenticationAgent {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -473,4 +488,4 @@ class AuthenticationAgent extends Shell.PolkitAuthenticationAgent {
|
|||
}
|
||||
});
|
||||
|
||||
var Component = AuthenticationAgent;
|
||||
export let Component = AuthenticationAgent;
|
||||
|
|
|
|||
|
|
@ -1,12 +1,29 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Component */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import St from 'gi://St';
|
||||
|
||||
import gi from 'gi';
|
||||
|
||||
import Main from './../main.js';
|
||||
|
||||
import * as History from '../../misc/history.js';
|
||||
import * as MessageList from './../messageList.js';
|
||||
import * as MessageTray from './../messageTray.js';
|
||||
import * as Util from '../../misc/util.js';
|
||||
|
||||
/** @type {import('telepathylogger0')} */
|
||||
let Tpl = null;
|
||||
/** @type {import('telepathyglib0')} */
|
||||
let Tp = null;
|
||||
|
||||
var Tpl = null;
|
||||
var Tp = null;
|
||||
try {
|
||||
({ TelepathyGLib: Tp, TelepathyLogger: Tpl } = imports.gi);
|
||||
Tp = gi.require('TelepathyGlib');
|
||||
Tpl = gi.require('TelepathyLogger');
|
||||
|
||||
Gio._promisify(Tp.Channel.prototype, 'close_async', 'close_finish');
|
||||
Gio._promisify(Tp.TextChannel.prototype,
|
||||
|
|
@ -19,29 +36,23 @@ try {
|
|||
log('Telepathy is not available, chat integration will be disabled.');
|
||||
}
|
||||
|
||||
const History = imports.misc.history;
|
||||
const Main = imports.ui.main;
|
||||
const MessageList = imports.ui.messageList;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const Util = imports.misc.util;
|
||||
|
||||
const HAVE_TP = Tp != null && Tpl != null;
|
||||
|
||||
// See Notification.appendMessage
|
||||
var SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes
|
||||
var SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||
var SCROLLBACK_RECENT_LENGTH = 20;
|
||||
var SCROLLBACK_IDLE_LENGTH = 5;
|
||||
export let SCROLLBACK_IMMEDIATE_TIME = 3 * 60; // 3 minutes
|
||||
export let SCROLLBACK_RECENT_TIME = 15 * 60; // 15 minutes
|
||||
export let SCROLLBACK_RECENT_LENGTH = 20;
|
||||
export let SCROLLBACK_IDLE_LENGTH = 5;
|
||||
|
||||
// See Source._displayPendingMessages
|
||||
var SCROLLBACK_HISTORY_LINES = 10;
|
||||
export let SCROLLBACK_HISTORY_LINES = 10;
|
||||
|
||||
// See Notification._onEntryChanged
|
||||
var COMPOSING_STOP_TIMEOUT = 5;
|
||||
export let COMPOSING_STOP_TIMEOUT = 5;
|
||||
|
||||
var CHAT_EXPAND_LINES = 12;
|
||||
export let CHAT_EXPAND_LINES = 12;
|
||||
|
||||
var NotificationDirection = {
|
||||
export const NotificationDirection = {
|
||||
SENT: 'chat-sent',
|
||||
RECEIVED: 'chat-received',
|
||||
};
|
||||
|
|
@ -51,8 +62,8 @@ const ChatMessage = HAVE_TP ? GObject.registerClass({
|
|||
'message-type': GObject.ParamSpec.int(
|
||||
'message-type', 'message-type', 'message-type',
|
||||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
||||
Math.min(...Object.values(Tp.ChannelTextMessageType)),
|
||||
Math.max(...Object.values(Tp.ChannelTextMessageType)),
|
||||
Tp.ChannelTextMessageType.NORMAL,
|
||||
Tp.ChannelTextMessageType.DELIVERY_REPORT,
|
||||
Tp.ChannelTextMessageType.NORMAL),
|
||||
'text': GObject.ParamSpec.string(
|
||||
'text', 'text', 'text',
|
||||
|
|
@ -71,35 +82,52 @@ const ChatMessage = HAVE_TP ? GObject.registerClass({
|
|||
GObject.ParamFlags.READWRITE | GObject.ParamFlags.CONSTRUCT_ONLY,
|
||||
null),
|
||||
},
|
||||
}, class ChatMessageClass extends GObject.Object {
|
||||
static newFromTpMessage(tpMessage, direction) {
|
||||
return new ChatMessage({
|
||||
'message-type': tpMessage.get_message_type(),
|
||||
'text': tpMessage.to_text()[0],
|
||||
'sender': tpMessage.sender.alias,
|
||||
'timestamp': direction === NotificationDirection.RECEIVED
|
||||
? tpMessage.get_received_timestamp() : tpMessage.get_sent_timestamp(),
|
||||
direction,
|
||||
});
|
||||
}
|
||||
}, class ChatMessage extends GObject.Object {
|
||||
/**
|
||||
* @param {{ [key: string]: any }} properties
|
||||
*/
|
||||
_init(properties) {
|
||||
super._init(properties);
|
||||
|
||||
static newFromTplTextEvent(tplTextEvent) {
|
||||
let direction =
|
||||
tplTextEvent.get_sender().get_entity_type() === Tpl.EntityType.SELF
|
||||
? NotificationDirection.SENT : NotificationDirection.RECEIVED;
|
||||
|
||||
return new ChatMessage({
|
||||
'message-type': tplTextEvent.get_message_type(),
|
||||
'text': tplTextEvent.get_message(),
|
||||
'sender': tplTextEvent.get_sender().get_alias(),
|
||||
'timestamp': tplTextEvent.get_timestamp(),
|
||||
direction,
|
||||
});
|
||||
/** @type {number} */
|
||||
this.messageType;
|
||||
/** @type {string} */
|
||||
this.text;
|
||||
/** @type {string} */
|
||||
this.sender;
|
||||
/** @type {number} */
|
||||
this.timestamp;
|
||||
/** @type {string} */
|
||||
this.direction ;
|
||||
}
|
||||
}) : null;
|
||||
|
||||
function newChatMessageFromTpMessage(tpMessage, direction) {
|
||||
return new ChatMessage({
|
||||
'message-type': tpMessage.get_message_type(),
|
||||
'text': tpMessage.to_text()[0],
|
||||
'sender': tpMessage.sender.alias,
|
||||
'timestamp': direction === NotificationDirection.RECEIVED
|
||||
? tpMessage.get_received_timestamp() : tpMessage.get_sent_timestamp(),
|
||||
direction,
|
||||
});
|
||||
}
|
||||
|
||||
var TelepathyComponent = class {
|
||||
function newChatMessageFromTplTextEvent(tplTextEvent) {
|
||||
let direction =
|
||||
tplTextEvent.get_sender().get_entity_type() === Tpl.EntityType.SELF
|
||||
? NotificationDirection.SENT : NotificationDirection.RECEIVED;
|
||||
|
||||
return new ChatMessage({
|
||||
'message-type': tplTextEvent.get_message_type(),
|
||||
'text': tplTextEvent.get_message(),
|
||||
'sender': tplTextEvent.get_sender().get_alias(),
|
||||
'timestamp': tplTextEvent.get_timestamp(),
|
||||
direction,
|
||||
});
|
||||
}
|
||||
|
||||
export class TelepathyComponent {
|
||||
constructor() {
|
||||
this._client = null;
|
||||
|
||||
|
|
@ -131,7 +159,7 @@ var TelepathyComponent = class {
|
|||
}
|
||||
};
|
||||
|
||||
var TelepathyClient = HAVE_TP ? GObject.registerClass(
|
||||
export let TelepathyClient = HAVE_TP ? GObject.registerClass(
|
||||
class TelepathyClient extends Tp.BaseClient {
|
||||
_init() {
|
||||
// channel path -> ChatSource
|
||||
|
|
@ -161,11 +189,12 @@ class TelepathyClient extends Tp.BaseClient {
|
|||
uniquify_name: true });
|
||||
|
||||
// We only care about single-user text-based chats
|
||||
let filter = {};
|
||||
filter[Tp.PROP_CHANNEL_CHANNEL_TYPE] = Tp.IFACE_CHANNEL_TYPE_TEXT;
|
||||
filter[Tp.PROP_CHANNEL_TARGET_HANDLE_TYPE] = Tp.HandleType.CONTACT;
|
||||
|
||||
let filter = {
|
||||
[Tp.PROP_CHANNEL_CHANNEL_TYPE] : Tp.IFACE_CHANNEL_TYPE_TEXT,
|
||||
[Tp.PROP_CHANNEL_TARGET_HANDLE_TYPE] : Tp.HandleType.CONTACT,
|
||||
};
|
||||
this.set_observer_recover(true);
|
||||
// FIXME
|
||||
this.add_observer_filter(filter);
|
||||
this.add_approver_filter(filter);
|
||||
this.add_handler_filter(filter);
|
||||
|
|
@ -201,7 +230,7 @@ class TelepathyClient extends Tp.BaseClient {
|
|||
if (this._chatSources[channel.get_object_path()])
|
||||
return;
|
||||
|
||||
let source = new ChatSource(account, conn, channel, contact, this);
|
||||
let source = new ChatSource({ account, connection: conn, channel, contact, client: this });
|
||||
|
||||
this._chatSources[channel.get_object_path()] = source;
|
||||
source.connect('destroy', () => {
|
||||
|
|
@ -294,19 +323,37 @@ class TelepathyClient extends Tp.BaseClient {
|
|||
}
|
||||
}) : null;
|
||||
|
||||
var ChatSource = HAVE_TP ? GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} ChatSourceParams
|
||||
* @property {import('telepathyglib0').Account} account
|
||||
* @property {import('telepathyglib0').Connection} connection
|
||||
* @property {import('telepathyglib0').TextChannel} channel
|
||||
* @property {import('telepathyglib0').Contact} contact
|
||||
* @property {import('telepathyglib0').BaseClient} client
|
||||
*/
|
||||
|
||||
export let ChatSource = HAVE_TP ? GObject.registerClass(
|
||||
class ChatSource extends MessageTray.Source {
|
||||
_init(account, conn, channel, contact, client) {
|
||||
|
||||
/**
|
||||
* @param {import('../messageTray.js').SourceParams & ChatSourceParams} params
|
||||
*/
|
||||
_init(params) {
|
||||
const { account, contact, client, connection, channel, ...sourceParams } = params;
|
||||
|
||||
this._account = account;
|
||||
this._contact = contact;
|
||||
this._client = client;
|
||||
|
||||
super._init(contact.get_alias());
|
||||
super._init({
|
||||
title: contact.get_alias(),
|
||||
...sourceParams
|
||||
});
|
||||
|
||||
this.isChat = true;
|
||||
this._pendingMessages = [];
|
||||
|
||||
this._conn = conn;
|
||||
this._conn = connection;
|
||||
this._channel = channel;
|
||||
this._closedId = this._channel.connect('invalidated', this._channelClosed.bind(this));
|
||||
|
||||
|
|
@ -455,7 +502,7 @@ class ChatSource extends MessageTray.Source {
|
|||
Tpl.EventTypeMask.TEXT, SCROLLBACK_HISTORY_LINES,
|
||||
null);
|
||||
|
||||
let logMessages = events.map(e => ChatMessage.newFromTplTextEvent(e));
|
||||
let logMessages = events.map(e => newChatMessageFromTplTextEvent(e));
|
||||
this._ensureNotification();
|
||||
|
||||
let pendingTpMessages = this._channel.get_pending_messages();
|
||||
|
|
@ -467,7 +514,7 @@ class ChatSource extends MessageTray.Source {
|
|||
if (message.get_message_type() == Tp.ChannelTextMessageType.DELIVERY_REPORT)
|
||||
continue;
|
||||
|
||||
pendingMessages.push(ChatMessage.newFromTpMessage(message,
|
||||
pendingMessages.push(newChatMessageFromTpMessage(message,
|
||||
NotificationDirection.RECEIVED));
|
||||
|
||||
this._pendingMessages.push(message);
|
||||
|
|
@ -492,7 +539,7 @@ class ChatSource extends MessageTray.Source {
|
|||
|
||||
if (!isPending) {
|
||||
showTimestamp = true;
|
||||
this._notification.appendMessage(logMessage, true, ['chat-log-message']);
|
||||
this._notification.appendMessage(logMessage, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -564,7 +611,7 @@ class ChatSource extends MessageTray.Source {
|
|||
this._pendingMessages.push(message);
|
||||
this.countUpdated();
|
||||
|
||||
message = ChatMessage.newFromTpMessage(message,
|
||||
message = newChatMessageFromTpMessage(message,
|
||||
NotificationDirection.RECEIVED);
|
||||
this._notification.appendMessage(message);
|
||||
|
||||
|
|
@ -590,7 +637,7 @@ class ChatSource extends MessageTray.Source {
|
|||
// our client and other clients as well.
|
||||
_messageSent(channel, message, _flags, _token) {
|
||||
this._ensureNotification();
|
||||
message = ChatMessage.newFromTpMessage(message,
|
||||
message = newChatMessageFromTpMessage(message,
|
||||
NotificationDirection.SENT);
|
||||
this._notification.appendMessage(message);
|
||||
}
|
||||
|
|
@ -655,19 +702,25 @@ class ChatSource extends MessageTray.Source {
|
|||
|
||||
const ChatNotificationMessage = HAVE_TP ? GObject.registerClass(
|
||||
class ChatNotificationMessage extends GObject.Object {
|
||||
/**
|
||||
* @param {*} props
|
||||
*/
|
||||
_init(props = {}) {
|
||||
super._init();
|
||||
this.set(props);
|
||||
}
|
||||
}) : null;
|
||||
|
||||
var ChatNotification = HAVE_TP ? GObject.registerClass({
|
||||
export let ChatNotification = HAVE_TP ? GObject.registerClass({
|
||||
Signals: {
|
||||
'message-removed': { param_types: [ChatNotificationMessage.$gtype] },
|
||||
'message-added': { param_types: [ChatNotificationMessage.$gtype] },
|
||||
'timestamp-changed': { param_types: [ChatNotificationMessage.$gtype] },
|
||||
},
|
||||
}, class ChatNotification extends MessageTray.Notification {
|
||||
/**
|
||||
* @param {*} source
|
||||
*/
|
||||
_init(source) {
|
||||
super._init(source, source.title, null,
|
||||
{ secondaryGIcon: source.getSecondaryIcon() });
|
||||
|
|
@ -687,18 +740,13 @@ var ChatNotification = HAVE_TP ? GObject.registerClass({
|
|||
|
||||
/**
|
||||
* appendMessage:
|
||||
* @param {Object} message: An object with the properties
|
||||
* {string} message.text: the body of the message,
|
||||
* {Tp.ChannelTextMessageType} message.messageType: the type
|
||||
* {string} message.sender: the name of the sender,
|
||||
* {number} message.timestamp: the time the message was sent
|
||||
* {NotificationDirection} message.direction: a #NotificationDirection
|
||||
* @param {ChatMessage["prototype"]} message: An object with the properties
|
||||
*
|
||||
* @param {bool} noTimestamp: Whether to add a timestamp. If %true,
|
||||
* @param {boolean} [noTimestamp]: Whether to add a timestamp. If %true,
|
||||
* no timestamp will be added, regardless of the difference since
|
||||
* the last timestamp
|
||||
*/
|
||||
appendMessage(message, noTimestamp) {
|
||||
appendMessage(message, noTimestamp = false) {
|
||||
let messageBody = GLib.markup_escape_text(message.text, -1);
|
||||
let styles = [message.direction];
|
||||
|
||||
|
|
@ -714,11 +762,8 @@ var ChatNotification = HAVE_TP ? GObject.registerClass({
|
|||
bannerMarkup: true });
|
||||
}
|
||||
|
||||
let group = message.direction == NotificationDirection.RECEIVED
|
||||
? 'received' : 'sent';
|
||||
|
||||
this._append({ body: messageBody,
|
||||
group,
|
||||
group: message.direction == NotificationDirection.RECEIVED ? 'received' : 'sent',
|
||||
styles,
|
||||
timestamp: message.timestamp,
|
||||
noTimestamp });
|
||||
|
|
@ -749,15 +794,18 @@ var ChatNotification = HAVE_TP ? GObject.registerClass({
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} AppendProps: An object with the properties:
|
||||
* @property {string?} body: The text of the message.
|
||||
* @property {('received' | 'sent' | 'meta')?} group: The group of the message, one of: 'received', 'sent', 'meta'.
|
||||
* @property {string[]} [styles]: Style class names for the message to have.
|
||||
* @property {number} [timestamp]: The timestamp of the message.
|
||||
* @property {boolean} [noTimestamp]: suppress timestamp signal?
|
||||
*/
|
||||
|
||||
/**
|
||||
* _append:
|
||||
* @param {Object} props: An object with the properties:
|
||||
* {string} props.body: The text of the message.
|
||||
* {string} props.group: The group of the message, one of:
|
||||
* 'received', 'sent', 'meta'.
|
||||
* {string[]} props.styles: Style class names for the message to have.
|
||||
* {number} props.timestamp: The timestamp of the message.
|
||||
* {bool} props.noTimestamp: suppress timestamp signal?
|
||||
* @param {Partial<AppendProps>} props
|
||||
*/
|
||||
_append(props = {}) {
|
||||
let currentTime = Date.now() / 1000;
|
||||
|
|
@ -828,16 +876,22 @@ var ChatNotification = HAVE_TP ? GObject.registerClass({
|
|||
}
|
||||
}) : null;
|
||||
|
||||
var ChatLineBox = GObject.registerClass(
|
||||
export const ChatLineBox = GObject.registerClass(
|
||||
class ChatLineBox extends St.BoxLayout {
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let [, natHeight] = super.vfunc_get_preferred_height(forWidth);
|
||||
return [natHeight, natHeight];
|
||||
}
|
||||
});
|
||||
|
||||
var ChatNotificationBanner = GObject.registerClass(
|
||||
export const ChatNotificationBanner = GObject.registerClass(
|
||||
class ChatNotificationBanner extends MessageTray.NotificationBanner {
|
||||
/**
|
||||
* @param {*} notification
|
||||
*/
|
||||
_init(notification) {
|
||||
super._init(notification);
|
||||
|
||||
|
|
@ -1014,4 +1068,4 @@ class ChatNotificationBanner extends MessageTray.NotificationBanner {
|
|||
}
|
||||
});
|
||||
|
||||
var Component = TelepathyComponent;
|
||||
export const Component = TelepathyComponent;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,24 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported CtrlAltTabManager */
|
||||
|
||||
const { Clutter, GObject, Meta, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const SwitcherPopup = imports.ui.switcherPopup;
|
||||
import Main from './main.js';
|
||||
import * as SwitcherPopup from './switcherPopup.js';
|
||||
|
||||
var POPUP_APPICON_SIZE = 96;
|
||||
export let POPUP_APPICON_SIZE = 96;
|
||||
|
||||
var SortGroup = {
|
||||
export const SortGroup = {
|
||||
TOP: 0,
|
||||
MIDDLE: 1,
|
||||
BOTTOM: 2,
|
||||
};
|
||||
|
||||
var CtrlAltTabManager = class CtrlAltTabManager {
|
||||
export class CtrlAltTabManager {
|
||||
constructor() {
|
||||
this._items = [];
|
||||
this.addGroup(global.window_group, _("Windows"),
|
||||
|
|
@ -138,7 +142,7 @@ var CtrlAltTabManager = class CtrlAltTabManager {
|
|||
}
|
||||
};
|
||||
|
||||
var CtrlAltTabPopup = GObject.registerClass(
|
||||
export const CtrlAltTabPopup = GObject.registerClass(
|
||||
class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup {
|
||||
_init(items) {
|
||||
super._init(items);
|
||||
|
|
@ -167,7 +171,7 @@ class CtrlAltTabPopup extends SwitcherPopup.SwitcherPopup {
|
|||
}
|
||||
});
|
||||
|
||||
var CtrlAltTabSwitcher = GObject.registerClass(
|
||||
export const CtrlAltTabSwitcher = GObject.registerClass(
|
||||
class CtrlAltTabSwitcher extends SwitcherPopup.SwitcherList {
|
||||
_init(items) {
|
||||
super._init(true);
|
||||
|
|
|
|||
|
|
@ -1,29 +1,34 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Dash */
|
||||
|
||||
const { Clutter, GLib, GObject,
|
||||
Graphene, Meta, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Graphene from 'gi://Graphene';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const AppFavorites = imports.ui.appFavorites;
|
||||
const DND = imports.ui.dnd;
|
||||
const IconGrid = imports.ui.iconGrid;
|
||||
const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
import * as AppDisplay from './appDisplay.js';
|
||||
import * as AppFavorites from './appFavorites.js';
|
||||
import * as DND from './dnd.js';
|
||||
import * as IconGrid from './iconGrid.js';
|
||||
import * as Overview from './overview.js';
|
||||
import Main from './main.js';
|
||||
|
||||
var DASH_ANIMATION_TIME = 200;
|
||||
var DASH_ITEM_LABEL_SHOW_TIME = 150;
|
||||
var DASH_ITEM_LABEL_HIDE_TIME = 100;
|
||||
var DASH_ITEM_HOVER_TIMEOUT = 300;
|
||||
export const DASH_ANIMATION_TIME = 200;
|
||||
export const DASH_ITEM_LABEL_SHOW_TIME = 150;
|
||||
export const DASH_ITEM_LABEL_HIDE_TIME = 100;
|
||||
export const DASH_ITEM_HOVER_TIMEOUT = 300;
|
||||
|
||||
function getAppFromSource(source) {
|
||||
export function getAppFromSource(source) {
|
||||
if (source instanceof AppDisplay.AppIcon)
|
||||
return source.app;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
var DashIcon = GObject.registerClass(
|
||||
export const DashIcon = GObject.registerClass(
|
||||
class DashIcon extends AppDisplay.AppIcon {
|
||||
_init(app) {
|
||||
super._init(app, {
|
||||
|
|
@ -54,7 +59,7 @@ class DashIcon extends AppDisplay.AppIcon {
|
|||
|
||||
// A container like StBin, but taking the child's scale into account
|
||||
// when requesting a size
|
||||
var DashItemContainer = GObject.registerClass(
|
||||
export const DashItemContainer = GObject.registerClass(
|
||||
class DashItemContainer extends St.Widget {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -74,6 +79,7 @@ class DashItemContainer extends St.Widget {
|
|||
Main.layoutManager.addChrome(this.label);
|
||||
this.label_actor = this.label;
|
||||
|
||||
/** @type {St.Bin | null} */
|
||||
this.child = null;
|
||||
this.animatingOut = false;
|
||||
|
||||
|
|
@ -146,6 +152,9 @@ class DashItemContainer extends St.Widget {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {St.Bin} actor
|
||||
*/
|
||||
setChild(actor) {
|
||||
if (this.child == actor)
|
||||
return;
|
||||
|
|
@ -191,7 +200,7 @@ class DashItemContainer extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var ShowAppsIcon = GObject.registerClass(
|
||||
export const ShowAppsIcon = GObject.registerClass(
|
||||
class ShowAppsIcon extends DashItemContainer {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -270,7 +279,7 @@ class ShowAppsIcon extends DashItemContainer {
|
|||
}
|
||||
});
|
||||
|
||||
var DragPlaceholderItem = GObject.registerClass(
|
||||
export const DragPlaceholderItem = GObject.registerClass(
|
||||
class DragPlaceholderItem extends DashItemContainer {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -278,7 +287,7 @@ class DragPlaceholderItem extends DashItemContainer {
|
|||
}
|
||||
});
|
||||
|
||||
var EmptyDropTargetItem = GObject.registerClass(
|
||||
export const EmptyDropTargetItem = GObject.registerClass(
|
||||
class EmptyDropTargetItem extends DashItemContainer {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -294,6 +303,7 @@ class DashIconsLayout extends Clutter.BoxLayout {
|
|||
});
|
||||
}
|
||||
|
||||
/** @returns {[number, number]} */
|
||||
vfunc_get_preferred_width(container, forHeight) {
|
||||
const [, natWidth] = super.vfunc_get_preferred_width(container, forHeight);
|
||||
return [0, natWidth];
|
||||
|
|
@ -302,7 +312,7 @@ class DashIconsLayout extends Clutter.BoxLayout {
|
|||
|
||||
const baseIconSizes = [16, 22, 24, 32, 48, 64];
|
||||
|
||||
var Dash = GObject.registerClass({
|
||||
export const Dash = GObject.registerClass({
|
||||
Signals: { 'icon-size-changed': {} },
|
||||
}, class Dash extends St.Widget {
|
||||
_init() {
|
||||
|
|
@ -330,6 +340,7 @@ var Dash = GObject.registerClass({
|
|||
y_expand: true,
|
||||
});
|
||||
|
||||
/** @type {St.Widget<DashIconsLayout["prototype"], Clutter.Content, St.Widget | DashItemContainer["prototype"]>} */
|
||||
this._box = new St.Widget({
|
||||
clip_to_allocation: true,
|
||||
layout_manager: new DashIconsLayout(),
|
||||
|
|
@ -507,6 +518,10 @@ var Dash = GObject.registerClass({
|
|||
});
|
||||
|
||||
let item = new DashItemContainer();
|
||||
|
||||
// TODO: I don't know why this type error is occuring.
|
||||
// I'm guessing it is an issue with the complicated inheritance.
|
||||
// @ts-expect-error
|
||||
item.setChild(appIcon);
|
||||
|
||||
// Override default AppIcon label_actor, now the
|
||||
|
|
@ -574,9 +589,16 @@ var Dash = GObject.registerClass({
|
|||
// icons (i.e. ignoring drag placeholders) and which are not
|
||||
// animating out (which means they will be destroyed at the end of
|
||||
// the animation)
|
||||
let iconChildren = this._box.get_children().filter(actor => {
|
||||
return actor.child &&
|
||||
let iconChildren = this._box.get_children().filter(
|
||||
/**
|
||||
* @param {Clutter.Actor} actor
|
||||
* @returns {actor is DashItemContainer["prototype"]}
|
||||
*/
|
||||
(actor) => {
|
||||
return actor instanceof DashItemContainer &&
|
||||
actor.child &&
|
||||
actor.child._delegate &&
|
||||
// @ts-expect-error
|
||||
actor.child._delegate.icon &&
|
||||
!actor.animatingOut;
|
||||
});
|
||||
|
|
@ -598,7 +620,7 @@ var Dash = GObject.registerClass({
|
|||
let spacing = themeNode.get_length('spacing');
|
||||
|
||||
let firstButton = iconChildren[0].child;
|
||||
let firstIcon = firstButton._delegate.icon;
|
||||
let firstIcon = /** @type {typeof AppDisplay.AppIcon["prototype"]} */ (firstButton._delegate).icon;
|
||||
|
||||
// Enforce valid spacings during the size request
|
||||
firstIcon.icon.ensure_style();
|
||||
|
|
@ -634,7 +656,7 @@ var Dash = GObject.registerClass({
|
|||
|
||||
let scale = oldIconSize / newIconSize;
|
||||
for (let i = 0; i < iconChildren.length; i++) {
|
||||
let icon = iconChildren[i].child._delegate.icon;
|
||||
let icon = /** @type {typeof AppDisplay.AppIcon["prototype"]} */ (iconChildren[i].child._delegate).icon;
|
||||
|
||||
// Set the new size immediately, to keep the icons' sizes
|
||||
// in sync with this.iconSize
|
||||
|
|
@ -676,13 +698,20 @@ var Dash = GObject.registerClass({
|
|||
|
||||
let running = this._appSystem.get_running();
|
||||
|
||||
// FIXME
|
||||
let children = this._box.get_children().filter(actor => {
|
||||
return actor.child &&
|
||||
actor.child._delegate &&
|
||||
actor.child._delegate.app;
|
||||
return 'child' in actor && actor.child &&
|
||||
/** @type {typeof AppDisplay.AppIcon["prototype"]} */ (actor.child._delegate).app &&
|
||||
/** @type {typeof AppDisplay.AppIcon["prototype"]} */ (actor.child._delegate).app;
|
||||
|
||||
});
|
||||
// Apps currently in the dash
|
||||
let oldApps = children.map(actor => actor.child._delegate.app);
|
||||
let oldApps = children.map(actor => 'child' in actor ? actor.child._delegate : null).filter(
|
||||
/**
|
||||
* @param {unknown} delegate '
|
||||
* @returns {delegate is typeof AppDisplay.AppIcon["prototype"]}
|
||||
*/
|
||||
delegate => delegate instanceof AppDisplay.AppIcon).map(d => d.app);
|
||||
// Apps supposed to be in the dash
|
||||
let newApps = [];
|
||||
|
||||
|
|
@ -749,7 +778,8 @@ var Dash = GObject.registerClass({
|
|||
? newApps[newIndex + 1] : null;
|
||||
let insertHere = nextApp && nextApp == oldApp;
|
||||
let alreadyRemoved = removedActors.reduce((result, actor) => {
|
||||
let removedApp = actor.child._delegate.app;
|
||||
let removedApp = /** @type {typeof AppDisplay.AppIcon["prototype"]} */ (actor.child._delegate).app;
|
||||
|
||||
return result || removedApp == newApp;
|
||||
}, false);
|
||||
|
||||
|
|
@ -773,9 +803,10 @@ var Dash = GObject.registerClass({
|
|||
for (let i = 0; i < removedActors.length; i++) {
|
||||
let item = removedActors[i];
|
||||
|
||||
// FIXME
|
||||
// Don't animate item removal when the overview is transitioning
|
||||
// or hidden
|
||||
if (Main.overview.visible && !Main.overview.animationInProgress)
|
||||
if (Main.overview.visible && !Main.overview.animationInProgress && 'animateOutAndDestroy' in item)
|
||||
item.animateOutAndDestroy();
|
||||
else
|
||||
item.destroy();
|
||||
|
|
@ -947,7 +978,7 @@ var Dash = GObject.registerClass({
|
|||
children[i] == this._dragPlaceholder)
|
||||
continue;
|
||||
|
||||
let childId = children[i].child._delegate.app.get_id();
|
||||
let childId = /** @type {typeof AppDisplay.AppIcon["prototype"]} */ (children[i].child._delegate).app.get_id();
|
||||
if (childId == id)
|
||||
continue;
|
||||
if (childId in favorites)
|
||||
|
|
|
|||
|
|
@ -1,17 +1,24 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported DateMenuButton */
|
||||
|
||||
const { Clutter, Gio, GLib, GnomeDesktop,
|
||||
GObject, GWeather, Pango, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GnomeDesktop from 'gi://GnomeDesktop';
|
||||
import GObject from 'gi://GObject';
|
||||
import GWeather from 'gi://GWeather';
|
||||
import Pango from 'gi://Pango';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Util = imports.misc.util;
|
||||
const Main = imports.ui.main;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const Calendar = imports.ui.calendar;
|
||||
const Weather = imports.misc.weather;
|
||||
const System = imports.system;
|
||||
import * as Util from '../misc/util.js';
|
||||
import Main from './main.js';
|
||||
import * as PanelMenu from './panelMenu.js';
|
||||
import * as Calendar from './calendar.js';
|
||||
import * as Weather from '../misc/weather.js';
|
||||
import System from 'system';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
const NC_ = (context, str) => '%s\u0004%s'.format(context, str);
|
||||
const T_ = Shell.util_translate_time_string;
|
||||
|
|
@ -24,7 +31,7 @@ const ClocksProxy = Gio.DBusProxy.makeProxyWrapper(ClocksIntegrationIface);
|
|||
|
||||
function _isToday(date) {
|
||||
let now = new Date();
|
||||
return now.getYear() == date.getYear() &&
|
||||
return now.getFullYear() == date.getFullYear() &&
|
||||
now.getMonth() == date.getMonth() &&
|
||||
now.getDate() == date.getDate();
|
||||
}
|
||||
|
|
@ -33,8 +40,11 @@ function _gDateTimeToDate(datetime) {
|
|||
return new Date(datetime.to_unix() * 1000 + datetime.get_microsecond() / 1000);
|
||||
}
|
||||
|
||||
var TodayButton = GObject.registerClass(
|
||||
export const TodayButton = GObject.registerClass(
|
||||
class TodayButton extends St.Button {
|
||||
/**
|
||||
* @param {*} calendar
|
||||
*/
|
||||
_init(calendar) {
|
||||
// Having the ability to go to the current date if the user is already
|
||||
// on the current date can be confusing. So don't make the button reactive
|
||||
|
|
@ -88,7 +98,7 @@ class TodayButton extends St.Button {
|
|||
}
|
||||
});
|
||||
|
||||
var EventsSection = GObject.registerClass(
|
||||
export const EventsSection = GObject.registerClass(
|
||||
class EventsSection extends St.Button {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -126,7 +136,11 @@ class EventsSection extends St.Button {
|
|||
this._appInstalledChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Date} date
|
||||
*/
|
||||
setDate(date) {
|
||||
/** @type {[number, number, number]} */
|
||||
const day = [date.getFullYear(), date.getMonth(), date.getDate()];
|
||||
this._startDate = new Date(...day);
|
||||
this._endDate = new Date(...day, 23, 59, 59, 999);
|
||||
|
|
@ -158,9 +172,9 @@ class EventsSection extends St.Button {
|
|||
|
||||
if (this._startDate <= now && now <= this._endDate)
|
||||
this._title.text = _('Today');
|
||||
else if (this._endDate < now && now - this._endDate < timeSpanDay)
|
||||
else if (this._endDate < now && now.getTime() - this._endDate.getTime() < timeSpanDay)
|
||||
this._title.text = _('Yesterday');
|
||||
else if (this._startDate > now && this._startDate - now < timeSpanDay)
|
||||
else if (this._startDate > now && this._startDate.getTime() - now.getTime() < timeSpanDay)
|
||||
this._title.text = _('Tomorrow');
|
||||
else if (this._startDate.getFullYear() === now.getFullYear())
|
||||
this._title.text = this._startDate.toLocaleFormat(sameYearFormat);
|
||||
|
|
@ -270,7 +284,7 @@ class EventsSection extends St.Button {
|
|||
}
|
||||
});
|
||||
|
||||
var WorldClocksSection = GObject.registerClass(
|
||||
export const WorldClocksSection = GObject.registerClass(
|
||||
class WorldClocksSection extends St.Button {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -331,7 +345,7 @@ class WorldClocksSection extends St.Button {
|
|||
this._locations = [];
|
||||
|
||||
let world = GWeather.Location.get_world();
|
||||
let clocks = this._settings.get_value('locations').deep_unpack();
|
||||
let clocks = /** @type {GLib.Variant<'av'>} */ (this._settings.get_value('locations')).deep_unpack();
|
||||
for (let i = 0; i < clocks.length; i++) {
|
||||
let l = world.deserialize(clocks[i]);
|
||||
if (l && l.get_timezone() != null)
|
||||
|
|
@ -466,7 +480,7 @@ class WorldClocksSection extends St.Button {
|
|||
}
|
||||
});
|
||||
|
||||
var WeatherSection = GObject.registerClass(
|
||||
export const WeatherSection = GObject.registerClass(
|
||||
class WeatherSection extends St.Button {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -602,6 +616,9 @@ class WeatherSection extends St.Button {
|
|||
layout.attach(label, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GWeather.Location} loc
|
||||
*/
|
||||
_findBestLocationName(loc) {
|
||||
const locName = loc.get_name();
|
||||
|
||||
|
|
@ -659,7 +676,7 @@ class WeatherSection extends St.Button {
|
|||
}
|
||||
});
|
||||
|
||||
var MessagesIndicator = GObject.registerClass(
|
||||
export const MessagesIndicator = GObject.registerClass(
|
||||
class MessagesIndicator extends St.Icon {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -720,13 +737,17 @@ class MessagesIndicator extends St.Icon {
|
|||
}
|
||||
});
|
||||
|
||||
var FreezableBinLayout = GObject.registerClass(
|
||||
export const FreezableBinLayout = GObject.registerClass(
|
||||
class FreezableBinLayout extends Clutter.BinLayout {
|
||||
_init() {
|
||||
super._init();
|
||||
|
||||
this._frozen = false;
|
||||
|
||||
/** @type {[number, number]} */
|
||||
this._savedWidth = [NaN, NaN];
|
||||
|
||||
/** @type {[number, number]} */
|
||||
this._savedHeight = [NaN, NaN];
|
||||
}
|
||||
|
||||
|
|
@ -739,6 +760,9 @@ class FreezableBinLayout extends Clutter.BinLayout {
|
|||
this.layout_changed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(container, forHeight) {
|
||||
if (!this._frozen || this._savedWidth.some(isNaN))
|
||||
return super.vfunc_get_preferred_width(container, forHeight);
|
||||
|
|
@ -760,8 +784,11 @@ class FreezableBinLayout extends Clutter.BinLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var CalendarColumnLayout = GObject.registerClass(
|
||||
export const CalendarColumnLayout = GObject.registerClass(
|
||||
class CalendarColumnLayout extends Clutter.BoxLayout {
|
||||
/**
|
||||
* @param {*} actors
|
||||
*/
|
||||
_init(actors) {
|
||||
super._init({ orientation: Clutter.Orientation.VERTICAL });
|
||||
this._colActors = actors;
|
||||
|
|
@ -779,7 +806,7 @@ class CalendarColumnLayout extends Clutter.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var DateMenuButton = GObject.registerClass(
|
||||
export const DateMenuButton = GObject.registerClass(
|
||||
class DateMenuButton extends PanelMenu.Button {
|
||||
_init() {
|
||||
let hbox;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Dialog, MessageDialogContent, ListSection, ListSectionItem */
|
||||
|
||||
const { Clutter, GLib, GObject, Meta, Pango, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Pango from 'gi://Pango';
|
||||
import St from 'gi://St';
|
||||
|
||||
|
||||
function _setLabel(label, value) {
|
||||
label.set({
|
||||
|
|
@ -10,8 +16,12 @@ function _setLabel(label, value) {
|
|||
});
|
||||
}
|
||||
|
||||
var Dialog = GObject.registerClass(
|
||||
export const Dialog = GObject.registerClass(
|
||||
class Dialog extends St.Widget {
|
||||
/**
|
||||
* @param {*} parentActor
|
||||
* @param {*} styleClass
|
||||
*/
|
||||
_init(parentActor, styleClass) {
|
||||
super._init({ layout_manager: new Clutter.BinLayout() });
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
|
@ -157,7 +167,7 @@ class Dialog extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var MessageDialogContent = GObject.registerClass({
|
||||
export const MessageDialogContent = GObject.registerClass({
|
||||
Properties: {
|
||||
'title': GObject.ParamSpec.string(
|
||||
'title', 'title', 'title',
|
||||
|
|
@ -171,6 +181,9 @@ var MessageDialogContent = GObject.registerClass({
|
|||
null),
|
||||
},
|
||||
}, class MessageDialogContent extends St.BoxLayout {
|
||||
/**
|
||||
* @param {*} params
|
||||
*/
|
||||
_init(params) {
|
||||
this._title = new St.Label({ style_class: 'message-dialog-title' });
|
||||
this._description = new St.Label({ style_class: 'message-dialog-description' });
|
||||
|
|
@ -247,7 +260,7 @@ var MessageDialogContent = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ListSection = GObject.registerClass({
|
||||
export const ListSection = GObject.registerClass({
|
||||
Properties: {
|
||||
'title': GObject.ParamSpec.string(
|
||||
'title', 'title', 'title',
|
||||
|
|
@ -256,6 +269,9 @@ var ListSection = GObject.registerClass({
|
|||
null),
|
||||
},
|
||||
}, class ListSection extends St.BoxLayout {
|
||||
/**
|
||||
* @param {*} params
|
||||
*/
|
||||
_init(params) {
|
||||
this._title = new St.Label({ style_class: 'dialog-list-title' });
|
||||
|
||||
|
|
@ -292,7 +308,7 @@ var ListSection = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ListSectionItem = GObject.registerClass({
|
||||
export const ListSectionItem = GObject.registerClass({
|
||||
Properties: {
|
||||
'icon-actor': GObject.ParamSpec.object(
|
||||
'icon-actor', 'icon-actor', 'Icon actor',
|
||||
|
|
@ -310,6 +326,9 @@ var ListSectionItem = GObject.registerClass({
|
|||
null),
|
||||
},
|
||||
}, class ListSectionItem extends St.BoxLayout {
|
||||
/**
|
||||
* @param {*} params
|
||||
*/
|
||||
_init(params) {
|
||||
this._iconActorBin = new St.Bin();
|
||||
|
||||
|
|
|
|||
95
js/ui/dnd.js
95
js/ui/dnd.js
|
|
@ -1,43 +1,87 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported addDragMonitor, removeDragMonitor, makeDraggable */
|
||||
|
||||
const { Clutter, GLib, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
import Main from './main.js';
|
||||
|
||||
// Time to scale down to maxDragActorSize
|
||||
var SCALE_ANIMATION_TIME = 250;
|
||||
export let SCALE_ANIMATION_TIME = 250;
|
||||
// Time to animate to original position on cancel
|
||||
var SNAP_BACK_ANIMATION_TIME = 250;
|
||||
export let SNAP_BACK_ANIMATION_TIME = 250;
|
||||
// Time to animate to original position on success
|
||||
var REVERT_ANIMATION_TIME = 750;
|
||||
export let REVERT_ANIMATION_TIME = 750;
|
||||
|
||||
var DragMotionResult = {
|
||||
/** @typedef {{ getDragActor<T extends Clutter.Actor = Clutter.Actor>(): T }} DragActorContainer */
|
||||
/** @typedef {{ getDragActorSource<T extends Clutter.Actor = Clutter.Actor>(): T }} DragActorSourceContainer */
|
||||
/** @typedef {{ handleDragOver(source: Clutter.Actor | Signals.EventEmitter, actor: Clutter.Actor, x: number, y: number, time: number): DragMotionResult }} DragOverTarget */
|
||||
/** @typedef {{ acceptDrop(source: Clutter.Actor | Signals.EventEmitter, actor: Clutter.Actor, x: number, y: number, time: number): boolean }} DropTarget */
|
||||
|
||||
/**
|
||||
* @param {unknown} delegate
|
||||
* @returns {delegate is DragActorContainer}
|
||||
*/
|
||||
function hasDragActor(delegate) {
|
||||
return !!(/** @type {DragActorContainer} */ (delegate).getDragActor);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} delegate
|
||||
* @returns {delegate is DragActorSourceContainer}
|
||||
*/
|
||||
function hasDragActorSource(delegate) {
|
||||
return !!(/** @type {DragActorSourceContainer} */ (delegate).getDragActorSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} delegate
|
||||
* @returns {delegate is DragOverTarget}
|
||||
*/
|
||||
export function handlesDragOver(delegate) {
|
||||
return !!(/** @type {DragOverTarget} */ (delegate).handleDragOver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {unknown} delegate
|
||||
* @returns {delegate is DropTarget}
|
||||
*/
|
||||
function isDropTarget(delegate) {
|
||||
return !!(/** @type {DropTarget} */ (delegate).acceptDrop);
|
||||
}
|
||||
|
||||
/** @enum {number} */
|
||||
export const DragMotionResult = {
|
||||
NO_DROP: 0,
|
||||
COPY_DROP: 1,
|
||||
MOVE_DROP: 2,
|
||||
CONTINUE: 3,
|
||||
};
|
||||
|
||||
var DragState = {
|
||||
/** @enum {number} */
|
||||
export const DragState = {
|
||||
INIT: 0,
|
||||
DRAGGING: 1,
|
||||
CANCELLED: 2,
|
||||
};
|
||||
|
||||
var DRAG_CURSOR_MAP = {
|
||||
export const DRAG_CURSOR_MAP = {
|
||||
0: Meta.Cursor.DND_UNSUPPORTED_TARGET,
|
||||
1: Meta.Cursor.DND_COPY,
|
||||
2: Meta.Cursor.DND_MOVE,
|
||||
};
|
||||
|
||||
var DragDropResult = {
|
||||
export const DragDropResult = {
|
||||
FAILURE: 0,
|
||||
SUCCESS: 1,
|
||||
CONTINUE: 2,
|
||||
};
|
||||
var dragMonitors = [];
|
||||
export let dragMonitors = [];
|
||||
|
||||
let eventHandlerActor = null;
|
||||
let currentDraggable = null;
|
||||
|
|
@ -64,11 +108,11 @@ function _getRealActorScale(actor) {
|
|||
return scale;
|
||||
}
|
||||
|
||||
function addDragMonitor(monitor) {
|
||||
export function addDragMonitor(monitor) {
|
||||
dragMonitors.push(monitor);
|
||||
}
|
||||
|
||||
function removeDragMonitor(monitor) {
|
||||
export function removeDragMonitor(monitor) {
|
||||
for (let i = 0; i < dragMonitors.length; i++) {
|
||||
if (dragMonitors[i] == monitor) {
|
||||
dragMonitors.splice(i, 1);
|
||||
|
|
@ -77,7 +121,20 @@ function removeDragMonitor(monitor) {
|
|||
}
|
||||
}
|
||||
|
||||
var _Draggable = class _Draggable extends Signals.EventEmitter {
|
||||
// FIXME
|
||||
/**
|
||||
* @typedef {object} _DraggableParams
|
||||
* @property {boolean} [manualMode]
|
||||
* @property {number} [timeoutThreshold]
|
||||
* @property {boolean} [restoreOnSuccess]
|
||||
* @property {number} [dragActorMaxSize]
|
||||
* @property {number} [dragActorOpacity]
|
||||
*/
|
||||
export class _Draggable extends Signals.EventEmitter {
|
||||
/**
|
||||
* @param {Clutter.Actor} actor
|
||||
* @param {Partial<_DraggableParams>} [params]
|
||||
*/
|
||||
constructor(actor, params = {}) {
|
||||
super();
|
||||
|
||||
|
|
@ -358,7 +415,7 @@ var _Draggable = class _Draggable extends Signals.EventEmitter {
|
|||
|
||||
let scaledWidth, scaledHeight;
|
||||
|
||||
if (this.actor._delegate && this.actor._delegate.getDragActor) {
|
||||
if (this.actor._delegate && hasDragActor(this.actor._delegate)) {
|
||||
this._dragActor = this.actor._delegate.getDragActor();
|
||||
Main.uiGroup.add_child(this._dragActor);
|
||||
Main.uiGroup.set_child_above_sibling(this._dragActor, null);
|
||||
|
|
@ -367,7 +424,7 @@ var _Draggable = class _Draggable extends Signals.EventEmitter {
|
|||
// Drag actor does not always have to be the same as actor. For example drag actor
|
||||
// can be an image that's part of the actor. So to perform "snap back" correctly we need
|
||||
// to know what was the drag actor source.
|
||||
if (this.actor._delegate.getDragActorSource) {
|
||||
if (hasDragActorSource(this.actor._delegate)) {
|
||||
this._dragActorSource = this.actor._delegate.getDragActorSource();
|
||||
// If the user dragged from the source, then position
|
||||
// the dragActor over it. Otherwise, center it
|
||||
|
|
@ -570,7 +627,7 @@ var _Draggable = class _Draggable extends Signals.EventEmitter {
|
|||
dragEvent.targetActor.disconnect(targetActorDestroyHandlerId);
|
||||
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.handleDragOver) {
|
||||
if (target._delegate && handlesDragOver(target._delegate)) {
|
||||
let [r_, targX, targY] = target.transform_stage_point(this._dragX, this._dragY);
|
||||
// We currently loop through all parents on drag-over even if one of the children has handled it.
|
||||
// We can check the return value of the function and break the loop if it's true if we don't want
|
||||
|
|
@ -643,7 +700,7 @@ var _Draggable = class _Draggable extends Signals.EventEmitter {
|
|||
this._dragCancellable = false;
|
||||
|
||||
while (target) {
|
||||
if (target._delegate && target._delegate.acceptDrop) {
|
||||
if (target._delegate && isDropTarget(target._delegate)) {
|
||||
let [r_, targX, targY] = target.transform_stage_point(dropX, dropY);
|
||||
let accepted = false;
|
||||
try {
|
||||
|
|
@ -842,6 +899,6 @@ var _Draggable = class _Draggable extends Signals.EventEmitter {
|
|||
* target wants to reuse the actor, it's up to the drop target to
|
||||
* reset these values.
|
||||
*/
|
||||
function makeDraggable(actor, params) {
|
||||
export function makeDraggable(actor, params) {
|
||||
return new _Draggable(actor, params);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,26 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported EdgeDragAction */
|
||||
|
||||
const { Clutter, GObject, Meta, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
import Main from './main.js';
|
||||
|
||||
var EDGE_THRESHOLD = 20;
|
||||
var DRAG_DISTANCE = 80;
|
||||
export const EDGE_THRESHOLD = 20;
|
||||
export const DRAG_DISTANCE = 80;
|
||||
|
||||
var EdgeDragAction = GObject.registerClass({
|
||||
export const EdgeDragAction = GObject.registerClass({
|
||||
Signals: {
|
||||
'activated': {},
|
||||
'progress': { param_types: [GObject.TYPE_DOUBLE] },
|
||||
},
|
||||
}, class EdgeDragAction extends Clutter.GestureAction {
|
||||
/**
|
||||
* @param {*} side
|
||||
* @param {*} allowedModes
|
||||
*/
|
||||
_init(side, allowedModes) {
|
||||
super._init();
|
||||
this._side = side;
|
||||
|
|
|
|||
|
|
@ -17,17 +17,26 @@
|
|||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
const { AccountsService, Clutter, Gio,
|
||||
GLib, GObject, Pango, Polkit, Shell, St, UPowerGlib: UPower } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Gio from 'gi://Gio';
|
||||
|
||||
const CheckBox = imports.ui.checkBox;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const LoginManager = imports.misc.loginManager;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const UserWidget = imports.ui.userWidget;
|
||||
import AccountsService from 'gi://AccountsService';
|
||||
import Pango from 'gi://Pango';
|
||||
import Polkit from 'gi://Polkit';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import UPower from 'gi://UPowerGlib';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import * as CheckBox from './checkBox.js';
|
||||
import * as Dialog from './dialog.js';
|
||||
import * as GnomeSession from '../misc/gnomeSession.js';
|
||||
import * as LoginManager from '../misc/loginManager.js';
|
||||
import * as ModalDialog from './modalDialog.js';
|
||||
import * as UserWidget from './userWidget.js';
|
||||
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
const _ITEM_ICON_SIZE = 64;
|
||||
|
||||
|
|
@ -151,7 +160,7 @@ const DialogContent = {
|
|||
4 /* DialogType.UPGRADE_RESTART */: restartUpgradeDialogContent,
|
||||
};
|
||||
|
||||
var MAX_USERS_IN_SESSION_DIALOG = 5;
|
||||
export let MAX_USERS_IN_SESSION_DIALOG = 5;
|
||||
|
||||
const LogindSessionIface = loadInterfaceXML('org.freedesktop.login1.Session');
|
||||
const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
|
||||
|
|
@ -216,14 +225,22 @@ function _setCheckBoxLabel(checkBox, text) {
|
|||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
export function init() {
|
||||
// This always returns the same singleton object
|
||||
// By instantiating it initially, we register the
|
||||
// bus object, etc.
|
||||
new EndSessionDialog();
|
||||
}
|
||||
|
||||
var EndSessionDialog = GObject.registerClass(
|
||||
/** @typedef {{ name?: string; version?: string; }} PreparedUpgradeInfo */
|
||||
/** @typedef {{
|
||||
UpdateTriggered: boolean,
|
||||
UpdatePrepared: boolean,
|
||||
UpgradeTriggered: boolean,
|
||||
PreparedUpgrade: PreparedUpgradeInfo }
|
||||
} UpdateInfo */
|
||||
|
||||
export const EndSessionDialog = GObject.registerClass(
|
||||
class EndSessionDialog extends ModalDialog.ModalDialog {
|
||||
_init() {
|
||||
super._init({ styleClass: 'end-session-dialog',
|
||||
|
|
@ -650,7 +667,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
|||
let n = 0;
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
let [id_, uid_, userName, seat_, sessionPath] = result[i];
|
||||
let proxy = new LogindSession(Gio.DBus.system, 'org.freedesktop.login1', sessionPath);
|
||||
let proxy = LogindSession(Gio.DBus.system, 'org.freedesktop.login1', sessionPath);
|
||||
|
||||
if (proxy.Class != 'user')
|
||||
continue;
|
||||
|
|
@ -662,7 +679,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
|||
if (!sessionId) {
|
||||
this._loginManager.getCurrentSessionProxy(currentSessionProxy => {
|
||||
sessionId = currentSessionProxy.Id;
|
||||
log('endSessionDialog: No XDG_SESSION_ID, fetched from logind: %d'.format(sessionId));
|
||||
log('endSessionDialog: No XDG_SESSION_ID, fetched from logind: %s'.format(sessionId));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -706,6 +723,9 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Promise<UpdateInfo>}
|
||||
*/
|
||||
async _getUpdateInfo() {
|
||||
const connection = this._pkOfflineProxy.get_connection();
|
||||
const reply = await connection.call(
|
||||
|
|
@ -714,12 +734,14 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
|||
'org.freedesktop.DBus.Properties',
|
||||
'GetAll',
|
||||
new GLib.Variant('(s)', [this._pkOfflineProxy.g_interface_name]),
|
||||
null,
|
||||
new GLib.VariantType('(a{sv})'),
|
||||
Gio.DBusCallFlags.NONE,
|
||||
-1,
|
||||
null);
|
||||
|
||||
const [info] = reply.recursiveUnpack();
|
||||
return info;
|
||||
|
||||
return /** @type {UpdateInfo} */ (info);
|
||||
}
|
||||
|
||||
async OpenAsync(parameters, invocation) {
|
||||
|
|
@ -764,7 +786,7 @@ class EndSessionDialog extends ModalDialog.ModalDialog {
|
|||
let dialogContent = DialogContent[this._type];
|
||||
|
||||
for (let i = 0; i < inhibitorObjectPaths.length; i++) {
|
||||
let inhibitor = new GnomeSession.Inhibitor(inhibitorObjectPaths[i], proxy => {
|
||||
let inhibitor = GnomeSession.Inhibitor(inhibitorObjectPaths[i], proxy => {
|
||||
this._onInhibitorLoaded(proxy);
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -3,27 +3,34 @@
|
|||
|
||||
const Config = imports.misc.config;
|
||||
|
||||
imports.gi.versions.Clutter = Config.LIBMUTTER_API_VERSION;
|
||||
imports.gi.versions.Gio = '2.0';
|
||||
imports.gi.versions.GdkPixbuf = '2.0';
|
||||
imports.gi.versions.Gtk = '3.0';
|
||||
imports.gi.versions.Soup = '3.0';
|
||||
imports.gi.versions.TelepathyGLib = '0.12';
|
||||
imports.gi.versions.TelepathyLogger = '0.2';
|
||||
import gi from "gi";
|
||||
import "gi://Gio?version=2.0";
|
||||
import "gi://GdkPixbuf?version=2.0";
|
||||
import "gi://Gtk?version=3.0";
|
||||
import "gi://TelepathyGLib?version=0.12";
|
||||
import "gi://TelepathyLogger?version=0.2";
|
||||
|
||||
import Gio from "gi://Gio";
|
||||
import GLib from "gi://GLib";
|
||||
import GObject from "gi://GObject";
|
||||
import Meta from "gi://Meta";
|
||||
import Polkit from "gi://Polkit";
|
||||
import Shell from "gi://Shell";
|
||||
import St from "gi://St";
|
||||
import * as Gettext from "gettext";
|
||||
import System from "system";
|
||||
// import * as ExtensionUtils from '../misc/extensionUtils.js';
|
||||
|
||||
try {
|
||||
if (Config.HAVE_SOUP2)
|
||||
throw new Error('Soup3 support not enabled');
|
||||
const Soup_ = imports.gi.Soup;
|
||||
if (Config.HAVE_SOUP2)
|
||||
throw new Error('Soup3 support not enabled');
|
||||
const Soup_ = gi.require('Soup', '3.0');
|
||||
} catch (e) {
|
||||
imports.gi.versions.Soup = '2.4';
|
||||
const { Soup } = imports.gi;
|
||||
_injectSoup3Compat(Soup);
|
||||
const Soup = gi.require('Soup', '2.4');
|
||||
_injectSoup3Compat(Soup);
|
||||
}
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Polkit, Shell, St } = imports.gi;
|
||||
const Gettext = imports.gettext;
|
||||
const System = imports.system;
|
||||
const Clutter = gi.require("Clutter", Config.LIBMUTTER_API_VERSION);
|
||||
|
||||
Gio._promisify(Gio.DataInputStream.prototype, 'fill_async', 'fill_finish');
|
||||
Gio._promisify(Gio.DataInputStream.prototype,
|
||||
|
|
@ -42,41 +49,37 @@ let _localTimeZone = null;
|
|||
// variable initializations, etc, that depend on init() already having
|
||||
// been run.
|
||||
|
||||
|
||||
// "monkey patch" in some varargs ClutterContainer methods; we need
|
||||
// to do this per-container class since there is no representation
|
||||
// of interfaces in Javascript
|
||||
function _patchContainerClass(containerClass) {
|
||||
// This one is a straightforward mapping of the C method
|
||||
containerClass.prototype.child_set = function (actor, props) {
|
||||
let meta = this.get_child_meta(actor);
|
||||
for (let prop in props)
|
||||
meta[prop] = props[prop];
|
||||
};
|
||||
// This one is a straightforward mapping of the C method
|
||||
containerClass.prototype.child_set = function (actor, props) {
|
||||
let meta = this.get_child_meta(actor);
|
||||
for (let prop in props) meta[prop] = props[prop];
|
||||
};
|
||||
|
||||
// clutter_container_add() actually is a an add-many-actors
|
||||
// method. We conveniently, but somewhat dubiously, take the
|
||||
// this opportunity to make it do something more useful.
|
||||
containerClass.prototype.add = function (actor, props) {
|
||||
this.add_actor(actor);
|
||||
if (props)
|
||||
this.child_set(actor, props);
|
||||
};
|
||||
// clutter_container_add() actually is a an add-many-actors
|
||||
// method. We conveniently, but somewhat dubiously, take the
|
||||
// this opportunity to make it do something more useful.
|
||||
containerClass.prototype.add = function (actor, props) {
|
||||
this.add_actor(actor);
|
||||
if (props) this.child_set(actor, props);
|
||||
};
|
||||
}
|
||||
|
||||
function _patchLayoutClass(layoutClass, styleProps) {
|
||||
if (styleProps) {
|
||||
layoutClass.prototype.hookup_style = function (container) {
|
||||
container.connect('style-changed', () => {
|
||||
let node = container.get_theme_node();
|
||||
for (let prop in styleProps) {
|
||||
let [found, length] = node.lookup_length(styleProps[prop], false);
|
||||
if (found)
|
||||
this[prop] = length;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
if (styleProps) {
|
||||
layoutClass.prototype.hookup_style = function (container) {
|
||||
container.connect("style-changed", () => {
|
||||
let node = container.get_theme_node();
|
||||
for (let prop in styleProps) {
|
||||
let [found, length] = node.lookup_length(styleProps[prop], false);
|
||||
if (found) this[prop] = length;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -116,331 +119,350 @@ function _injectSoup3Compat(Soup) {
|
|||
}
|
||||
|
||||
function _makeEaseCallback(params, cleanup) {
|
||||
let onComplete = params.onComplete;
|
||||
delete params.onComplete;
|
||||
let onComplete = params.onComplete;
|
||||
delete params.onComplete;
|
||||
|
||||
let onStopped = params.onStopped;
|
||||
delete params.onStopped;
|
||||
let onStopped = params.onStopped;
|
||||
delete params.onStopped;
|
||||
|
||||
return isFinished => {
|
||||
cleanup();
|
||||
return (isFinished) => {
|
||||
cleanup();
|
||||
|
||||
if (onStopped)
|
||||
onStopped(isFinished);
|
||||
if (onComplete && isFinished)
|
||||
onComplete();
|
||||
};
|
||||
if (onStopped) onStopped(isFinished);
|
||||
if (onComplete && isFinished) onComplete();
|
||||
};
|
||||
}
|
||||
|
||||
function _getPropertyTarget(actor, propName) {
|
||||
if (!propName.startsWith('@'))
|
||||
return [actor, propName];
|
||||
if (!propName.startsWith("@")) return [actor, propName];
|
||||
|
||||
let [type, name, prop] = propName.split('.');
|
||||
switch (type) {
|
||||
case '@layout':
|
||||
return [actor.layout_manager, name];
|
||||
case '@actions':
|
||||
return [actor.get_action(name), prop];
|
||||
case '@constraints':
|
||||
return [actor.get_constraint(name), prop];
|
||||
case '@content':
|
||||
return [actor.content, name];
|
||||
case '@effects':
|
||||
return [actor.get_effect(name), prop];
|
||||
}
|
||||
let [type, name, prop] = propName.split(".");
|
||||
switch (type) {
|
||||
case "@layout":
|
||||
return [actor.layout_manager, name];
|
||||
case "@actions":
|
||||
return [actor.get_action(name), prop];
|
||||
case "@constraints":
|
||||
return [actor.get_constraint(name), prop];
|
||||
case "@content":
|
||||
return [actor.content, name];
|
||||
case "@effects":
|
||||
return [actor.get_effect(name), prop];
|
||||
}
|
||||
|
||||
throw new Error(`Invalid property name ${propName}`);
|
||||
throw new Error(`Invalid property name ${propName}`);
|
||||
}
|
||||
|
||||
function _easeActor(actor, params) {
|
||||
actor.save_easing_state();
|
||||
actor.save_easing_state();
|
||||
|
||||
if (params.duration != undefined)
|
||||
actor.set_easing_duration(params.duration);
|
||||
delete params.duration;
|
||||
if (params.duration != undefined) actor.set_easing_duration(params.duration);
|
||||
delete params.duration;
|
||||
|
||||
if (params.delay != undefined)
|
||||
actor.set_easing_delay(params.delay);
|
||||
delete params.delay;
|
||||
if (params.delay != undefined) actor.set_easing_delay(params.delay);
|
||||
delete params.delay;
|
||||
|
||||
let repeatCount = 0;
|
||||
if (params.repeatCount != undefined)
|
||||
repeatCount = params.repeatCount;
|
||||
delete params.repeatCount;
|
||||
let repeatCount = 0;
|
||||
if (params.repeatCount != undefined) repeatCount = params.repeatCount;
|
||||
delete params.repeatCount;
|
||||
|
||||
let autoReverse = false;
|
||||
if (params.autoReverse != undefined)
|
||||
autoReverse = params.autoReverse;
|
||||
delete params.autoReverse;
|
||||
let autoReverse = false;
|
||||
if (params.autoReverse != undefined) autoReverse = params.autoReverse;
|
||||
delete params.autoReverse;
|
||||
|
||||
// repeatCount doesn't include the initial iteration
|
||||
const numIterations = repeatCount + 1;
|
||||
// whether the transition should finish where it started
|
||||
const isReversed = autoReverse && numIterations % 2 === 0;
|
||||
// repeatCount doesn't include the initial iteration
|
||||
const numIterations = repeatCount + 1;
|
||||
// whether the transition should finish where it started
|
||||
const isReversed = autoReverse && numIterations % 2 === 0;
|
||||
|
||||
if (params.mode != undefined)
|
||||
actor.set_easing_mode(params.mode);
|
||||
delete params.mode;
|
||||
if (params.mode != undefined) actor.set_easing_mode(params.mode);
|
||||
delete params.mode;
|
||||
|
||||
const prepare = () => {
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
global.begin_work();
|
||||
};
|
||||
const cleanup = () => {
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
global.end_work();
|
||||
};
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
const prepare = () => {
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
global.begin_work();
|
||||
};
|
||||
const cleanup = () => {
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
global.end_work();
|
||||
};
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
// cancel overwritten transitions
|
||||
let animatedProps = Object.keys(params).map(p => p.replace('_', '-', 'g'));
|
||||
animatedProps.forEach(p => actor.remove_transition(p));
|
||||
// cancel overwritten transitions
|
||||
let animatedProps = Object.keys(params).map((p) => p.replace(/_/g, "-"));
|
||||
animatedProps.forEach((p) => actor.remove_transition(p));
|
||||
|
||||
if (actor.get_easing_duration() > 0 || !isReversed)
|
||||
actor.set(params);
|
||||
actor.restore_easing_state();
|
||||
if (actor.get_easing_duration() > 0 || !isReversed) actor.set(params);
|
||||
actor.restore_easing_state();
|
||||
|
||||
let transition = animatedProps.map(p => actor.get_transition(p))
|
||||
.find(t => t !== null);
|
||||
let transition = animatedProps.map((p) => actor.get_transition(p)).find((t) => t !== null);
|
||||
|
||||
if (transition && transition.delay)
|
||||
transition.connect('started', () => prepare());
|
||||
else
|
||||
prepare();
|
||||
if (transition && transition.delay) transition.connect("started", () => prepare());
|
||||
else prepare();
|
||||
|
||||
if (transition) {
|
||||
transition.set({ repeatCount, autoReverse });
|
||||
transition.connect('stopped', (t, finished) => callback(finished));
|
||||
} else {
|
||||
callback(true);
|
||||
}
|
||||
if (transition) {
|
||||
transition.set({ repeatCount, autoReverse });
|
||||
transition.connect("stopped", (t, finished) => callback(finished));
|
||||
} else {
|
||||
callback(true);
|
||||
}
|
||||
}
|
||||
|
||||
function _easeActorProperty(actor, propName, target, params) {
|
||||
// Avoid pointless difference with ease()
|
||||
if (params.mode)
|
||||
params.progress_mode = params.mode;
|
||||
delete params.mode;
|
||||
// Avoid pointless difference with ease()
|
||||
if (params.mode) params.progress_mode = params.mode;
|
||||
delete params.mode;
|
||||
|
||||
if (params.duration)
|
||||
params.duration = adjustAnimationTime(params.duration);
|
||||
let duration = Math.floor(params.duration || 0);
|
||||
if (params.duration) params.duration = adjustAnimationTime(params.duration);
|
||||
let duration = Math.floor(params.duration || 0);
|
||||
|
||||
let repeatCount = 0;
|
||||
if (params.repeatCount != undefined)
|
||||
repeatCount = params.repeatCount;
|
||||
delete params.repeatCount;
|
||||
let repeatCount = 0;
|
||||
if (params.repeatCount != undefined) repeatCount = params.repeatCount;
|
||||
delete params.repeatCount;
|
||||
|
||||
let autoReverse = false;
|
||||
if (params.autoReverse != undefined)
|
||||
autoReverse = params.autoReverse;
|
||||
delete params.autoReverse;
|
||||
let autoReverse = false;
|
||||
if (params.autoReverse != undefined) autoReverse = params.autoReverse;
|
||||
delete params.autoReverse;
|
||||
|
||||
// repeatCount doesn't include the initial iteration
|
||||
const numIterations = repeatCount + 1;
|
||||
// whether the transition should finish where it started
|
||||
const isReversed = autoReverse && numIterations % 2 === 0;
|
||||
// repeatCount doesn't include the initial iteration
|
||||
const numIterations = repeatCount + 1;
|
||||
// whether the transition should finish where it started
|
||||
const isReversed = autoReverse && numIterations % 2 === 0;
|
||||
|
||||
// Copy Clutter's behavior for implicit animations, see
|
||||
// should_skip_implicit_transition()
|
||||
if (actor instanceof Clutter.Actor && !actor.mapped)
|
||||
duration = 0;
|
||||
// Copy Clutter's behavior for implicit animations, see
|
||||
// should_skip_implicit_transition()
|
||||
if (actor instanceof Clutter.Actor && !actor.mapped) duration = 0;
|
||||
|
||||
const prepare = () => {
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
global.begin_work();
|
||||
};
|
||||
const cleanup = () => {
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
global.end_work();
|
||||
};
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
const prepare = () => {
|
||||
Meta.disable_unredirect_for_display(global.display);
|
||||
global.begin_work();
|
||||
};
|
||||
const cleanup = () => {
|
||||
Meta.enable_unredirect_for_display(global.display);
|
||||
global.end_work();
|
||||
};
|
||||
let callback = _makeEaseCallback(params, cleanup);
|
||||
|
||||
// cancel overwritten transition
|
||||
actor.remove_transition(propName);
|
||||
// cancel overwritten transition
|
||||
actor.remove_transition(propName);
|
||||
|
||||
if (duration == 0) {
|
||||
let [obj, prop] = _getPropertyTarget(actor, propName);
|
||||
if (duration == 0) {
|
||||
let [obj, prop] = _getPropertyTarget(actor, propName);
|
||||
|
||||
if (!isReversed)
|
||||
obj[prop] = target;
|
||||
if (!isReversed) obj[prop] = target;
|
||||
|
||||
prepare();
|
||||
callback(true);
|
||||
prepare();
|
||||
callback(true);
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
let pspec = actor.find_property(propName);
|
||||
let transition = new Clutter.PropertyTransition(Object.assign({
|
||||
let pspec = actor.find_property(propName);
|
||||
let transition = new Clutter.PropertyTransition(
|
||||
Object.assign(
|
||||
{
|
||||
property_name: propName,
|
||||
interval: new Clutter.Interval({ value_type: pspec.value_type }),
|
||||
remove_on_complete: true,
|
||||
repeat_count: repeatCount,
|
||||
auto_reverse: autoReverse,
|
||||
}, params));
|
||||
actor.add_transition(propName, transition);
|
||||
},
|
||||
params
|
||||
)
|
||||
);
|
||||
actor.add_transition(propName, transition);
|
||||
|
||||
transition.set_to(target);
|
||||
transition.set_to(target);
|
||||
|
||||
if (transition.delay)
|
||||
transition.connect('started', () => prepare());
|
||||
else
|
||||
prepare();
|
||||
if (transition.delay) transition.connect("started", () => prepare());
|
||||
else prepare();
|
||||
|
||||
transition.connect('stopped', (t, finished) => callback(finished));
|
||||
transition.connect("stopped", (t, finished) => callback(finished));
|
||||
}
|
||||
|
||||
function _loggingFunc(...args) {
|
||||
let fields = { 'MESSAGE': args.join(', ') };
|
||||
let domain = "GNOME Shell";
|
||||
let fields = { MESSAGE: args.join(", ") };
|
||||
let domain = "GNOME Shell";
|
||||
|
||||
// If the caller is an extension, add it as metadata
|
||||
let extension = imports.misc.extensionUtils.getCurrentExtension();
|
||||
if (extension != null) {
|
||||
domain = extension.metadata.name;
|
||||
fields['GNOME_SHELL_EXTENSION_UUID'] = extension.uuid;
|
||||
fields['GNOME_SHELL_EXTENSION_NAME'] = extension.metadata.name;
|
||||
}
|
||||
// If the caller is an extension, add it as metadata
|
||||
// let extension = ExtensionUtils.getCurrentExtension();
|
||||
// if (extension != null) {
|
||||
// domain = extension.metadata.name;
|
||||
// fields['GNOME_SHELL_EXTENSION_UUID'] = extension.uuid;
|
||||
// fields['GNOME_SHELL_EXTENSION_NAME'] = extension.metadata.name;
|
||||
// }
|
||||
|
||||
GLib.log_structured(domain, GLib.LogLevelFlags.LEVEL_MESSAGE, fields);
|
||||
GLib.log_structured(domain, GLib.LogLevelFlags.LEVEL_MESSAGE, fields);
|
||||
}
|
||||
|
||||
function init() {
|
||||
// Add some bindings to the global JS namespace
|
||||
globalThis.global = Shell.Global.get();
|
||||
log("initializing...");
|
||||
// Add some bindings to the global JS namespace
|
||||
|
||||
globalThis.log = _loggingFunc;
|
||||
// TODO: This errors because the Shell global has an incorrect type for 'stage'
|
||||
/** @type {Shell.Global & { stage: import('gi://Clutter').Stage; }} */
|
||||
globalThis.global = (Shell.Global.get());
|
||||
|
||||
globalThis._ = Gettext.gettext;
|
||||
globalThis.C_ = Gettext.pgettext;
|
||||
globalThis.ngettext = Gettext.ngettext;
|
||||
globalThis.N_ = s => s;
|
||||
globalThis.log = _loggingFunc;
|
||||
|
||||
GObject.gtypeNameBasedOnJSPath = true;
|
||||
globalThis._ = Gettext.gettext;
|
||||
globalThis.C_ = Gettext.pgettext;
|
||||
globalThis.ngettext = Gettext.ngettext;
|
||||
globalThis.N_ = (s) => s;
|
||||
|
||||
// Miscellaneous monkeypatching
|
||||
_patchContainerClass(St.BoxLayout);
|
||||
|
||||
_patchLayoutClass(Clutter.GridLayout, { row_spacing: 'spacing-rows',
|
||||
column_spacing: 'spacing-columns' });
|
||||
_patchLayoutClass(Clutter.BoxLayout, { spacing: 'spacing' });
|
||||
|
||||
let origSetEasingDuration = Clutter.Actor.prototype.set_easing_duration;
|
||||
Clutter.Actor.prototype.set_easing_duration = function (msecs) {
|
||||
origSetEasingDuration.call(this, adjustAnimationTime(msecs));
|
||||
};
|
||||
let origSetEasingDelay = Clutter.Actor.prototype.set_easing_delay;
|
||||
Clutter.Actor.prototype.set_easing_delay = function (msecs) {
|
||||
origSetEasingDelay.call(this, adjustAnimationTime(msecs));
|
||||
};
|
||||
|
||||
Clutter.Actor.prototype.ease = function (props) {
|
||||
_easeActor(this, props);
|
||||
};
|
||||
Clutter.Actor.prototype.ease_property = function (propName, target, params) {
|
||||
_easeActorProperty(this, propName, target, params);
|
||||
};
|
||||
St.Adjustment.prototype.ease = function (target, params) {
|
||||
// we're not an actor of course, but we implement the same
|
||||
// transition API as Clutter.Actor, so this works anyway
|
||||
_easeActorProperty(this, 'value', target, params);
|
||||
};
|
||||
|
||||
Clutter.Actor.prototype[Symbol.iterator] = function* () {
|
||||
for (let c = this.get_first_child(); c; c = c.get_next_sibling())
|
||||
yield c;
|
||||
};
|
||||
|
||||
Clutter.Actor.prototype.toString = function () {
|
||||
return St.describe_actor(this);
|
||||
};
|
||||
// Deprecation warning for former JS classes turned into an actor subclass
|
||||
Object.defineProperty(Clutter.Actor.prototype, 'actor', {
|
||||
get() {
|
||||
let klass = this.constructor.name;
|
||||
let { stack } = new Error();
|
||||
log(`Usage of object.actor is deprecated for ${klass}\n${stack}`);
|
||||
return this;
|
||||
},
|
||||
});
|
||||
|
||||
Gio._LocalFilePrototype.touch_async = function (callback) {
|
||||
Shell.util_touch_file_async(this, callback);
|
||||
};
|
||||
Gio._LocalFilePrototype.touch_finish = function (result) {
|
||||
return Shell.util_touch_file_finish(this, result);
|
||||
};
|
||||
|
||||
St.set_slow_down_factor = function (factor) {
|
||||
let { stack } = new Error();
|
||||
log(`St.set_slow_down_factor() is deprecated, use St.Settings.slow_down_factor\n${stack}`);
|
||||
St.Settings.get().slow_down_factor = factor;
|
||||
};
|
||||
|
||||
let origToString = Object.prototype.toString;
|
||||
Object.prototype.toString = function () {
|
||||
let base = origToString.call(this);
|
||||
try {
|
||||
if ('actor' in this && this.actor instanceof Clutter.Actor)
|
||||
return base.replace(/\]$/, ` delegate for ${this.actor.toString().substring(1)}`);
|
||||
else
|
||||
return base;
|
||||
} catch (e) {
|
||||
return base;
|
||||
}
|
||||
};
|
||||
|
||||
// Override to clear our own timezone cache as well
|
||||
const origClearDateCaches = System.clearDateCaches;
|
||||
System.clearDateCaches = function () {
|
||||
_localTimeZone = null;
|
||||
origClearDateCaches();
|
||||
};
|
||||
|
||||
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783
|
||||
Date.prototype.toLocaleFormat = function (format) {
|
||||
if (_localTimeZone === null)
|
||||
_localTimeZone = GLib.TimeZone.new_local();
|
||||
|
||||
let dt = GLib.DateTime.new(_localTimeZone,
|
||||
this.getFullYear(),
|
||||
this.getMonth() + 1,
|
||||
this.getDate(),
|
||||
this.getHours(),
|
||||
this.getMinutes(),
|
||||
this.getSeconds());
|
||||
return dt?.format(format) ?? '';
|
||||
};
|
||||
|
||||
let slowdownEnv = GLib.getenv('GNOME_SHELL_SLOWDOWN_FACTOR');
|
||||
if (slowdownEnv) {
|
||||
let factor = parseFloat(slowdownEnv);
|
||||
if (!isNaN(factor) && factor > 0.0)
|
||||
St.Settings.get().slow_down_factor = factor;
|
||||
globalThis.assertType =
|
||||
/**
|
||||
* @template T
|
||||
* @param {unknown} obj
|
||||
* @param {new(...args: any[]) => T} type
|
||||
* @param {string} [message]
|
||||
* @returns {asserts obj is T}
|
||||
*/
|
||||
(obj, type, message) => {
|
||||
if (!(obj instanceof type)) {
|
||||
throw new Error(`${obj} is not an instance of ${type.name}${message ? `: ${message}` : ""}`);
|
||||
}
|
||||
};
|
||||
|
||||
// OK, now things are initialized enough that we can import shell JS
|
||||
const Format = imports.format;
|
||||
GObject.gtypeNameBasedOnJSPath = true;
|
||||
|
||||
String.prototype.format = Format.format;
|
||||
// Miscellaneous monkeypatching
|
||||
_patchContainerClass(St.BoxLayout);
|
||||
|
||||
Math.clamp = function (x, lower, upper) {
|
||||
return Math.min(Math.max(x, lower), upper);
|
||||
};
|
||||
_patchLayoutClass(Clutter.GridLayout, { row_spacing: "spacing-rows", column_spacing: "spacing-columns" });
|
||||
_patchLayoutClass(Clutter.BoxLayout, { spacing: "spacing" });
|
||||
|
||||
let origSetEasingDuration = Clutter.Actor.prototype.set_easing_duration;
|
||||
Clutter.Actor.prototype.set_easing_duration = function (msecs) {
|
||||
origSetEasingDuration.call(this, adjustAnimationTime(msecs));
|
||||
};
|
||||
let origSetEasingDelay = Clutter.Actor.prototype.set_easing_delay;
|
||||
Clutter.Actor.prototype.set_easing_delay = function (msecs) {
|
||||
origSetEasingDelay.call(this, adjustAnimationTime(msecs));
|
||||
};
|
||||
|
||||
Clutter.Actor.prototype.ease = function (props) {
|
||||
_easeActor(this, props);
|
||||
};
|
||||
Clutter.Actor.prototype.ease_property = function (propName, target, params) {
|
||||
_easeActorProperty(this, propName, target, params);
|
||||
};
|
||||
St.Adjustment.prototype.ease = function (target, params) {
|
||||
// we're not an actor of course, but we implement the same
|
||||
// transition API as Clutter.Actor, so this works anyway
|
||||
_easeActorProperty(this, "value", target, params);
|
||||
};
|
||||
|
||||
Clutter.Actor.prototype[Symbol.iterator] = function* () {
|
||||
for (let c = this.get_first_child(); c; c = c.get_next_sibling()) yield c;
|
||||
};
|
||||
|
||||
Clutter.Actor.prototype.toString = function () {
|
||||
return St.describe_actor(this);
|
||||
};
|
||||
// Deprecation warning for former JS classes turned into an actor subclass
|
||||
Object.defineProperty(Clutter.Actor.prototype, "actor", {
|
||||
get() {
|
||||
let klass = this.constructor.name;
|
||||
let { stack } = new Error();
|
||||
log(`Usage of object.actor is deprecated for ${klass}\n${stack}`);
|
||||
return this;
|
||||
},
|
||||
});
|
||||
|
||||
Gio._LocalFilePrototype.touch_async = function (callback) {
|
||||
// TODO
|
||||
if (!callback) {
|
||||
return Shell.util_touch_file_async(this);
|
||||
}
|
||||
|
||||
Shell.util_touch_file_async(this, callback);
|
||||
};
|
||||
|
||||
Gio._LocalFilePrototype.touch_finish =
|
||||
/**
|
||||
* @this {Gio.File}
|
||||
* @param {Gio.AsyncResult} result
|
||||
*/
|
||||
function (result) {
|
||||
return Shell.util_touch_file_finish(this, result);
|
||||
};
|
||||
|
||||
St.set_slow_down_factor = function (factor) {
|
||||
let { stack } = new Error();
|
||||
log(`St.set_slow_down_factor() is deprecated, use St.Settings.slow_down_factor\n${stack}`);
|
||||
St.Settings.get().slow_down_factor = factor;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {unknown} obj
|
||||
* @returns {obj is {actor: unknown}}
|
||||
*/
|
||||
function hasActor(obj) {
|
||||
let actorObj = /** @type {{actor?: unknown}} */ (obj);
|
||||
|
||||
return "actor" in actorObj;
|
||||
}
|
||||
|
||||
let origToString = Object.prototype.toString;
|
||||
Object.prototype.toString = function () {
|
||||
let base = origToString.call(this);
|
||||
try {
|
||||
if (hasActor(this) && this.actor instanceof Clutter.Actor)
|
||||
return base.replace(/\]$/, ` delegate for ${this.actor.toString().substring(1)}`);
|
||||
else return base;
|
||||
} catch (e) {
|
||||
return base;
|
||||
}
|
||||
};
|
||||
|
||||
// Override to clear our own timezone cache as well
|
||||
const origClearDateCaches = System.clearDateCaches;
|
||||
System.clearDateCaches = function () {
|
||||
_localTimeZone = null;
|
||||
origClearDateCaches();
|
||||
};
|
||||
|
||||
// Work around https://bugzilla.mozilla.org/show_bug.cgi?id=508783
|
||||
Date.prototype.toLocaleFormat = function (format) {
|
||||
if (_localTimeZone === null) _localTimeZone = GLib.TimeZone.new_local();
|
||||
|
||||
let dt = GLib.DateTime.new(
|
||||
_localTimeZone,
|
||||
this.getFullYear(),
|
||||
this.getMonth() + 1,
|
||||
this.getDate(),
|
||||
this.getHours(),
|
||||
this.getMinutes(),
|
||||
this.getSeconds()
|
||||
);
|
||||
return dt?.format(format) ?? "";
|
||||
};
|
||||
|
||||
let slowdownEnv = GLib.getenv("GNOME_SHELL_SLOWDOWN_FACTOR");
|
||||
if (slowdownEnv) {
|
||||
let factor = parseFloat(slowdownEnv);
|
||||
if (!isNaN(factor) && factor > 0.0) St.Settings.get().slow_down_factor = factor;
|
||||
}
|
||||
|
||||
// OK, now things are initialized enough that we can import shell JS
|
||||
const Format = imports.format;
|
||||
|
||||
String.prototype.format = Format.format;
|
||||
|
||||
Math.clamp = function (x, lower, upper) {
|
||||
return Math.min(Math.max(x, lower), upper);
|
||||
};
|
||||
|
||||
log("done initializing...");
|
||||
|
||||
// adjustAnimationTime:
|
||||
// @msecs: time in milliseconds
|
||||
//
|
||||
// Adjust @msecs to account for St's enable-animations
|
||||
// and slow-down-factor settings
|
||||
function adjustAnimationTime(msecs) {
|
||||
let settings = St.Settings.get();
|
||||
export function adjustAnimationTime(msecs) {
|
||||
let settings = St.Settings.get();
|
||||
|
||||
if (!settings.enable_animations)
|
||||
return 1;
|
||||
return settings.slow_down_factor * msecs;
|
||||
if (!settings.enable_animations) return 1;
|
||||
return settings.slow_down_factor * msecs;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported init, installExtension, uninstallExtension, checkForUpdates */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Soup } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Soup from 'gi://Soup';
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
const Main = imports.ui.main;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
import * as Dialog from './dialog.js';
|
||||
import * as ExtensionUtils from '../misc/extensionUtils.js';
|
||||
import * as FileUtils from '../misc/fileUtilsModule.js';
|
||||
import Main from './main.js';
|
||||
import * as ModalDialog from './modalDialog.js';
|
||||
|
||||
Gio._promisify(Soup.Session.prototype,
|
||||
'send_and_read_async', 'send_and_read_finish');
|
||||
|
|
@ -19,10 +23,10 @@ Gio._promisify(Gio.IOStream.prototype,
|
|||
Gio._promisify(Gio.Subprocess.prototype,
|
||||
'wait_check_async', 'wait_check_finish');
|
||||
|
||||
var REPOSITORY_URL_DOWNLOAD = 'https://extensions.gnome.org/download-extension/%s.shell-extension.zip';
|
||||
var REPOSITORY_URL_INFO = 'https://extensions.gnome.org/extension-info/';
|
||||
var REPOSITORY_URL_UPDATE = 'https://extensions.gnome.org/update-info/';
|
||||
|
||||
export const REPOSITORY_URL_DOWNLOAD = 'https://extensions.gnome.org/download-extension/%s.shell-extension.zip';
|
||||
export const REPOSITORY_URL_INFO = 'https://extensions.gnome.org/extension-info/';
|
||||
export const REPOSITORY_URL_UPDATE = 'https://extensions.gnome.org/update-info/';
|
||||
|
||||
let _httpSession;
|
||||
|
||||
/**
|
||||
|
|
@ -60,7 +64,7 @@ async function installExtension(uuid, invocation) {
|
|||
dialog.open(global.get_current_time());
|
||||
}
|
||||
|
||||
function uninstallExtension(uuid) {
|
||||
export function uninstallExtension(uuid) {
|
||||
let extension = Main.extensionManager.lookup(uuid);
|
||||
if (!extension)
|
||||
return false;
|
||||
|
|
@ -215,7 +219,7 @@ async function checkForUpdates() {
|
|||
}
|
||||
}
|
||||
|
||||
var InstallExtensionDialog = GObject.registerClass(
|
||||
export const InstallExtensionDialog = GObject.registerClass(
|
||||
class InstallExtensionDialog extends ModalDialog.ModalDialog {
|
||||
_init(uuid, info, invocation) {
|
||||
super._init({ styleClass: 'extension-dialog' });
|
||||
|
|
|
|||
|
|
@ -1,14 +1,18 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported init connect disconnect ExtensionManager */
|
||||
|
||||
const { GLib, Gio, GObject, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import GLib from 'gi://GLib';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const ExtensionDownloader = imports.ui.extensionDownloader;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
import * as ExtensionDownloader from './extensionDownloader.js';
|
||||
import * as ExtensionUtils from '../misc/extensionUtils.js';
|
||||
import * as FileUtils from '../misc/fileUtilsModule.js';
|
||||
import Main from './main.js';
|
||||
import * as MessageTray from './messageTray.js';
|
||||
|
||||
const { ExtensionState, ExtensionType } = ExtensionUtils;
|
||||
|
||||
|
|
@ -19,7 +23,7 @@ const EXTENSION_DISABLE_VERSION_CHECK_KEY = 'disable-extension-version-validatio
|
|||
|
||||
const UPDATE_CHECK_TIMEOUT = 24 * 60 * 60; // 1 day in seconds
|
||||
|
||||
var ExtensionManager = class extends Signals.EventEmitter {
|
||||
export class ExtensionManager extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -418,35 +422,36 @@ var ExtensionManager = class extends Signals.EventEmitter {
|
|||
let extensionModule;
|
||||
let extensionState = null;
|
||||
|
||||
ExtensionUtils.installImporter(extension);
|
||||
// TODO: Fix extension initialization.
|
||||
// ExtensionUtils.installImporter(extension);
|
||||
try {
|
||||
extensionModule = extension.imports.extension;
|
||||
// extensionModule = extension.imports.extension;
|
||||
} catch (e) {
|
||||
this.logExtensionError(uuid, e);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (extensionModule.init) {
|
||||
try {
|
||||
extensionState = extensionModule.init(extension);
|
||||
} catch (e) {
|
||||
this.logExtensionError(uuid, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// if (extensionModule.init) {
|
||||
// try {
|
||||
// extensionState = extensionModule.init(extension);
|
||||
// } catch (e) {
|
||||
// this.logExtensionError(uuid, e);
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!extensionState)
|
||||
extensionState = extensionModule;
|
||||
extension.stateObj = extensionState;
|
||||
// if (!extensionState)
|
||||
// extensionState = extensionModule;
|
||||
// extension.stateObj = extensionState;
|
||||
|
||||
extension.state = ExtensionState.DISABLED;
|
||||
this.emit('extension-loaded', uuid);
|
||||
return true;
|
||||
// extension.state = ExtensionState.DISABLED;
|
||||
// this.emit('extension-loaded', uuid);
|
||||
return false;
|
||||
}
|
||||
|
||||
_getModeExtensions() {
|
||||
if (Array.isArray(Main.sessionMode.enabledExtensions))
|
||||
return Main.sessionMode.enabledExtensions;
|
||||
// if (Array.isArray(Main.sessionMode.enabledExtensions))
|
||||
// return Main.sessionMode.enabledExtensions;
|
||||
return [];
|
||||
}
|
||||
|
||||
|
|
@ -499,7 +504,7 @@ var ExtensionManager = class extends Signals.EventEmitter {
|
|||
.filter(uuid => !newEnabledExtensions.includes(uuid))
|
||||
.reverse().forEach(uuid => this._callExtensionDisable(uuid));
|
||||
|
||||
this._enabledExtensions = newEnabledExtensions;
|
||||
this._enabledExtensions = []; //newEnabledExtensions;
|
||||
}
|
||||
|
||||
_onSettingsWritableChanged() {
|
||||
|
|
@ -625,10 +630,10 @@ var ExtensionManager = class extends Signals.EventEmitter {
|
|||
// from allowExtensions in the future
|
||||
if (Main.sessionMode.allowExtensions) {
|
||||
// Take care of added or removed sessionMode extensions
|
||||
this._onEnabledExtensionsChanged();
|
||||
this._enableAllExtensions();
|
||||
// this._onEnabledExtensionsChanged();
|
||||
// this._enableAllExtensions();
|
||||
} else {
|
||||
this._disableAllExtensions();
|
||||
// this._disableAllExtensions();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -639,7 +644,7 @@ class ExtensionUpdateSource extends MessageTray.Source {
|
|||
let appSys = Shell.AppSystem.get_default();
|
||||
this._app = appSys.lookup_app('org.gnome.Extensions.desktop');
|
||||
|
||||
super._init(this._app.get_name());
|
||||
super._init({ title: this._app.get_name() });
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
|
|
|
|||
|
|
@ -22,13 +22,13 @@
|
|||
*/
|
||||
/* exported FocusCaretTracker */
|
||||
|
||||
const Atspi = imports.gi.Atspi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Atspi from 'gi://Atspi';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const CARETMOVED = 'object:text-caret-moved';
|
||||
const STATECHANGED = 'object:state-changed';
|
||||
|
||||
var FocusCaretTracker = class FocusCaretTracker extends Signals.EventEmitter {
|
||||
export class FocusCaretTracker extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported GrabHelper */
|
||||
|
||||
const { Clutter, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
|
||||
import Main from './main.js';
|
||||
|
||||
let _capturedEventId = 0;
|
||||
let _grabHelperStack = [];
|
||||
|
|
@ -30,6 +32,8 @@ function _popGrabHelper(grabHelper) {
|
|||
}
|
||||
}
|
||||
|
||||
/** @typedef {{ actor: St.Widget, focus?: St.Widget, savedFocus?: Clutter.Actor, onUngrab: (isUser: boolean) => void }} Grab */
|
||||
|
||||
// GrabHelper:
|
||||
// @owner: the actor that owns the GrabHelper
|
||||
// @params: optional parameters to pass to Main.pushModal()
|
||||
|
|
@ -41,7 +45,7 @@ function _popGrabHelper(grabHelper) {
|
|||
// your code just needs to deal with it; you shouldn't adjust behavior directly
|
||||
// after you call ungrab(), but instead pass an 'onUngrab' callback when you
|
||||
// call grab().
|
||||
var GrabHelper = class GrabHelper {
|
||||
export class GrabHelper {
|
||||
constructor(owner, params) {
|
||||
if (!(owner instanceof Clutter.Actor))
|
||||
throw new Error('GrabHelper owner must be a Clutter.Actor');
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported CandidatePopup */
|
||||
|
||||
const { Clutter, GObject, IBus, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import IBus from 'gi://IBus';
|
||||
import St from 'gi://St';
|
||||
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const Main = imports.ui.main;
|
||||
|
||||
var MAX_CANDIDATES_PER_PAGE = 16;
|
||||
import * as BoxPointer from './boxpointer.js';
|
||||
import Main from './main.js';
|
||||
|
||||
var DEFAULT_INDEX_LABELS = ['1', '2', '3', '4', '5', '6', '7', '8',
|
||||
export let MAX_CANDIDATES_PER_PAGE = 16;
|
||||
|
||||
export let DEFAULT_INDEX_LABELS = ['1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', '0', 'a', 'b', 'c', 'd', 'e', 'f'];
|
||||
|
||||
var CandidateArea = GObject.registerClass({
|
||||
export const CandidateArea = GObject.registerClass({
|
||||
Signals: {
|
||||
'candidate-clicked': { param_types: [GObject.TYPE_UINT,
|
||||
GObject.TYPE_UINT,
|
||||
|
|
@ -98,12 +102,20 @@ var CandidateArea = GObject.registerClass({
|
|||
this.vertical = false;
|
||||
this.remove_style_class_name('vertical');
|
||||
this.add_style_class_name('horizontal');
|
||||
|
||||
assertType(this._previousButton.child, St.Icon);
|
||||
assertType(this._nextButton.child, St.Icon);
|
||||
|
||||
this._previousButton.child.icon_name = 'go-previous-symbolic';
|
||||
this._nextButton.child.icon_name = 'go-next-symbolic';
|
||||
} else { // VERTICAL || SYSTEM
|
||||
this.vertical = true;
|
||||
this.add_style_class_name('vertical');
|
||||
this.remove_style_class_name('horizontal');
|
||||
|
||||
assertType(this._previousButton.child, St.Icon);
|
||||
assertType(this._nextButton.child, St.Icon);
|
||||
|
||||
this._previousButton.child.icon_name = 'go-up-symbolic';
|
||||
this._nextButton.child.icon_name = 'go-down-symbolic';
|
||||
}
|
||||
|
|
@ -139,7 +151,7 @@ var CandidateArea = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var CandidatePopup = GObject.registerClass(
|
||||
export const CandidatePopup = GObject.registerClass(
|
||||
class IbusCandidatePopup extends BoxPointer.BoxPointer {
|
||||
_init() {
|
||||
super._init(St.Side.TOP);
|
||||
|
|
@ -199,6 +211,7 @@ class IbusCandidatePopup extends BoxPointer.BoxPointer {
|
|||
panelService.connect('set-cursor-location-relative', (ps, x, y, w, h) => {
|
||||
if (!global.display.focus_window)
|
||||
return;
|
||||
|
||||
let window = global.display.focus_window.get_compositor_private();
|
||||
this._setDummyCursorGeometry(window.x + x, window.y + y, w, h);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,37 +1,49 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported BaseIcon, IconGrid, IconGridLayout */
|
||||
|
||||
const { Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
import Main from './main.js';
|
||||
|
||||
var ICON_SIZE = 96;
|
||||
export let ICON_SIZE = 96;
|
||||
|
||||
var ANIMATION_TIME_IN = 350;
|
||||
var ANIMATION_TIME_OUT = 1 / 2 * ANIMATION_TIME_IN;
|
||||
var ANIMATION_MAX_DELAY_FOR_ITEM = 2 / 3 * ANIMATION_TIME_IN;
|
||||
var ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 2 / 3 * ANIMATION_TIME_OUT;
|
||||
var ANIMATION_FADE_IN_TIME_FOR_ITEM = 1 / 4 * ANIMATION_TIME_IN;
|
||||
export let ANIMATION_TIME_IN = 350;
|
||||
export let ANIMATION_TIME_OUT = 1 / 2 * ANIMATION_TIME_IN;
|
||||
export let ANIMATION_MAX_DELAY_FOR_ITEM = 2 / 3 * ANIMATION_TIME_IN;
|
||||
export let ANIMATION_MAX_DELAY_OUT_FOR_ITEM = 2 / 3 * ANIMATION_TIME_OUT;
|
||||
export let ANIMATION_FADE_IN_TIME_FOR_ITEM = 1 / 4 * ANIMATION_TIME_IN;
|
||||
|
||||
var PAGE_SWITCH_TIME = 300;
|
||||
export let PAGE_SWITCH_TIME = 300;
|
||||
|
||||
var AnimationDirection = {
|
||||
/** @typedef {Clutter.Actor & { icon?: typeof BaseIcon["prototype"] }} BaseItem */
|
||||
|
||||
/** @enum {number} */
|
||||
export const AnimationDirection = {
|
||||
IN: 0,
|
||||
OUT: 1,
|
||||
};
|
||||
|
||||
var IconSize = {
|
||||
/** @enum {number} */
|
||||
export const IconSize = {
|
||||
LARGE: 96,
|
||||
MEDIUM: 64,
|
||||
SMALL: 32,
|
||||
TINY: 16,
|
||||
};
|
||||
|
||||
var APPICON_ANIMATION_OUT_SCALE = 3;
|
||||
var APPICON_ANIMATION_OUT_TIME = 250;
|
||||
export let APPICON_ANIMATION_OUT_SCALE = 3;
|
||||
export let APPICON_ANIMATION_OUT_TIME = 250;
|
||||
|
||||
const ICON_POSITION_DELAY = 10;
|
||||
|
||||
/** @typedef {{rows: number, columns: number}} GridMode */
|
||||
|
||||
/** @type {GridMode[]} */
|
||||
const defaultGridModes = [
|
||||
{
|
||||
rows: 8,
|
||||
|
|
@ -51,10 +63,11 @@ const defaultGridModes = [
|
|||
},
|
||||
];
|
||||
|
||||
var LEFT_DIVIDER_LEEWAY = 20;
|
||||
var RIGHT_DIVIDER_LEEWAY = 20;
|
||||
export let LEFT_DIVIDER_LEEWAY = 20;
|
||||
export let RIGHT_DIVIDER_LEEWAY = 20;
|
||||
|
||||
var DragLocation = {
|
||||
/** @enum {number} */
|
||||
export const DragLocation = {
|
||||
INVALID: 0,
|
||||
START_EDGE: 1,
|
||||
ON_ICON: 2,
|
||||
|
|
@ -62,7 +75,7 @@ var DragLocation = {
|
|||
EMPTY_SPACE: 4,
|
||||
};
|
||||
|
||||
var BaseIcon = GObject.registerClass(
|
||||
export const BaseIcon = GObject.registerClass(
|
||||
class BaseIcon extends Shell.SquareBin {
|
||||
_init(label, params = {}) {
|
||||
const {
|
||||
|
|
@ -114,6 +127,10 @@ class BaseIcon extends Shell.SquareBin {
|
|||
|
||||
// This can be overridden by a subclass, or by the createIcon
|
||||
// parameter to _init()
|
||||
/**
|
||||
* @param {number} _size
|
||||
* @returns {St.Widget}
|
||||
*/
|
||||
createIcon(_size) {
|
||||
throw new GObject.NotImplementedError(`createIcon in ${this.constructor.name}`);
|
||||
}
|
||||
|
|
@ -186,7 +203,7 @@ class BaseIcon extends Shell.SquareBin {
|
|||
}
|
||||
});
|
||||
|
||||
function zoomOutActor(actor) {
|
||||
export function zoomOutActor(actor) {
|
||||
let [x, y] = actor.get_transformed_position();
|
||||
zoomOutActorAtPos(actor, x, y);
|
||||
}
|
||||
|
|
@ -250,7 +267,7 @@ function swap(value, length) {
|
|||
return length - value - 1;
|
||||
}
|
||||
|
||||
var IconGridLayout = GObject.registerClass({
|
||||
export const IconGridLayout = GObject.registerClass({
|
||||
Properties: {
|
||||
'allow-incomplete-pages': GObject.ParamSpec.boolean('allow-incomplete-pages',
|
||||
'Allow incomplete pages', 'Allow incomplete pages',
|
||||
|
|
@ -319,6 +336,7 @@ var IconGridLayout = GObject.registerClass({
|
|||
'pages-changed': {},
|
||||
},
|
||||
}, class IconGridLayout extends Clutter.LayoutManager {
|
||||
|
||||
_init(params = {}) {
|
||||
this._orientation = params.orientation ?? Clutter.Orientation.VERTICAL;
|
||||
|
||||
|
|
@ -327,6 +345,29 @@ var IconGridLayout = GObject.registerClass({
|
|||
if (!this.pagePadding)
|
||||
this.pagePadding = new Clutter.Margin();
|
||||
|
||||
/** @type {number} */
|
||||
this.fixedIconSize;
|
||||
/** @type {number} */
|
||||
this.rowSpacing;
|
||||
/** @type {number} */
|
||||
this.columnSpacing;
|
||||
/** @type {number} */
|
||||
this.maxRowSpacing;
|
||||
/** @type {number} */
|
||||
this.maxColumnSpacing;
|
||||
/** @type {number} */
|
||||
this.columnsPerPage;
|
||||
/** @type {number} */
|
||||
this.rowsPerPage;
|
||||
/** @type {number} */
|
||||
this.lastRowAlign;
|
||||
/** @type {number} */
|
||||
this.allowIncompletePages;
|
||||
/** @type {Clutter.ActorAlign} */
|
||||
this.pageHalign;
|
||||
/** @type {Clutter.ActorAlign} */
|
||||
this.pageValign;
|
||||
|
||||
this._iconSize = this.fixedIconSize !== -1
|
||||
? this.fixedIconSize
|
||||
: IconSize.LARGE;
|
||||
|
|
@ -729,6 +770,9 @@ var IconGridLayout = GObject.registerClass({
|
|||
this._containerDestroyedId = this._container.connect('destroy', this._onDestroy.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(_container, _forHeight) {
|
||||
let minWidth = -1;
|
||||
let natWidth = -1;
|
||||
|
|
@ -748,6 +792,9 @@ var IconGridLayout = GObject.registerClass({
|
|||
return [minWidth, natWidth];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(_container, _forWidth) {
|
||||
let minHeight = -1;
|
||||
let natHeight = -1;
|
||||
|
|
@ -840,8 +887,8 @@ var IconGridLayout = GObject.registerClass({
|
|||
/**
|
||||
* addItem:
|
||||
* @param {Clutter.Actor} item: item to append to the grid
|
||||
* @param {int} page: page number
|
||||
* @param {int} index: position in the page
|
||||
* @param {number} page: page number
|
||||
* @param {number} index: position in the page
|
||||
*
|
||||
* Adds @item to the grid. @item must not be part of the grid.
|
||||
*
|
||||
|
|
@ -880,8 +927,8 @@ var IconGridLayout = GObject.registerClass({
|
|||
/**
|
||||
* moveItem:
|
||||
* @param {Clutter.Actor} item: item to move
|
||||
* @param {int} newPage: new page of the item
|
||||
* @param {int} newPosition: new page of the item
|
||||
* @param {number} newPage: new page of the item
|
||||
* @param {number} newPosition: new page of the item
|
||||
*
|
||||
* Moves @item to the grid. @item must be part of the grid.
|
||||
*/
|
||||
|
|
@ -916,7 +963,7 @@ var IconGridLayout = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemsAtPage:
|
||||
* @param {int} pageIndex: page index
|
||||
* @param {number} pageIndex: page index
|
||||
*
|
||||
* Retrieves the children at page @pageIndex. Children may be invisible.
|
||||
*
|
||||
|
|
@ -931,12 +978,12 @@ var IconGridLayout = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemPosition:
|
||||
* @param {BaseIcon} item: the item
|
||||
* @param {BaseIcon["prototype"]} item: the item
|
||||
*
|
||||
* Retrieves the position of @item is its page, or -1 if @item is not
|
||||
* part of the grid.
|
||||
*
|
||||
* @returns {[int, int]} the page and position of @item
|
||||
* @returns {[number, number]} the page and position of @item
|
||||
*/
|
||||
getItemPosition(item) {
|
||||
if (!this._items.has(item))
|
||||
|
|
@ -950,8 +997,8 @@ var IconGridLayout = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemAt:
|
||||
* @param {int} page: the page
|
||||
* @param {int} position: the position in page
|
||||
* @param {number} page: the page
|
||||
* @param {number} position: the position in page
|
||||
*
|
||||
* Retrieves the item at @page and @position.
|
||||
*
|
||||
|
|
@ -971,11 +1018,11 @@ var IconGridLayout = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemPage:
|
||||
* @param {BaseIcon} item: the item
|
||||
* @param {BaseIcon["prototype"]} item: the item
|
||||
*
|
||||
* Retrieves the page @item is in, or -1 if @item is not part of the grid.
|
||||
*
|
||||
* @returns {int} the page where @item is in
|
||||
* @returns {number} the page where @item is in
|
||||
*/
|
||||
getItemPage(item) {
|
||||
if (!this._items.has(item))
|
||||
|
|
@ -1023,13 +1070,13 @@ var IconGridLayout = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getDropTarget:
|
||||
* @param {int} x: position of the horizontal axis
|
||||
* @param {int} y: position of the vertical axis
|
||||
* @param {number} x: position of the horizontal axis
|
||||
* @param {number} y: position of the vertical axis
|
||||
*
|
||||
* Retrieves the item located at (@x, @y), as well as the drag location.
|
||||
* Both @x and @y are relative to the grid.
|
||||
*
|
||||
* @returns {[Clutter.Actor, DragLocation]} the item and drag location
|
||||
* @returns {[BaseIcon["prototype"] | null, DragLocation]} the item and drag location
|
||||
* under (@x, @y)
|
||||
*/
|
||||
getDropTarget(x, y) {
|
||||
|
|
@ -1154,12 +1201,17 @@ var IconGridLayout = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var IconGrid = GObject.registerClass({
|
||||
export const IconGrid = GObject.registerClass({
|
||||
Signals: {
|
||||
'pages-changed': {},
|
||||
'animation-done': {},
|
||||
},
|
||||
}, class IconGrid extends St.Viewport {
|
||||
},
|
||||
/** @extends {St.Viewport<typeof IconGridLayout["prototype"]>} */
|
||||
class IconGrid extends St.Viewport {
|
||||
/**
|
||||
* @param {*} layoutParams
|
||||
*/
|
||||
_init(layoutParams = {}) {
|
||||
const iconGridLayoutParams = {
|
||||
allow_incomplete_pages: false,
|
||||
|
|
@ -1238,6 +1290,9 @@ var IconGrid = GObject.registerClass({
|
|||
this.goToPage(itemPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} modeIndex
|
||||
*/
|
||||
_setGridMode(modeIndex) {
|
||||
if (this._currentMode === modeIndex)
|
||||
return;
|
||||
|
|
@ -1259,17 +1314,16 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
const sizeRatio = width / height;
|
||||
let closestRatio = Infinity;
|
||||
let bestMode = -1;
|
||||
|
||||
for (let modeIndex in this._gridModes) {
|
||||
const mode = this._gridModes[modeIndex];
|
||||
let bestMode = this._gridModes.findIndex((mode) => {
|
||||
const modeRatio = mode.columns / mode.rows;
|
||||
|
||||
if (Math.abs(sizeRatio - modeRatio) < Math.abs(sizeRatio - closestRatio)) {
|
||||
closestRatio = modeRatio;
|
||||
bestMode = modeIndex;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}) ?? -1;
|
||||
|
||||
this._setGridMode(bestMode);
|
||||
}
|
||||
|
|
@ -1312,9 +1366,9 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* addItem:
|
||||
* @param {Clutter.Actor} item: item to append to the grid
|
||||
* @param {int} page: page number
|
||||
* @param {int} index: position in the page
|
||||
* @param {BaseItem} item: item to append to the grid
|
||||
* @param {number} page: page number
|
||||
* @param {number} index: position in the page
|
||||
*
|
||||
* Adds @item to the grid. @item must not be part of the grid.
|
||||
*
|
||||
|
|
@ -1344,8 +1398,8 @@ var IconGrid = GObject.registerClass({
|
|||
/**
|
||||
* moveItem:
|
||||
* @param {Clutter.Actor} item: item to move
|
||||
* @param {int} newPage: new page of the item
|
||||
* @param {int} newPosition: new page of the item
|
||||
* @param {number} newPage: new page of the item
|
||||
* @param {number} newPosition: new page of the item
|
||||
*
|
||||
* Moves @item to the grid. @item must be part of the grid.
|
||||
*/
|
||||
|
|
@ -1369,7 +1423,7 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* goToPage:
|
||||
* @param {int} pageIndex: page index
|
||||
* @param {number} pageIndex: page index
|
||||
* @param {boolean} animate: animate the page transition
|
||||
*
|
||||
* Moves the current page to @pageIndex. @pageIndex must be a valid page
|
||||
|
|
@ -1405,11 +1459,11 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemPage:
|
||||
* @param {BaseIcon} item: the item
|
||||
* @param {BaseIcon["prototype"]} item: the item
|
||||
*
|
||||
* Retrieves the page @item is in, or -1 if @item is not part of the grid.
|
||||
*
|
||||
* @returns {int} the page where @item is in
|
||||
* @returns {number} the page where @item is in
|
||||
*/
|
||||
getItemPage(item) {
|
||||
return this.layout_manager.getItemPage(item);
|
||||
|
|
@ -1417,12 +1471,12 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemPosition:
|
||||
* @param {BaseIcon} item: the item
|
||||
* @param {BaseIcon["prototype"]} item: the item
|
||||
*
|
||||
* Retrieves the position of @item is its page, or -1 if @item is not
|
||||
* part of the grid.
|
||||
*
|
||||
* @returns {[int, int]} the page and position of @item
|
||||
* @returns {[number, number]} the page and position of @item
|
||||
*/
|
||||
getItemPosition(item) {
|
||||
if (!this.contains(item))
|
||||
|
|
@ -1434,8 +1488,8 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemAt:
|
||||
* @param {int} page: the page
|
||||
* @param {int} position: the position in page
|
||||
* @param {number} page: the page
|
||||
* @param {number} position: the position in page
|
||||
*
|
||||
* Retrieves the item at @page and @position.
|
||||
*
|
||||
|
|
@ -1448,7 +1502,7 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
/**
|
||||
* getItemsAtPage:
|
||||
* @param {int} page: the page index
|
||||
* @param {number} page: the page index
|
||||
*
|
||||
* Retrieves the children at page @page, including invisible children.
|
||||
*
|
||||
|
|
@ -1553,11 +1607,9 @@ var IconGrid = GObject.registerClass({
|
|||
duration: ANIMATION_TIME_IN,
|
||||
mode: Clutter.AnimationMode.EASE_IN_OUT_QUAD,
|
||||
delay,
|
||||
...(isLastItem ? { onComplete: this._animationDone.bind(this) } : {})
|
||||
};
|
||||
|
||||
if (isLastItem)
|
||||
movementParams.onComplete = this._animationDone.bind(this);
|
||||
|
||||
fadeParams = {
|
||||
opacity: 255,
|
||||
duration: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
||||
|
|
@ -1579,11 +1631,9 @@ var IconGrid = GObject.registerClass({
|
|||
duration: ANIMATION_TIME_OUT,
|
||||
mode: Clutter.AnimationMode.EASE_IN_OUT_QUAD,
|
||||
delay,
|
||||
...(isLastItem ? { onComplete: this._animationDone.bind(this) } : {})
|
||||
};
|
||||
|
||||
if (isLastItem)
|
||||
movementParams.onComplete = this._animationDone.bind(this);
|
||||
|
||||
fadeParams = {
|
||||
opacity: 0,
|
||||
duration: ANIMATION_FADE_IN_TIME_FOR_ITEM,
|
||||
|
|
@ -1597,6 +1647,9 @@ var IconGrid = GObject.registerClass({
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {GridMode[]} modes
|
||||
*/
|
||||
setGridModes(modes) {
|
||||
this._gridModes = modes ? modes : defaultGridModes;
|
||||
this.queue_relayout();
|
||||
|
|
@ -1604,7 +1657,7 @@ var IconGrid = GObject.registerClass({
|
|||
|
||||
getDropTarget(x, y) {
|
||||
const layoutManager = this.layout_manager;
|
||||
return layoutManager.getDropTarget(x, y, this._currentPage);
|
||||
return layoutManager.getDropTarget(x, y);
|
||||
}
|
||||
|
||||
get itemsPerPage() {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,17 @@
|
|||
/* exported InhibitShortcutsDialog */
|
||||
const { Clutter, Gio, GLib, GObject, Gtk, Meta, Pango, 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 Pango from 'gi://Pango';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
const PermissionStore = imports.misc.permissionStore;
|
||||
import * as Dialog from './dialog.js';
|
||||
import * as ModalDialog from './modalDialog.js';
|
||||
import * as PermissionStore from '../misc/permissionStore.js';
|
||||
|
||||
const WAYLAND_KEYBINDINGS_SCHEMA = 'org.gnome.mutter.wayland.keybindings';
|
||||
|
||||
|
|
@ -13,14 +21,17 @@ const APP_PERMISSIONS_ID = 'shortcuts-inhibitor';
|
|||
const GRANTED = 'GRANTED';
|
||||
const DENIED = 'DENIED';
|
||||
|
||||
var DialogResponse = Meta.InhibitShortcutsDialogResponse;
|
||||
export const DialogResponse = Meta.InhibitShortcutsDialogResponse;
|
||||
|
||||
var InhibitShortcutsDialog = GObject.registerClass({
|
||||
export const InhibitShortcutsDialog = GObject.registerClass({
|
||||
Implements: [Meta.InhibitShortcutsDialog],
|
||||
Properties: {
|
||||
'window': GObject.ParamSpec.override('window', Meta.InhibitShortcutsDialog),
|
||||
},
|
||||
}, class InhibitShortcutsDialog extends GObject.Object {
|
||||
/**
|
||||
* @param {*} window
|
||||
*/
|
||||
_init(window) {
|
||||
super._init();
|
||||
this._window = window;
|
||||
|
|
@ -59,7 +70,7 @@ var InhibitShortcutsDialog = GObject.registerClass({
|
|||
|
||||
let permissions = {};
|
||||
permissions[this._app.get_id()] = [grant];
|
||||
let data = GLib.Variant.new('av', {});
|
||||
let data = GLib.Variant.new('av', []);
|
||||
|
||||
this._permStore.SetRemote(APP_PERMISSIONS_TABLE,
|
||||
true,
|
||||
|
|
|
|||
|
|
@ -2,5 +2,15 @@ import { setConsoleLogDomain } from 'console';
|
|||
|
||||
setConsoleLogDomain('GNOME Shell');
|
||||
|
||||
imports.ui.environment.init();
|
||||
imports.ui.main.start();
|
||||
import "./environment.js";
|
||||
|
||||
import("./main.js")
|
||||
.then(({ main }) => {
|
||||
main.start();
|
||||
})
|
||||
.catch((error) => {
|
||||
logError(error);
|
||||
})
|
||||
.finally(() => {
|
||||
log("Main imported.");
|
||||
});
|
||||
|
|
@ -1,14 +1,18 @@
|
|||
/* exported KbdA11yDialog */
|
||||
const { Clutter, Gio, GObject } = imports.gi;
|
||||
import Meta from 'gi://Meta';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const ModalDialog = imports.ui.modalDialog;
|
||||
|
||||
import * as Dialog from './dialog.js';
|
||||
import * as ModalDialog from './modalDialog.js';
|
||||
|
||||
const KEYBOARD_A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
|
||||
const KEY_STICKY_KEYS_ENABLED = 'stickykeys-enable';
|
||||
const KEY_SLOW_KEYS_ENABLED = 'slowkeys-enable';
|
||||
|
||||
var KbdA11yDialog = GObject.registerClass(
|
||||
export const KbdA11yDialog = GObject.registerClass(
|
||||
class KbdA11yDialog extends GObject.Object {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -25,17 +29,23 @@ class KbdA11yDialog extends GObject.Object {
|
|||
let title, description;
|
||||
let key, enabled;
|
||||
|
||||
if (whatChanged & Clutter.KeyboardA11yFlags.SLOW_KEYS_ENABLED) {
|
||||
const META_A11Y_SLOW_KEYS_ENABLED = 1 << 3;
|
||||
const META_A11Y_STICKY_KEYS_ENABLED = 1 << 10;
|
||||
// FIXME:
|
||||
// This change https://github.com/GNOME/mutter/commit/c3acaeb25127a7520ecc0d3edbb3d0cc53b5634e#diff-8da73b762bc44dbbfb6a00938e37693e5e3fc3266673275502117ea932cf7675R55
|
||||
// made Clutter.KeyboardA11yFlags turn into Meta.KeyboardA11yFlags but
|
||||
// also removed it from introspection.
|
||||
if (whatChanged & /* Meta.KeyboardA11yFlags */ META_A11Y_SLOW_KEYS_ENABLED) {
|
||||
key = KEY_SLOW_KEYS_ENABLED;
|
||||
enabled = (newFlags & Clutter.KeyboardA11yFlags.SLOW_KEYS_ENABLED) > 0;
|
||||
enabled = (newFlags & META_A11Y_SLOW_KEYS_ENABLED) > 0;
|
||||
title = enabled
|
||||
? _("Slow Keys Turned On")
|
||||
: _("Slow Keys Turned Off");
|
||||
description = _('You just held down the Shift key for 8 seconds. This is the shortcut ' +
|
||||
'for the Slow Keys feature, which affects the way your keyboard works.');
|
||||
} else if (whatChanged & Clutter.KeyboardA11yFlags.STICKY_KEYS_ENABLED) {
|
||||
} else if (whatChanged & META_A11Y_STICKY_KEYS_ENABLED) {
|
||||
key = KEY_STICKY_KEYS_ENABLED;
|
||||
enabled = (newFlags & Clutter.KeyboardA11yFlags.STICKY_KEYS_ENABLED) > 0;
|
||||
enabled = (newFlags & META_A11Y_STICKY_KEYS_ENABLED) > 0;
|
||||
title = enabled
|
||||
? _("Sticky Keys Turned On")
|
||||
: _("Sticky Keys Turned Off");
|
||||
|
|
|
|||
|
|
@ -1,16 +1,22 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported KeyboardManager */
|
||||
import Clutter from 'gi://Clutter';
|
||||
import St from 'gi://St';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Shell from 'gi://Shell';
|
||||
import Meta from 'gi://Meta';
|
||||
import Graphene from 'gi://Graphene';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Graphene, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
|
||||
const EdgeDragAction = imports.ui.edgeDragAction;
|
||||
const InputSourceManager = imports.ui.status.keyboard;
|
||||
const IBusManager = imports.misc.ibusManager;
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const Main = imports.ui.main;
|
||||
const PageIndicators = imports.ui.pageIndicators;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
import * as EdgeDragAction from './edgeDragAction.js';
|
||||
import * as InputSourceManager from './status/keyboard.js';
|
||||
import * as IBusManager from '../misc/ibusManager.js';
|
||||
import * as BoxPointer from './boxpointer.js';
|
||||
import Main from './main.js';
|
||||
import * as PageIndicators from './pageIndicators.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
|
||||
var KEYBOARD_ANIMATION_TIME = 150;
|
||||
var KEYBOARD_REST_TIME = KEYBOARD_ANIMATION_TIME * 2;
|
||||
|
|
@ -50,7 +56,7 @@ const defaultKeysPost = [
|
|||
[{ action: 'emoji', icon: 'face-smile-symbolic' }, { action: 'languageMenu', extraClassName: 'layout-key', icon: 'keyboard-layout-filled-symbolic' }, { action: 'hide', extraClassName: 'hide-key', icon: 'go-down-symbolic' }]],
|
||||
];
|
||||
|
||||
var AspectContainer = GObject.registerClass(
|
||||
export const AspectContainer = GObject.registerClass(
|
||||
class AspectContainer extends St.Widget {
|
||||
_init(params) {
|
||||
super._init(params);
|
||||
|
|
@ -62,6 +68,9 @@ class AspectContainer extends St.Widget {
|
|||
this.queue_relayout();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(forHeight) {
|
||||
let [min, nat] = super.vfunc_get_preferred_width(forHeight);
|
||||
|
||||
|
|
@ -71,6 +80,9 @@ class AspectContainer extends St.Widget {
|
|||
return [min, nat];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
let [min, nat] = super.vfunc_get_preferred_height(forWidth);
|
||||
|
||||
|
|
@ -102,7 +114,7 @@ class AspectContainer extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var KeyContainer = GObject.registerClass(
|
||||
export const KeyContainer = GObject.registerClass(
|
||||
class KeyContainer extends St.Widget {
|
||||
_init() {
|
||||
let gridLayout = new Clutter.GridLayout({ orientation: Clutter.Orientation.HORIZONTAL,
|
||||
|
|
@ -120,6 +132,8 @@ class KeyContainer extends St.Widget {
|
|||
|
||||
this._currentRow = null;
|
||||
this._rows = [];
|
||||
|
||||
this.shiftKeys = [];
|
||||
}
|
||||
|
||||
appendRow() {
|
||||
|
|
@ -183,7 +197,7 @@ class KeyContainer extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var Suggestions = GObject.registerClass(
|
||||
export const Suggestions = GObject.registerClass(
|
||||
class Suggestions extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -205,7 +219,7 @@ class Suggestions extends St.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
|
||||
export class LanguageSelectionPopup extends PopupMenu.PopupMenu {
|
||||
constructor(actor) {
|
||||
super(actor, 0.5, St.Side.BOTTOM);
|
||||
|
||||
|
|
@ -268,7 +282,7 @@ var LanguageSelectionPopup = class extends PopupMenu.PopupMenu {
|
|||
}
|
||||
};
|
||||
|
||||
var Key = GObject.registerClass({
|
||||
export const Key = GObject.registerClass({
|
||||
Signals: {
|
||||
'activated': {},
|
||||
'long-press': {},
|
||||
|
|
@ -288,6 +302,7 @@ var Key = GObject.registerClass({
|
|||
this.add_child(this.keyButton);
|
||||
this.connect('destroy', this._onDestroy.bind(this));
|
||||
|
||||
this._keyvalPress = false;
|
||||
this._extendedKeys = extendedKeys;
|
||||
this._extendedKeyboard = null;
|
||||
this._pressTimeoutId = 0;
|
||||
|
|
@ -516,7 +531,7 @@ var Key = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var KeyboardModel = class {
|
||||
export class KeyboardModel {
|
||||
constructor(groupName) {
|
||||
let names = [groupName];
|
||||
if (groupName.includes('+'))
|
||||
|
|
@ -549,7 +564,7 @@ var KeyboardModel = class {
|
|||
}
|
||||
};
|
||||
|
||||
var FocusTracker = class extends Signals.EventEmitter {
|
||||
export class FocusTracker extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -664,7 +679,7 @@ var FocusTracker = class extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var EmojiPager = GObject.registerClass({
|
||||
export const EmojiPager = GObject.registerClass({
|
||||
Properties: {
|
||||
'delta': GObject.ParamSpec.int(
|
||||
'delta', 'delta', 'delta',
|
||||
|
|
@ -952,7 +967,7 @@ var EmojiPager = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var EmojiSelection = GObject.registerClass({
|
||||
export const EmojiSelection = GObject.registerClass({
|
||||
Signals: {
|
||||
'emoji-selected': { param_types: [GObject.TYPE_STRING] },
|
||||
'close-request': {},
|
||||
|
|
@ -1110,7 +1125,7 @@ var EmojiSelection = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var Keypad = GObject.registerClass({
|
||||
export const Keypad = GObject.registerClass({
|
||||
Signals: {
|
||||
'keyval': { param_types: [GObject.TYPE_UINT] },
|
||||
},
|
||||
|
|
@ -1162,7 +1177,7 @@ var Keypad = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var KeyboardManager = class KeyBoardManager {
|
||||
export class KeyboardManager {
|
||||
constructor() {
|
||||
this._keyboard = null;
|
||||
this._a11yApplicationsSettings = new Gio.Settings({ schema_id: A11Y_APPLICATIONS_SCHEMA });
|
||||
|
|
@ -1269,7 +1284,7 @@ var KeyboardManager = class KeyBoardManager {
|
|||
}
|
||||
};
|
||||
|
||||
var Keyboard = GObject.registerClass({
|
||||
export const Keyboard = GObject.registerClass({
|
||||
Signals: {
|
||||
'visibility-changed': {},
|
||||
},
|
||||
|
|
@ -1301,7 +1316,7 @@ var Keyboard = GObject.registerClass({
|
|||
if (!Meta.is_wayland_compositor()) {
|
||||
this._connectSignal(this._focusTracker, 'focus-changed', (_tracker, focused) => {
|
||||
if (focused)
|
||||
this.open(Main.layoutManager.focusIndex);
|
||||
this.open(!!Main.layoutManager.focusIndex);
|
||||
else
|
||||
this.close();
|
||||
});
|
||||
|
|
@ -1441,7 +1456,7 @@ var Keyboard = GObject.registerClass({
|
|||
// Showing an extended key popup and clicking a key from the extended keys
|
||||
// will grab focus, but ignore that
|
||||
let extendedKeysWereFocused = this._focusInExtendedKeys;
|
||||
this._focusInExtendedKeys = focus && (focus._extendedKeys || focus.extendedKey);
|
||||
this._focusInExtendedKeys = focus && (focus instanceof St.Button && (focus._extendedKeys || focus.extendedKey));
|
||||
if (this._focusInExtendedKeys || extendedKeysWereFocused)
|
||||
return;
|
||||
|
||||
|
|
@ -1452,7 +1467,7 @@ var Keyboard = GObject.registerClass({
|
|||
|
||||
if (!this._showIdleId) {
|
||||
this._showIdleId = GLib.idle_add(GLib.PRIORITY_DEFAULT_IDLE, () => {
|
||||
this.open(Main.layoutManager.focusIndex);
|
||||
this.open(!!Main.layoutManager.focusIndex);
|
||||
this._showIdleId = 0;
|
||||
return GLib.SOURCE_REMOVE;
|
||||
});
|
||||
|
|
@ -1473,7 +1488,6 @@ var Keyboard = GObject.registerClass({
|
|||
let level = i >= 1 && levels.length == 3 ? i + 1 : i;
|
||||
|
||||
let layout = new KeyContainer();
|
||||
layout.shiftKeys = [];
|
||||
|
||||
this._loadRows(currentLevel, level, levels.length, layout);
|
||||
layers[level] = layout;
|
||||
|
|
@ -1655,6 +1669,12 @@ var Keyboard = GObject.registerClass({
|
|||
this._loadDefaultKeys(post, layout, numLevels, row.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} model
|
||||
* @param {number} level
|
||||
* @param {number} numLevels
|
||||
* @param {KeyContainer["prototype"]} layout
|
||||
*/
|
||||
_loadRows(model, level, numLevels, layout) {
|
||||
let rows = model.rows;
|
||||
for (let i = 0; i < rows.length; ++i) {
|
||||
|
|
@ -1708,8 +1728,7 @@ var Keyboard = GObject.registerClass({
|
|||
}
|
||||
|
||||
_onKeyboardGroupsChanged() {
|
||||
let nonGroupActors = [this._emojiSelection, this._keypad];
|
||||
this._aspectContainer.get_children().filter(c => !nonGroupActors.includes(c)).forEach(c => {
|
||||
this._aspectContainer.get_children().filter(c => c !== this._emojiSelection && c !== this._keypad).forEach(c => {
|
||||
c.destroy();
|
||||
});
|
||||
|
||||
|
|
@ -1747,7 +1766,7 @@ var Keyboard = GObject.registerClass({
|
|||
return;
|
||||
|
||||
if (enabled)
|
||||
this.open(Main.layoutManager.focusIndex);
|
||||
this.open(!!Main.layoutManager.focusIndex);
|
||||
else
|
||||
this.close();
|
||||
}
|
||||
|
|
@ -2037,7 +2056,7 @@ var Keyboard = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var KeyboardController = class extends Signals.EventEmitter {
|
||||
export class KeyboardController extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported MonitorConstraint, LayoutManager */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const BackgroundMenu = imports.ui.backgroundMenu;
|
||||
import * as Background from './background.js';
|
||||
import * as BackgroundMenu from './backgroundMenu.js';
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const Main = imports.ui.main;
|
||||
const Ripples = imports.ui.ripples;
|
||||
import * as DND from './dnd.js';
|
||||
import Main from './main.js';
|
||||
import * as Ripples from './ripples.js';
|
||||
|
||||
var STARTUP_ANIMATION_TIME = 500;
|
||||
var BACKGROUND_FADE_ANIMATION_TIME = 1000;
|
||||
export let STARTUP_ANIMATION_TIME = 500;
|
||||
export let BACKGROUND_FADE_ANIMATION_TIME = 1000;
|
||||
|
||||
var HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
|
||||
var HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
|
||||
export let HOT_CORNER_PRESSURE_THRESHOLD = 100; // pixels
|
||||
export let HOT_CORNER_PRESSURE_TIMEOUT = 1000; // ms
|
||||
|
||||
function isPopupMetaWindow(actor) {
|
||||
switch (actor.meta_window.get_window_type()) {
|
||||
|
|
@ -28,7 +34,7 @@ function isPopupMetaWindow(actor) {
|
|||
}
|
||||
}
|
||||
|
||||
var MonitorConstraint = GObject.registerClass({
|
||||
export const MonitorConstraint = GObject.registerClass({
|
||||
Properties: {
|
||||
'primary': GObject.ParamSpec.boolean('primary',
|
||||
'Primary', 'Track primary monitor',
|
||||
|
|
@ -44,6 +50,9 @@ var MonitorConstraint = GObject.registerClass({
|
|||
false),
|
||||
},
|
||||
}, class MonitorConstraint extends Clutter.Constraint {
|
||||
/**
|
||||
* @param {*} props
|
||||
*/
|
||||
_init(props) {
|
||||
this._primary = false;
|
||||
this._index = -1;
|
||||
|
|
@ -145,7 +154,7 @@ var MonitorConstraint = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var Monitor = class Monitor {
|
||||
export class Monitor {
|
||||
constructor(index, geometry, geometryScale) {
|
||||
this.index = index;
|
||||
this.x = geometry.x;
|
||||
|
|
@ -162,11 +171,17 @@ var Monitor = class Monitor {
|
|||
|
||||
const UiActor = GObject.registerClass(
|
||||
class UiActor extends St.Widget {
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(_forHeight) {
|
||||
let width = global.stage.width;
|
||||
return [width, width];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(_forWidth) {
|
||||
let height = global.stage.height;
|
||||
return [height, height];
|
||||
|
|
@ -179,7 +194,7 @@ const defaultParams = {
|
|||
affectsInputRegion: true,
|
||||
};
|
||||
|
||||
var LayoutManager = GObject.registerClass({
|
||||
export const LayoutManager = GObject.registerClass({
|
||||
Signals: {
|
||||
'hot-corners-changed': {},
|
||||
'startup-complete': {},
|
||||
|
|
@ -244,7 +259,7 @@ var LayoutManager = GObject.registerClass({
|
|||
trackFullscreen: true });
|
||||
this.panelBox.connect('notify::allocation',
|
||||
this._panelBoxChanged.bind(this));
|
||||
|
||||
log('initing?');
|
||||
this.modalDialogGroup = new St.Widget({ name: 'modalDialogGroup',
|
||||
layout_manager: new Clutter.BinLayout() });
|
||||
this.uiGroup.add_actor(this.modalDialogGroup);
|
||||
|
|
@ -296,7 +311,7 @@ var LayoutManager = GObject.registerClass({
|
|||
// This is called by Main after everything else is constructed
|
||||
init() {
|
||||
Main.sessionMode.connect('updated', this._sessionUpdated.bind(this));
|
||||
|
||||
log('testing?');
|
||||
this._loadBackground();
|
||||
}
|
||||
|
||||
|
|
@ -503,6 +518,7 @@ var LayoutManager = GObject.registerClass({
|
|||
}
|
||||
|
||||
_panelBoxChanged() {
|
||||
log('panel box changed')
|
||||
this._updatePanelBarrier();
|
||||
|
||||
let size = this.panelBox.height;
|
||||
|
|
@ -532,6 +548,7 @@ var LayoutManager = GObject.registerClass({
|
|||
}
|
||||
|
||||
_monitorsChanged() {
|
||||
log('monitor?');
|
||||
this._updateMonitors();
|
||||
this._updateBoxes();
|
||||
this._updateHotCorners();
|
||||
|
|
@ -606,8 +623,9 @@ var LayoutManager = GObject.registerClass({
|
|||
this._systemBackground.add_constraint(constraint);
|
||||
|
||||
let signalId = this._systemBackground.connect('loaded', () => {
|
||||
log('loaded!');
|
||||
this._systemBackground.disconnect(signalId);
|
||||
|
||||
log('p2');
|
||||
// We're mostly prepared for the startup animation
|
||||
// now, but since a lot is going on asynchronously
|
||||
// during startup, let's defer the startup animation
|
||||
|
|
@ -615,6 +633,7 @@ var LayoutManager = GObject.registerClass({
|
|||
// This helps to prevent us from running the animation
|
||||
// when the system is bogged down
|
||||
const id = GLib.idle_add(GLib.PRIORITY_LOW, () => {
|
||||
log('idling...');
|
||||
this._systemBackground.show();
|
||||
global.stage.show();
|
||||
this._prepareStartupAnimation();
|
||||
|
|
@ -640,6 +659,7 @@ var LayoutManager = GObject.registerClass({
|
|||
// of the screen.
|
||||
|
||||
async _prepareStartupAnimation() {
|
||||
log('preparing...');
|
||||
// During the initial transition, add a simple actor to block all events,
|
||||
// so they don't get delivered to X11 windows that have been transformed.
|
||||
this._coverPane = new Clutter.Actor({ opacity: 0,
|
||||
|
|
@ -676,25 +696,31 @@ var LayoutManager = GObject.registerClass({
|
|||
}
|
||||
|
||||
global.window_group.set_clip(monitor.x, monitor.y, monitor.width, monitor.height);
|
||||
|
||||
log('update backgrounds?');
|
||||
await this._updateBackgrounds();
|
||||
}
|
||||
|
||||
log('prepared?');
|
||||
|
||||
this.emit('startup-prepared');
|
||||
|
||||
this._startupAnimation();
|
||||
}
|
||||
|
||||
_startupAnimation() {
|
||||
if (Meta.is_restart())
|
||||
if (Meta.is_restart()) {
|
||||
log('testing')
|
||||
this._startupAnimationComplete();
|
||||
else if (Main.sessionMode.isGreeter)
|
||||
} else if (Main.sessionMode.isGreeter)
|
||||
this._startupAnimationGreeter();
|
||||
else
|
||||
else {
|
||||
log ('test 213');
|
||||
this._startupAnimationSession();
|
||||
}
|
||||
}
|
||||
|
||||
_startupAnimationGreeter() {
|
||||
log('greet start');
|
||||
this.panelBox.ease({
|
||||
translation_y: 0,
|
||||
duration: STARTUP_ANIMATION_TIME,
|
||||
|
|
@ -704,6 +730,7 @@ var LayoutManager = GObject.registerClass({
|
|||
}
|
||||
|
||||
_startupAnimationSession() {
|
||||
log('greet sesh start');
|
||||
const onComplete = () => this._startupAnimationComplete();
|
||||
if (Main.sessionMode.hasOverview) {
|
||||
Main.overview.runStartupAnimation(onComplete);
|
||||
|
|
@ -720,6 +747,7 @@ var LayoutManager = GObject.registerClass({
|
|||
}
|
||||
|
||||
_startupAnimationComplete() {
|
||||
log('Animation compl')
|
||||
this._coverPane.destroy();
|
||||
this._coverPane = null;
|
||||
|
||||
|
|
@ -852,14 +880,15 @@ var LayoutManager = GObject.registerClass({
|
|||
if (this._findActor(actor) != -1)
|
||||
throw new Error('trying to re-track existing chrome actor');
|
||||
|
||||
let actorData = { ...defaultParams, ...params };
|
||||
actorData.actor = actor;
|
||||
actorData.visibleId = actor.connect('notify::visible',
|
||||
this._queueUpdateRegions.bind(this));
|
||||
actorData.allocationId = actor.connect('notify::allocation',
|
||||
this._queueUpdateRegions.bind(this));
|
||||
actorData.destroyId = actor.connect('destroy',
|
||||
this._untrackActor.bind(this));
|
||||
let actorData = { ...defaultParams, ...params,
|
||||
actor: actor,
|
||||
isibleId : actor.connect('notify::visible',
|
||||
this._queueUpdateRegions.bind(this)),
|
||||
allocationId : actor.connect('notify::allocation',
|
||||
this._queueUpdateRegions.bind(this)),
|
||||
destroyId: actor.connect('destroy',
|
||||
this._untrackActor.bind(this)),
|
||||
};
|
||||
// Note that destroying actor will unset its parent, so we don't
|
||||
// need to connect to 'destroy' too.
|
||||
|
||||
|
|
@ -1069,7 +1098,7 @@ var LayoutManager = GObject.registerClass({
|
|||
//
|
||||
// This class manages a "hot corner" that can toggle switching to
|
||||
// overview.
|
||||
var HotCorner = GObject.registerClass(
|
||||
export const HotCorner = GObject.registerClass(
|
||||
class HotCorner extends Clutter.Actor {
|
||||
_init(layoutManager, monitor, x, y) {
|
||||
super._init();
|
||||
|
|
@ -1227,7 +1256,7 @@ class HotCorner extends Clutter.Actor {
|
|||
}
|
||||
});
|
||||
|
||||
var PressureBarrier = class PressureBarrier extends Signals.EventEmitter {
|
||||
export class PressureBarrier extends Signals.EventEmitter {
|
||||
constructor(threshold, timeout, actionMode) {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Lightbox */
|
||||
|
||||
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';
|
||||
|
||||
|
||||
var DEFAULT_FADE_FACTOR = 0.4;
|
||||
var VIGNETTE_BRIGHTNESS = 0.5;
|
||||
var VIGNETTE_SHARPNESS = 0.7;
|
||||
export let DEFAULT_FADE_FACTOR = 0.4;
|
||||
export let VIGNETTE_BRIGHTNESS = 0.5;
|
||||
export let VIGNETTE_SHARPNESS = 0.7;
|
||||
|
||||
const VIGNETTE_DECLARATIONS = '\
|
||||
uniform float brightness;\n\
|
||||
|
|
@ -21,7 +24,7 @@ t = clamp(t, 0.0, 1.0);\n\
|
|||
float pixel_brightness = mix(1.0, 1.0 - vignette_sharpness, t);\n\
|
||||
cogl_color_out.a = cogl_color_out.a * (1 - pixel_brightness * brightness);';
|
||||
|
||||
var RadialShaderEffect = GObject.registerClass({
|
||||
export const RadialShaderEffect = GObject.registerClass({
|
||||
Properties: {
|
||||
'brightness': GObject.ParamSpec.float(
|
||||
'brightness', 'brightness', 'brightness',
|
||||
|
|
@ -102,7 +105,7 @@ var RadialShaderEffect = GObject.registerClass({
|
|||
* @container and will track any changes in its size. You can override
|
||||
* this by passing an explicit width and height in @params.
|
||||
*/
|
||||
var Lightbox = GObject.registerClass({
|
||||
export const Lightbox = GObject.registerClass({
|
||||
Properties: {
|
||||
'active': GObject.ParamSpec.boolean(
|
||||
'active', 'active', 'active', GObject.ParamFlags.READABLE, false),
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported LocatePointer */
|
||||
|
||||
const { Gio } = imports.gi;
|
||||
const Ripples = imports.ui.ripples;
|
||||
const Main = imports.ui.main;
|
||||
import Gio from 'gi://Gio';
|
||||
import * as Ripples from './ripples.js';
|
||||
import Main from './main.js';
|
||||
|
||||
const LOCATE_POINTER_KEY = "locate-pointer";
|
||||
const LOCATE_POINTER_SCHEMA = "org.gnome.desktop.interface";
|
||||
|
||||
var LocatePointer = class {
|
||||
export class LocatePointer {
|
||||
constructor() {
|
||||
this._settings = new Gio.Settings({ schema_id: LOCATE_POINTER_SCHEMA });
|
||||
this._settings.connect(`changed::${LOCATE_POINTER_KEY}`, () => this._syncEnabled());
|
||||
|
|
|
|||
|
|
@ -1,16 +1,24 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported LookingGlass */
|
||||
|
||||
const { Clutter, Cogl, Gio, GLib, GObject,
|
||||
Graphene, Meta, Pango, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
const System = imports.system;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Cogl from 'gi://Cogl';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Graphene from 'gi://Graphene';
|
||||
import Meta from 'gi://Meta';
|
||||
import Pango from 'gi://Pango';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
import System from 'system';
|
||||
|
||||
const History = imports.misc.history;
|
||||
const ExtensionUtils = imports.misc.extensionUtils;
|
||||
const ShellEntry = imports.ui.shellEntry;
|
||||
const Main = imports.ui.main;
|
||||
const JsParse = imports.misc.jsParse;
|
||||
import * as History from '../misc/history.js';
|
||||
import * as ExtensionUtils from '../misc/extensionUtils.js';
|
||||
import * as ShellEntry from './shellEntry.js';
|
||||
import Main from './main.js';
|
||||
import * as JsParse from '../misc/jsParse.js';
|
||||
|
||||
const { ExtensionState } = ExtensionUtils;
|
||||
|
||||
|
|
@ -18,7 +26,7 @@ const CHEVRON = '>>> ';
|
|||
|
||||
/* Imports...feel free to add here as needed */
|
||||
var commandHeader = 'const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi; ' +
|
||||
'const Main = imports.ui.main; ' +
|
||||
'const Main = getMain(); ' +
|
||||
/* Utility functions...we should probably be able to use these
|
||||
* in the shell core code too. */
|
||||
'const stage = global.stage; ' +
|
||||
|
|
@ -29,9 +37,10 @@ var commandHeader = 'const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = im
|
|||
|
||||
const HISTORY_KEY = 'looking-glass-history';
|
||||
// Time between tabs for them to count as a double-tab event
|
||||
var AUTO_COMPLETE_DOUBLE_TAB_DELAY = 500;
|
||||
var AUTO_COMPLETE_SHOW_COMPLETION_ANIMATION_DURATION = 200;
|
||||
var AUTO_COMPLETE_GLOBAL_KEYWORDS = _getAutoCompleteGlobalKeywords();
|
||||
|
||||
export let AUTO_COMPLETE_DOUBLE_TAB_DELAY = 500;
|
||||
export let AUTO_COMPLETE_SHOW_COMPLETION_ANIMATION_DURATION = 200;
|
||||
export let AUTO_COMPLETE_GLOBAL_KEYWORDS = _getAutoCompleteGlobalKeywords();
|
||||
|
||||
const LG_ANIMATION_TIME = 500;
|
||||
|
||||
|
|
@ -45,7 +54,7 @@ function _getAutoCompleteGlobalKeywords() {
|
|||
return keywords.concat(windowProperties).concat(headerProperties);
|
||||
}
|
||||
|
||||
var AutoComplete = class AutoComplete extends Signals.EventEmitter {
|
||||
export class AutoComplete extends Signals.EventEmitter {
|
||||
constructor(entry) {
|
||||
super();
|
||||
|
||||
|
|
@ -109,8 +118,7 @@ var AutoComplete = class AutoComplete extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
var Notebook = GObject.registerClass({
|
||||
export const Notebook = GObject.registerClass({
|
||||
Signals: { 'selection': { param_types: [Clutter.Actor.$gtype] } },
|
||||
}, class Notebook extends St.BoxLayout {
|
||||
_init() {
|
||||
|
|
@ -253,8 +261,14 @@ function objectToString(o) {
|
|||
}
|
||||
}
|
||||
|
||||
var ObjLink = GObject.registerClass(
|
||||
export const ObjLink = GObject.registerClass(
|
||||
/** @extends {St.Button<Clutter.Text>} */
|
||||
class ObjLink extends St.Button {
|
||||
/**
|
||||
* @param {*} lookingGlass
|
||||
* @param {*} o
|
||||
* @param {*} title
|
||||
*/
|
||||
_init(lookingGlass, o, title) {
|
||||
let text;
|
||||
if (title)
|
||||
|
|
@ -281,8 +295,14 @@ class ObjLink extends St.Button {
|
|||
}
|
||||
});
|
||||
|
||||
var Result = GObject.registerClass(
|
||||
export const Result = GObject.registerClass(
|
||||
class Result extends St.BoxLayout {
|
||||
/**
|
||||
* @param {*} lookingGlass
|
||||
* @param {*} command
|
||||
* @param {*} o
|
||||
* @param {*} index
|
||||
*/
|
||||
_init(lookingGlass, command, o, index) {
|
||||
super._init({ vertical: true });
|
||||
|
||||
|
|
@ -304,8 +324,11 @@ class Result extends St.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var WindowList = GObject.registerClass({
|
||||
export const WindowList = GObject.registerClass({
|
||||
}, class WindowList extends St.BoxLayout {
|
||||
/**
|
||||
* @param {*} lookingGlass
|
||||
*/
|
||||
_init(lookingGlass) {
|
||||
super._init({ name: 'Windows', vertical: true, style: 'spacing: 8px' });
|
||||
let tracker = Shell.WindowTracker.get_default();
|
||||
|
|
@ -357,8 +380,11 @@ var WindowList = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ObjInspector = GObject.registerClass(
|
||||
export const ObjInspector = GObject.registerClass(
|
||||
class ObjInspector extends St.ScrollView {
|
||||
/**
|
||||
* @param {*} lookingGlass
|
||||
*/
|
||||
_init(lookingGlass) {
|
||||
super._init({
|
||||
pivot_point: new Graphene.Point({ x: 0.5, y: 0.5 }),
|
||||
|
|
@ -397,7 +423,8 @@ class ObjInspector extends St.ScrollView {
|
|||
text: 'Inspecting: %s: %s'.format(typeof obj, objectToString(obj)),
|
||||
x_expand: true,
|
||||
});
|
||||
label.single_line_mode = true;
|
||||
// TODO: Is this the intended code?
|
||||
label.clutterText.single_line_mode = true;
|
||||
hbox.add_child(label);
|
||||
let button = new St.Button({ label: 'Insert', style_class: 'lg-obj-inspector-button' });
|
||||
button.connect('clicked', this._onInsert.bind(this));
|
||||
|
|
@ -475,7 +502,7 @@ class ObjInspector extends St.ScrollView {
|
|||
}
|
||||
});
|
||||
|
||||
var RedBorderEffect = GObject.registerClass(
|
||||
export const RedBorderEffect = GObject.registerClass(
|
||||
class RedBorderEffect extends Clutter.Effect {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -527,7 +554,7 @@ class RedBorderEffect extends Clutter.Effect {
|
|||
}
|
||||
});
|
||||
|
||||
var Inspector = GObject.registerClass({
|
||||
export const Inspector = GObject.registerClass({
|
||||
Signals: { 'closed': {},
|
||||
'target': { param_types: [Clutter.Actor.$gtype, GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] } },
|
||||
}, class Inspector extends Clutter.Actor {
|
||||
|
|
@ -667,7 +694,7 @@ var Inspector = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var Extensions = GObject.registerClass({
|
||||
export const Extensions = GObject.registerClass({
|
||||
}, class Extensions extends St.BoxLayout {
|
||||
_init(lookingGlass) {
|
||||
super._init({ vertical: true, name: 'lookingGlassExtensions' });
|
||||
|
|
@ -820,7 +847,7 @@ var Extensions = GObject.registerClass({
|
|||
});
|
||||
|
||||
|
||||
var ActorLink = GObject.registerClass({
|
||||
export const ActorLink = GObject.registerClass({
|
||||
Signals: {
|
||||
'inspect-actor': {},
|
||||
},
|
||||
|
|
@ -877,7 +904,7 @@ var ActorLink = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ActorTreeViewer = GObject.registerClass(
|
||||
export const ActorTreeViewer = GObject.registerClass(
|
||||
class ActorTreeViewer extends St.BoxLayout {
|
||||
_init(lookingGlass) {
|
||||
super._init();
|
||||
|
|
@ -1004,7 +1031,7 @@ class ActorTreeViewer extends St.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var LookingGlass = GObject.registerClass(
|
||||
export const LookingGlass = GObject.registerClass(
|
||||
class LookingGlass extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -1093,6 +1120,7 @@ class LookingGlass extends St.BoxLayout {
|
|||
this._evalBox = new St.BoxLayout({ name: 'EvalBox', vertical: true });
|
||||
notebook.appendPage('Evaluator', this._evalBox);
|
||||
|
||||
/** @type {St.BoxLayout<Result["prototype"]>} */
|
||||
this._resultsArea = new St.BoxLayout({
|
||||
name: 'ResultsArea',
|
||||
vertical: true,
|
||||
|
|
@ -1270,7 +1298,7 @@ class LookingGlass extends St.BoxLayout {
|
|||
|
||||
getResult(idx) {
|
||||
try {
|
||||
return this._resultsArea.get_child_at_index(idx - this._offset).o;
|
||||
return /** @type {Result["prototype"]} */ (this._resultsArea.get_child_at_index(idx - this._offset)).o;
|
||||
} catch (e) {
|
||||
throw new Error('Unknown result at index %d'.format(idx));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,28 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Magnifier */
|
||||
|
||||
const { Atspi, Clutter, GDesktopEnums,
|
||||
Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Atspi from 'gi://Atspi';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GDesktopEnums from 'gi://GDesktopEnums';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Background = imports.ui.background;
|
||||
const FocusCaretTracker = imports.ui.focusCaretTracker;
|
||||
const Main = imports.ui.main;
|
||||
const PointerWatcher = imports.ui.pointerWatcher;
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
var CROSSHAIRS_CLIP_SIZE = [100, 100];
|
||||
var NO_CHANGE = 0.0;
|
||||
import * as Background from './background.js';
|
||||
import * as FocusCaretTracker from './focusCaretTracker.js';
|
||||
import Main from './main.js';
|
||||
import * as PointerWatcher from './pointerWatcher.js';
|
||||
|
||||
var POINTER_REST_TIME = 1000; // milliseconds
|
||||
/** @type {[number, number]} */
|
||||
export const CROSSHAIRS_CLIP_SIZE = [100, 100];
|
||||
export const NO_CHANGE = 0.0;
|
||||
|
||||
export const POINTER_REST_TIME = 1000; // milliseconds
|
||||
|
||||
// Settings
|
||||
const MAGNIFIER_SCHEMA = 'org.gnome.desktop.a11y.magnifier';
|
||||
|
|
@ -39,7 +48,7 @@ const CROSS_HAIRS_OPACITY_KEY = 'cross-hairs-opacity';
|
|||
const CROSS_HAIRS_LENGTH_KEY = 'cross-hairs-length';
|
||||
const CROSS_HAIRS_CLIP_KEY = 'cross-hairs-clip';
|
||||
|
||||
var MouseSpriteContent = GObject.registerClass({
|
||||
export const MouseSpriteContent = GObject.registerClass({
|
||||
Implements: [Clutter.Content],
|
||||
}, class MouseSpriteContent extends GObject.Object {
|
||||
_init() {
|
||||
|
|
@ -72,6 +81,9 @@ var MouseSpriteContent = GObject.registerClass({
|
|||
return this._texture;
|
||||
}
|
||||
|
||||
/**
|
||||
* @this {this & Clutter.Content}
|
||||
*/
|
||||
set texture(coglTexture) {
|
||||
if (this._texture == coglTexture)
|
||||
return;
|
||||
|
|
@ -87,7 +99,7 @@ var MouseSpriteContent = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var Magnifier = class Magnifier extends Signals.EventEmitter {
|
||||
export class Magnifier extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -98,8 +110,10 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
let cursorTracker = Meta.CursorTracker.get_for_display(global.display);
|
||||
this._cursorTracker = cursorTracker;
|
||||
|
||||
this._mouseSprite = new Clutter.Actor({ request_mode: Clutter.RequestMode.CONTENT_SIZE });
|
||||
this._mouseSprite.content = new MouseSpriteContent();
|
||||
this._mouseSprite = new Clutter.Actor({
|
||||
request_mode: Clutter.RequestMode.CONTENT_SIZE,
|
||||
content: new MouseSpriteContent()
|
||||
});
|
||||
|
||||
// Create the first ZoomRegion and initialize it according to the
|
||||
// magnification settings.
|
||||
|
|
@ -145,7 +159,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
/**
|
||||
* setActive:
|
||||
* Show/hide all the zoom regions.
|
||||
* @param {bool} activate: Boolean to activate or de-activate the magnifier.
|
||||
* @param {boolean} activate: Boolean to activate or de-activate the magnifier.
|
||||
*/
|
||||
setActive(activate) {
|
||||
let isActive = this.isActive();
|
||||
|
|
@ -185,7 +199,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
|
||||
/**
|
||||
* isActive:
|
||||
* @returns {bool} Whether the magnifier is active.
|
||||
* @returns {boolean} Whether the magnifier is active.
|
||||
*/
|
||||
isActive() {
|
||||
// Sufficient to check one ZoomRegion since Magnifier's active
|
||||
|
|
@ -220,7 +234,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
|
||||
/**
|
||||
* isTrackingMouse:
|
||||
* @returns {bool} whether the magnifier is currently tracking the mouse
|
||||
* @returns {boolean} whether the magnifier is currently tracking the mouse
|
||||
*/
|
||||
isTrackingMouse() {
|
||||
return !!this._pointerWatch;
|
||||
|
|
@ -297,7 +311,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
/**
|
||||
* getZoomRegions:
|
||||
* Return a list of ZoomRegion's for this Magnifier.
|
||||
* @returns {number[]} The Magnifier's zoom region list.
|
||||
* @returns {ZoomRegion[]} The Magnifier's zoom region list.
|
||||
*/
|
||||
getZoomRegions() {
|
||||
return this._zoomRegions;
|
||||
|
|
@ -345,7 +359,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
/**
|
||||
* setCrosshairsVisible:
|
||||
* Show or hide the cross hair.
|
||||
* @param {bool} visible: Flag that indicates show (true) or hide (false).
|
||||
* @param {boolean} visible: Flag that indicates show (true) or hide (false).
|
||||
*/
|
||||
setCrosshairsVisible(visible) {
|
||||
if (visible) {
|
||||
|
|
@ -405,17 +419,6 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
this._crossHairs.setOpacity(opacity * 255);
|
||||
}
|
||||
|
||||
/**
|
||||
* getCrosshairsOpacity:
|
||||
* @returns {number} Value between 0.0 (transparent) and 1.0 (fully opaque).
|
||||
*/
|
||||
getCrosshairsOpacity() {
|
||||
if (this._crossHairs)
|
||||
return this._crossHairs.getOpacity() / 255.0;
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* setCrosshairsLength:
|
||||
* Set the crosshairs length for all ZoomRegions.
|
||||
|
|
@ -445,7 +448,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
/**
|
||||
* setCrosshairsClip:
|
||||
* Set whether the crosshairs are clipped at their intersection.
|
||||
* @param {bool} clip: Flag to indicate whether to clip the crosshairs.
|
||||
* @param {boolean} clip: Flag to indicate whether to clip the crosshairs.
|
||||
*/
|
||||
setCrosshairsClip(clip) {
|
||||
if (!this._crossHairs)
|
||||
|
|
@ -458,7 +461,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
/**
|
||||
* getCrosshairsClip:
|
||||
* Get whether the crosshairs are clipped by the mouse image.
|
||||
* @returns {bool} Whether the crosshairs are clipped.
|
||||
* @returns {boolean} Whether the crosshairs are clipped.
|
||||
*/
|
||||
getCrosshairsClip() {
|
||||
if (this._crossHairs) {
|
||||
|
|
@ -577,9 +580,9 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
if (aPref)
|
||||
zoomRegion.setCaretTrackingMode(aPref);
|
||||
|
||||
aPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY);
|
||||
if (aPref)
|
||||
zoomRegion.setInvertLightness(aPref);
|
||||
let aBoolPref = this._settings.get_boolean(INVERT_LIGHTNESS_KEY);
|
||||
if (aBoolPref)
|
||||
zoomRegion.setInvertLightness(aBoolPref);
|
||||
|
||||
aPref = this._settings.get_double(COLOR_SATURATION_KEY);
|
||||
if (aPref)
|
||||
|
|
@ -698,7 +701,7 @@ var Magnifier = class Magnifier extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var ZoomRegion = class ZoomRegion {
|
||||
export class ZoomRegion {
|
||||
constructor(magnifier, mouseSourceActor) {
|
||||
this._magnifier = magnifier;
|
||||
this._focusCaretTracker = new FocusCaretTracker.FocusCaretTracker();
|
||||
|
|
@ -749,11 +752,11 @@ var ZoomRegion = class ZoomRegion {
|
|||
this._monitorsChanged.bind(this));
|
||||
this._signalConnections.push([Main.layoutManager, id]);
|
||||
|
||||
id = this._focusCaretTracker.connect('caret-moved', this._updateCaret.bind(this));
|
||||
this._signalConnections.push([this._focusCaretTracker, id]);
|
||||
let focusId = this._focusCaretTracker.connect('caret-moved', this._updateCaret.bind(this));
|
||||
this._signalConnections.push([this._focusCaretTracker, focusId]);
|
||||
|
||||
id = this._focusCaretTracker.connect('focus-changed', this._updateFocus.bind(this));
|
||||
this._signalConnections.push([this._focusCaretTracker, id]);
|
||||
focusId = this._focusCaretTracker.connect('focus-changed', this._updateFocus.bind(this));
|
||||
this._signalConnections.push([this._focusCaretTracker, focusId]);
|
||||
}
|
||||
|
||||
_disconnectSignals() {
|
||||
|
|
@ -827,7 +830,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
|
||||
/**
|
||||
* setActive:
|
||||
* @param {bool} activate: Boolean to show/hide the ZoomRegion.
|
||||
* @param {boolean} activate: Boolean to show/hide the ZoomRegion.
|
||||
*/
|
||||
setActive(activate) {
|
||||
if (activate == this.isActive())
|
||||
|
|
@ -854,7 +857,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
|
||||
/**
|
||||
* isActive:
|
||||
* @returns {bool} Whether this ZoomRegion is active
|
||||
* @returns {boolean} Whether this ZoomRegion is active
|
||||
*/
|
||||
isActive() {
|
||||
return this._magView != null;
|
||||
|
|
@ -993,7 +996,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
* setLensMode:
|
||||
* Turn lens mode on/off. In full screen mode, lens mode does nothing since
|
||||
* a lens the size of the screen is pointless.
|
||||
* @param {bool} lensMode: Whether lensMode should be active
|
||||
* @param {boolean} lensMode: Whether lensMode should be active
|
||||
*/
|
||||
setLensMode(lensMode) {
|
||||
this._lensMode = lensMode;
|
||||
|
|
@ -1004,7 +1007,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
/**
|
||||
* isLensMode:
|
||||
* Is lens mode on or off?
|
||||
* @returns {bool} The lens mode state.
|
||||
* @returns {boolean} The lens mode state.
|
||||
*/
|
||||
isLensMode() {
|
||||
return this._lensMode;
|
||||
|
|
@ -1014,7 +1017,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
* setClampScrollingAtEdges:
|
||||
* Stop vs. allow scrolling of the magnified contents when it scroll beyond
|
||||
* the edges of the screen.
|
||||
* @param {bool} clamp: Boolean to turn on/off clamping.
|
||||
* @param {boolean} clamp: Boolean to turn on/off clamping.
|
||||
*/
|
||||
setClampScrollingAtEdges(clamp) {
|
||||
this._clampScrollingAtEdges = clamp;
|
||||
|
|
@ -1140,7 +1143,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
/**
|
||||
* scrollToMousePos:
|
||||
* Set the region of interest based on the position of the system pointer.
|
||||
* @returns {bool}: Whether the system mouse pointer is over the
|
||||
* @returns {boolean}: Whether the system mouse pointer is over the
|
||||
* magnified view.
|
||||
*/
|
||||
scrollToMousePos() {
|
||||
|
|
@ -1200,7 +1203,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
/**
|
||||
* addCrosshairs:
|
||||
* Add crosshairs centered on the magnified mouse.
|
||||
* @param {Crosshairs} crossHairs: Crosshairs instance
|
||||
* @param {Crosshairs["prototype"]} crossHairs: Crosshairs instance
|
||||
*/
|
||||
addCrosshairs(crossHairs) {
|
||||
this._crossHairs = crossHairs;
|
||||
|
|
@ -1214,7 +1217,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
/**
|
||||
* setInvertLightness:
|
||||
* Set whether to invert the lightness of the magnified view.
|
||||
* @param {bool} flag: whether brightness should be inverted
|
||||
* @param {boolean} flag: whether brightness should be inverted
|
||||
*/
|
||||
setInvertLightness(flag) {
|
||||
this._invertLightness = flag;
|
||||
|
|
@ -1225,7 +1228,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
/**
|
||||
* getInvertLightness:
|
||||
* Retrieve whether the lightness is inverted.
|
||||
* @returns {bool} whether brightness should be inverted
|
||||
* @returns {boolean} whether brightness should be inverted
|
||||
*/
|
||||
getInvertLightness() {
|
||||
return this._invertLightness;
|
||||
|
|
@ -1650,7 +1653,7 @@ var ZoomRegion = class ZoomRegion {
|
|||
}
|
||||
};
|
||||
|
||||
var Crosshairs = GObject.registerClass(
|
||||
export const Crosshairs = GObject.registerClass(
|
||||
class Crosshairs extends Clutter.Actor {
|
||||
_init() {
|
||||
// Set the group containing the crosshairs to three times the desktop
|
||||
|
|
@ -1825,7 +1828,7 @@ class Crosshairs extends Clutter.Actor {
|
|||
* setClip:
|
||||
* Set the width and height of the rectangle that clips the crosshairs at
|
||||
* their intersection
|
||||
* @param {number[]} size: Array of [width, height] defining the size
|
||||
* @param {[number, number]} size: Array of [width, height] defining the size
|
||||
* of the clip rectangle.
|
||||
*/
|
||||
setClip(size) {
|
||||
|
|
@ -1841,12 +1844,16 @@ class Crosshairs extends Clutter.Actor {
|
|||
}
|
||||
}
|
||||
|
||||
getClip() {
|
||||
return this._clipSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* reCenter:
|
||||
* Reposition the horizontal and vertical hairs such that they cross at
|
||||
* the center of crosshairs group. If called with the dimensions of
|
||||
* the clip rectangle, these are used to update the size of the clip.
|
||||
* @param {number[]=} clipSize: If present, the clip's [width, height].
|
||||
* @param {[number, number]} [clipSize]: If present, the clip's [width, height].
|
||||
*/
|
||||
reCenter(clipSize) {
|
||||
let [groupWidth, groupHeight] = this.get_size();
|
||||
|
|
@ -1871,7 +1878,7 @@ class Crosshairs extends Clutter.Actor {
|
|||
}
|
||||
});
|
||||
|
||||
var MagShaderEffects = class MagShaderEffects {
|
||||
export class MagShaderEffects {
|
||||
constructor(uiGroupClone) {
|
||||
this._inverse = new Shell.InvertLightnessEffect();
|
||||
this._brightnessContrast = new Clutter.BrightnessContrastEffect();
|
||||
|
|
@ -1902,7 +1909,7 @@ var MagShaderEffects = class MagShaderEffects {
|
|||
/**
|
||||
* setInvertLightness:
|
||||
* Enable/disable invert lightness effect.
|
||||
* @param {bool} invertFlag: Enabled flag.
|
||||
* @param {boolean} invertFlag: Enabled flag.
|
||||
*/
|
||||
setInvertLightness(invertFlag) {
|
||||
this._inverse.set_enabled(invertFlag);
|
||||
|
|
|
|||
1541
js/ui/main.js
1541
js/ui/main.js
File diff suppressed because it is too large
Load diff
|
|
@ -1,14 +1,22 @@
|
|||
/* exported MessageListSection */
|
||||
const { Atk, Clutter, Gio, GLib,
|
||||
GObject, Graphene, Meta, Pango, St } = imports.gi;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Graphene from 'gi://Graphene';
|
||||
import Meta from 'gi://Meta';
|
||||
import Pango from 'gi://Pango';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Util = imports.misc.util;
|
||||
import Main from './main.js';
|
||||
import * as MessageTray from './messageTray.js';
|
||||
|
||||
var MESSAGE_ANIMATION_TIME = 100;
|
||||
import * as Util from '../misc/util.js';
|
||||
|
||||
var DEFAULT_EXPAND_LINES = 6;
|
||||
export let MESSAGE_ANIMATION_TIME = 100;
|
||||
|
||||
export let DEFAULT_EXPAND_LINES = 6;
|
||||
|
||||
function _fixMarkup(text, allowMarkup) {
|
||||
if (allowMarkup) {
|
||||
|
|
@ -31,7 +39,7 @@ function _fixMarkup(text, allowMarkup) {
|
|||
return GLib.markup_escape_text(text, -1);
|
||||
}
|
||||
|
||||
var URLHighlighter = GObject.registerClass(
|
||||
export const URLHighlighter = GObject.registerClass(
|
||||
class URLHighlighter extends St.Label {
|
||||
_init(text = '', lineWrap, allowMarkup) {
|
||||
super._init({
|
||||
|
|
@ -159,7 +167,7 @@ class URLHighlighter extends St.Label {
|
|||
}
|
||||
});
|
||||
|
||||
var ScaleLayout = GObject.registerClass(
|
||||
export const ScaleLayout = GObject.registerClass(
|
||||
class ScaleLayout extends Clutter.BinLayout {
|
||||
_init(params) {
|
||||
this._container = null;
|
||||
|
|
@ -188,6 +196,9 @@ class ScaleLayout extends Clutter.BinLayout {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(container, forHeight) {
|
||||
this._connectContainer(container);
|
||||
|
||||
|
|
@ -196,6 +207,9 @@ class ScaleLayout extends Clutter.BinLayout {
|
|||
Math.floor(nat * container.scale_x)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(container, forWidth) {
|
||||
this._connectContainer(container);
|
||||
|
||||
|
|
@ -205,7 +219,7 @@ class ScaleLayout extends Clutter.BinLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var LabelExpanderLayout = GObject.registerClass({
|
||||
export const LabelExpanderLayout = GObject.registerClass({
|
||||
Properties: {
|
||||
'expansion': GObject.ParamSpec.double('expansion',
|
||||
'Expansion',
|
||||
|
|
@ -215,6 +229,9 @@ var LabelExpanderLayout = GObject.registerClass({
|
|||
0, 1, 0),
|
||||
},
|
||||
}, class LabelExpanderLayout extends Clutter.LayoutManager {
|
||||
/**
|
||||
* @param {*} params
|
||||
*/
|
||||
_init(params) {
|
||||
this._expansion = 0;
|
||||
this._expandLines = DEFAULT_EXPAND_LINES;
|
||||
|
|
@ -251,6 +268,9 @@ var LabelExpanderLayout = GObject.registerClass({
|
|||
this._container = container;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(container, forHeight) {
|
||||
let [min, nat] = [0, 0];
|
||||
|
||||
|
|
@ -266,6 +286,9 @@ var LabelExpanderLayout = GObject.registerClass({
|
|||
return [min, nat];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(container, forWidth) {
|
||||
let [min, nat] = [0, 0];
|
||||
|
||||
|
|
@ -295,13 +318,17 @@ var LabelExpanderLayout = GObject.registerClass({
|
|||
});
|
||||
|
||||
|
||||
var Message = GObject.registerClass({
|
||||
export const Message = GObject.registerClass({
|
||||
Signals: {
|
||||
'close': {},
|
||||
'expanded': {},
|
||||
'unexpanded': {},
|
||||
},
|
||||
}, class Message extends St.Button {
|
||||
/**
|
||||
* @param {*} title
|
||||
* @param {*} body
|
||||
*/
|
||||
_init(title, body) {
|
||||
super._init({
|
||||
style_class: 'message',
|
||||
|
|
@ -313,6 +340,7 @@ var Message = GObject.registerClass({
|
|||
|
||||
this.expanded = false;
|
||||
this._useBodyMarkup = false;
|
||||
this.notification = null;
|
||||
|
||||
let vbox = new St.BoxLayout({
|
||||
vertical: true,
|
||||
|
|
@ -361,11 +389,11 @@ var Message = GObject.registerClass({
|
|||
});
|
||||
titleBox.add_actor(this._closeButton);
|
||||
|
||||
this._bodyStack = new St.Widget({ x_expand: true });
|
||||
this._bodyStack.layout_manager = new LabelExpanderLayout();
|
||||
this._bodyStack = new St.Widget({ x_expand: true, layout_manager: new LabelExpanderLayout() });
|
||||
|
||||
contentBox.add_actor(this._bodyStack);
|
||||
|
||||
this.bodyLabel = new URLHighlighter('', false, this._useBodyMarkup);
|
||||
this.bodyLabel = new URLHighlighter({ text: '', lineWrap: false, allowMarkup: this._useBodyMarkup });
|
||||
this.bodyLabel.add_style_class_name('message-body');
|
||||
this._bodyStack.add_actor(this.bodyLabel);
|
||||
this.setBody(body);
|
||||
|
|
@ -532,7 +560,7 @@ var Message = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var MessageListSection = GObject.registerClass({
|
||||
export const MessageListSection = GObject.registerClass({
|
||||
Properties: {
|
||||
'can-clear': GObject.ParamSpec.boolean(
|
||||
'can-clear', 'can-clear', 'can-clear',
|
||||
|
|
@ -557,6 +585,7 @@ var MessageListSection = GObject.registerClass({
|
|||
x_expand: true,
|
||||
});
|
||||
|
||||
/** @type {St.BoxLayout<St.Bin<Message["prototype"]>>} */
|
||||
this._list = new St.BoxLayout({ style_class: 'message-list-section-list',
|
||||
vertical: true });
|
||||
this.add_actor(this._list);
|
||||
|
|
|
|||
|
|
@ -3,32 +3,38 @@
|
|||
NotificationApplicationPolicy, Source, SourceActor,
|
||||
SystemNotificationSource, MessageTray */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, 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 Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Calendar = imports.ui.calendar;
|
||||
const GnomeSession = imports.misc.gnomeSession;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
import * as Calendar from './calendar.js';
|
||||
import * as GnomeSession from '../misc/gnomeSession.js';
|
||||
import * as Layout from './layout.js';
|
||||
import Main from './main.js';
|
||||
|
||||
const SHELL_KEYBINDINGS_SCHEMA = 'org.gnome.shell.keybindings';
|
||||
|
||||
var ANIMATION_TIME = 200;
|
||||
var NOTIFICATION_TIMEOUT = 4000;
|
||||
export let ANIMATION_TIME = 200;
|
||||
export let NOTIFICATION_TIMEOUT = 4000;
|
||||
|
||||
var HIDE_TIMEOUT = 200;
|
||||
var LONGER_HIDE_TIMEOUT = 600;
|
||||
export let HIDE_TIMEOUT = 200;
|
||||
export let LONGER_HIDE_TIMEOUT = 600;
|
||||
|
||||
var MAX_NOTIFICATIONS_IN_QUEUE = 3;
|
||||
var MAX_NOTIFICATIONS_PER_SOURCE = 3;
|
||||
var MAX_NOTIFICATION_BUTTONS = 3;
|
||||
export let MAX_NOTIFICATIONS_IN_QUEUE = 3;
|
||||
export let MAX_NOTIFICATIONS_PER_SOURCE = 3;
|
||||
export let MAX_NOTIFICATION_BUTTONS = 3;
|
||||
|
||||
// We delay hiding of the tray if the mouse is within MOUSE_LEFT_ACTOR_THRESHOLD
|
||||
// range from the point where it left the tray.
|
||||
var MOUSE_LEFT_ACTOR_THRESHOLD = 20;
|
||||
export let MOUSE_LEFT_ACTOR_THRESHOLD = 20;
|
||||
|
||||
var IDLE_TIME = 1000;
|
||||
export let IDLE_TIME = 1000;
|
||||
|
||||
var State = {
|
||||
export const State = {
|
||||
HIDDEN: 0,
|
||||
SHOWING: 1,
|
||||
SHOWN: 2,
|
||||
|
|
@ -42,7 +48,8 @@ var State = {
|
|||
// notifications that were requested to be destroyed by the associated source,
|
||||
// and REPLACED for notifications that were destroyed as a consequence of a
|
||||
// newer version having replaced them.
|
||||
var NotificationDestroyedReason = {
|
||||
/** @enum {number} */
|
||||
export const NotificationDestroyedReason = {
|
||||
EXPIRED: 1,
|
||||
DISMISSED: 2,
|
||||
SOURCE_CLOSED: 3,
|
||||
|
|
@ -53,7 +60,8 @@ var NotificationDestroyedReason = {
|
|||
// urgency values map to the corresponding values for the notifications received
|
||||
// through the notification daemon. HIGH urgency value is used for chats received
|
||||
// through the Telepathy client.
|
||||
var Urgency = {
|
||||
/** @enum {number} */
|
||||
export const Urgency = {
|
||||
LOW: 0,
|
||||
NORMAL: 1,
|
||||
HIGH: 2,
|
||||
|
|
@ -66,12 +74,13 @@ var Urgency = {
|
|||
// contain information private to the physical system (for example, battery
|
||||
// status) and hence the same for every user. This affects whether the content
|
||||
// of a notification is shown on the lock screen.
|
||||
var PrivacyScope = {
|
||||
/** @enum {number} */
|
||||
export const PrivacyScope = {
|
||||
USER: 0,
|
||||
SYSTEM: 1,
|
||||
};
|
||||
|
||||
var FocusGrabber = class FocusGrabber {
|
||||
export class FocusGrabber {
|
||||
constructor(actor) {
|
||||
this._actor = actor;
|
||||
this._prevKeyFocusActor = null;
|
||||
|
|
@ -132,7 +141,7 @@ var FocusGrabber = class FocusGrabber {
|
|||
// source, such as whether to play sound or honour the critical bit.
|
||||
//
|
||||
// A notification without a policy object will inherit the default one.
|
||||
var NotificationPolicy = GObject.registerClass({
|
||||
export const NotificationPolicy = GObject.registerClass({
|
||||
GTypeFlags: GObject.TypeFlags.ABSTRACT,
|
||||
Properties: {
|
||||
'enable': GObject.ParamSpec.boolean(
|
||||
|
|
@ -187,7 +196,7 @@ var NotificationPolicy = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var NotificationGenericPolicy = GObject.registerClass({
|
||||
export const NotificationGenericPolicy = GObject.registerClass({
|
||||
}, class NotificationGenericPolicy extends NotificationPolicy {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
@ -204,6 +213,7 @@ var NotificationGenericPolicy = GObject.registerClass({
|
|||
}
|
||||
|
||||
_changed(settings, key) {
|
||||
// @ts-expect-error this.constructor cannot be statically analyzed.
|
||||
if (this.constructor.find_property(key))
|
||||
this.notify(key);
|
||||
}
|
||||
|
|
@ -217,7 +227,7 @@ var NotificationGenericPolicy = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var NotificationApplicationPolicy = GObject.registerClass({
|
||||
export const NotificationApplicationPolicy = GObject.registerClass({
|
||||
}, class NotificationApplicationPolicy extends NotificationPolicy {
|
||||
_init(id) {
|
||||
super._init();
|
||||
|
|
@ -253,6 +263,8 @@ var NotificationApplicationPolicy = GObject.registerClass({
|
|||
}
|
||||
|
||||
_changed(settings, key) {
|
||||
// FIXME
|
||||
// @ts-expect-error
|
||||
if (this.constructor.find_property(key))
|
||||
this.notify(key);
|
||||
}
|
||||
|
|
@ -345,7 +357,7 @@ var NotificationApplicationPolicy = GObject.registerClass({
|
|||
// @source allows playing sounds).
|
||||
//
|
||||
// [1] https://developer.gnome.org/notification-spec/#markup
|
||||
var Notification = GObject.registerClass({
|
||||
export const Notification = GObject.registerClass({
|
||||
Properties: {
|
||||
'acknowledged': GObject.ParamSpec.boolean(
|
||||
'acknowledged', 'acknowledged', 'acknowledged',
|
||||
|
|
@ -358,6 +370,12 @@ var Notification = GObject.registerClass({
|
|||
'updated': { param_types: [GObject.TYPE_BOOLEAN] },
|
||||
},
|
||||
}, class Notification extends GObject.Object {
|
||||
/**
|
||||
* @param {*} source
|
||||
* @param {*} title
|
||||
* @param {*} banner
|
||||
* @param {*} params
|
||||
*/
|
||||
_init(source, title, banner, params) {
|
||||
super._init();
|
||||
|
||||
|
|
@ -376,6 +394,8 @@ var Notification = GObject.registerClass({
|
|||
this.actions = [];
|
||||
this.setResident(false);
|
||||
|
||||
this.answered = false;
|
||||
|
||||
// If called with only one argument we assume the caller
|
||||
// will call .update() later on. This is the case of
|
||||
// NotificationDaemon, which wants to use the same code
|
||||
|
|
@ -507,7 +527,7 @@ var Notification = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var NotificationBanner = GObject.registerClass({
|
||||
export const NotificationBanner = GObject.registerClass({
|
||||
Signals: {
|
||||
'done-displaying': {},
|
||||
'unfocused': {},
|
||||
|
|
@ -606,7 +626,7 @@ var NotificationBanner = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var SourceActor = GObject.registerClass(
|
||||
export const SourceActor = GObject.registerClass(
|
||||
class SourceActor extends St.Widget {
|
||||
_init(source, size) {
|
||||
super._init();
|
||||
|
|
@ -645,7 +665,13 @@ class SourceActor extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var Source = GObject.registerClass({
|
||||
/**
|
||||
* @typedef {object} SourceParams
|
||||
* @property {string} [title]
|
||||
* @property {string} [iconName]
|
||||
*/
|
||||
|
||||
export const Source = GObject.registerClass({
|
||||
Properties: {
|
||||
'count': GObject.ParamSpec.int(
|
||||
'count', 'count', 'count',
|
||||
|
|
@ -707,6 +733,9 @@ var Source = GObject.registerClass({
|
|||
this.notify('count');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {NotificationPolicy["prototype"]}
|
||||
*/
|
||||
_createPolicy() {
|
||||
return new NotificationGenericPolicy();
|
||||
}
|
||||
|
|
@ -737,6 +766,9 @@ var Source = GObject.registerClass({
|
|||
icon_size: size });
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Gio.Icon}
|
||||
*/
|
||||
getIcon() {
|
||||
return new Gio.ThemedIcon({ name: this.iconName });
|
||||
}
|
||||
|
|
@ -808,7 +840,7 @@ var Source = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var MessageTray = GObject.registerClass({
|
||||
export const MessageTray = GObject.registerClass({
|
||||
Signals: {
|
||||
'queue-changed': {},
|
||||
'source-added': { param_types: [Source.$gtype] },
|
||||
|
|
@ -822,7 +854,7 @@ var MessageTray = GObject.registerClass({
|
|||
layout_manager: new Clutter.BinLayout(),
|
||||
});
|
||||
|
||||
this._presence = new GnomeSession.Presence((proxy, _error) => {
|
||||
this._presence = GnomeSession.Presence((proxy, _error) => {
|
||||
this._onStatusChanged(proxy.status);
|
||||
});
|
||||
this._busy = false;
|
||||
|
|
@ -1438,10 +1470,10 @@ var MessageTray = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var SystemNotificationSource = GObject.registerClass(
|
||||
export const SystemNotificationSource = GObject.registerClass(
|
||||
class SystemNotificationSource extends Source {
|
||||
_init() {
|
||||
super._init(_("System Information"), 'dialog-information-symbolic');
|
||||
super._init({ title: _("System Information"), iconName: 'dialog-information-symbolic' });
|
||||
}
|
||||
|
||||
open() {
|
||||
|
|
|
|||
|
|
@ -1,17 +1,22 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported ModalDialog */
|
||||
|
||||
const { Atk, Clutter, GObject, Shell, St } = imports.gi;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Dialog = imports.ui.dialog;
|
||||
const Layout = imports.ui.layout;
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
const Main = imports.ui.main;
|
||||
import * as Dialog from './dialog.js';
|
||||
import * as Layout from './layout.js';
|
||||
import * as Lightbox from './lightbox.js';
|
||||
import Main from './main.js';
|
||||
|
||||
var OPEN_AND_CLOSE_TIME = 100;
|
||||
var FADE_OUT_DIALOG_TIME = 1000;
|
||||
export let OPEN_AND_CLOSE_TIME = 100;
|
||||
export let FADE_OUT_DIALOG_TIME = 1000;
|
||||
|
||||
var State = {
|
||||
/** @enum {number} */
|
||||
export const State = {
|
||||
OPENED: 0,
|
||||
CLOSED: 1,
|
||||
OPENING: 2,
|
||||
|
|
@ -19,7 +24,17 @@ var State = {
|
|||
FADED_OUT: 4,
|
||||
};
|
||||
|
||||
var ModalDialog = GObject.registerClass({
|
||||
/**
|
||||
* @typedef {object} ModalDialogParams
|
||||
* @property {boolean} shellReactive
|
||||
* @property {string | null} styleClass
|
||||
* @property {Shell.ActionMode} actionMode
|
||||
* @property {boolean} shouldFadeIn
|
||||
* @property {boolean} shouldFadeOut
|
||||
* @property {boolean} destroyOnClose
|
||||
*/
|
||||
|
||||
export const ModalDialog = GObject.registerClass({
|
||||
Properties: {
|
||||
'state': GObject.ParamSpec.int('state', 'Dialog state', 'state',
|
||||
GObject.ParamFlags.READABLE,
|
||||
|
|
@ -29,7 +44,7 @@ var ModalDialog = GObject.registerClass({
|
|||
},
|
||||
Signals: { 'opened': {}, 'closed': {} },
|
||||
}, class ModalDialog extends St.Widget {
|
||||
_init(params = {}) {
|
||||
_init(params = {}, ...args) {
|
||||
super._init({ visible: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
|
|
@ -258,7 +273,7 @@ var ModalDialog = GObject.registerClass({
|
|||
opacity: 0,
|
||||
duration: FADE_OUT_DIALOG_TIME,
|
||||
mode: Clutter.AnimationMode.EASE_OUT_QUAD,
|
||||
onComplete: () => (this.state = State.FADED_OUT),
|
||||
onComplete: () => (this._setState(State.FADED_OUT)),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
/* exported MediaSection */
|
||||
const { Gio, GObject, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const MessageList = imports.ui.messageList;
|
||||
import Main from './main.js';
|
||||
import * as MessageList from './messageList.js';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
const DBusIface = loadInterfaceXML('org.freedesktop.DBus');
|
||||
const DBusProxy = Gio.DBusProxy.makeProxyWrapper(DBusIface);
|
||||
|
|
@ -18,8 +21,11 @@ const MprisPlayerProxy = Gio.DBusProxy.makeProxyWrapper(MprisPlayerIface);
|
|||
|
||||
const MPRIS_PLAYER_PREFIX = 'org.mpris.MediaPlayer2.';
|
||||
|
||||
var MediaMessage = GObject.registerClass(
|
||||
export const MediaMessage = GObject.registerClass(
|
||||
class MediaMessage extends MessageList.Message {
|
||||
/**
|
||||
* @param {*} player
|
||||
*/
|
||||
_init(player) {
|
||||
super._init('', '');
|
||||
|
||||
|
|
@ -93,7 +99,7 @@ class MediaMessage extends MessageList.Message {
|
|||
}
|
||||
});
|
||||
|
||||
var MprisPlayer = class MprisPlayer extends Signals.EventEmitter {
|
||||
export class MprisPlayer extends Signals.EventEmitter {
|
||||
constructor(busName) {
|
||||
super();
|
||||
|
||||
|
|
@ -243,7 +249,7 @@ var MprisPlayer = class MprisPlayer extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var MediaSection = GObject.registerClass(
|
||||
export const MediaSection = GObject.registerClass(
|
||||
class MediaSection extends MessageList.MessageListSection {
|
||||
_init() {
|
||||
super._init();
|
||||
|
|
|
|||
|
|
@ -1,30 +1,37 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported NotificationDaemon */
|
||||
|
||||
const { GdkPixbuf, Gio, GLib, GObject, Shell, St } = imports.gi;
|
||||
import GdkPixbuf from 'gi://GdkPixbuf';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
import Main from './main.js';
|
||||
import * as MessageTray from './messageTray.js';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
const FdoNotificationsIface = loadInterfaceXML('org.freedesktop.Notifications');
|
||||
|
||||
var NotificationClosedReason = {
|
||||
/** @enum {number} */
|
||||
export const NotificationClosedReason = {
|
||||
EXPIRED: 1,
|
||||
DISMISSED: 2,
|
||||
APP_CLOSED: 3,
|
||||
UNDEFINED: 4,
|
||||
};
|
||||
|
||||
var Urgency = {
|
||||
/** @enum {number} */
|
||||
export const Urgency = {
|
||||
LOW: 0,
|
||||
NORMAL: 1,
|
||||
CRITICAL: 2,
|
||||
};
|
||||
|
||||
var FdoNotificationDaemon = class FdoNotificationDaemon {
|
||||
export class FdoNotificationDaemon {
|
||||
constructor() {
|
||||
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(FdoNotificationsIface, this);
|
||||
this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
|
||||
|
|
@ -187,7 +194,8 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
|
|||
let sender = invocation.get_sender();
|
||||
let pid = hints['sender-pid'];
|
||||
|
||||
let source = this._getSource(appName, pid, ndata, sender, null);
|
||||
// FIXME
|
||||
let source = this._getSource(appName, pid, ndata, sender);
|
||||
this._notifyForSource(source, ndata);
|
||||
|
||||
return invocation.return_value(GLib.Variant.new('(u)', [id]));
|
||||
|
|
@ -342,7 +350,15 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
|
|||
}
|
||||
};
|
||||
|
||||
var FdoNotificationDaemonSource = GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} FdoNotificationDaemonSourceParams
|
||||
* @property {string} title
|
||||
* @property {number} pid
|
||||
* @property {string} sender
|
||||
* @property {string} appId
|
||||
*/
|
||||
|
||||
export const FdoNotificationDaemonSource = GObject.registerClass(
|
||||
class FdoNotificationDaemonSource extends MessageTray.Source {
|
||||
_init(title, pid, sender, appId) {
|
||||
this.pid = pid;
|
||||
|
|
@ -466,8 +482,12 @@ const PRIORITY_URGENCY_MAP = {
|
|||
urgent: MessageTray.Urgency.CRITICAL,
|
||||
};
|
||||
|
||||
var GtkNotificationDaemonNotification = GObject.registerClass(
|
||||
export const GtkNotificationDaemonNotification = GObject.registerClass(
|
||||
class GtkNotificationDaemonNotification extends MessageTray.Notification {
|
||||
/**
|
||||
* @param {*} source
|
||||
* @param {*} notification
|
||||
*/
|
||||
_init(source, notification) {
|
||||
super._init(source);
|
||||
this._serialized = GLib.Variant.new('a{sv}', notification);
|
||||
|
|
@ -542,14 +562,19 @@ function objectPathFromAppId(appId) {
|
|||
return '/' + appId.replace(/\./g, '/').replace(/-/g, '_');
|
||||
}
|
||||
|
||||
function getPlatformData() {
|
||||
let startupId = GLib.Variant.new('s', '_TIME%s'.format(global.get_current_time()));
|
||||
export function getPlatformData() {
|
||||
let startupId = GLib.Variant.new('s', '_TIME%d'.format(global.get_current_time()));
|
||||
return { "desktop-startup-id": startupId };
|
||||
}
|
||||
|
||||
function InvalidAppError() {}
|
||||
|
||||
var GtkNotificationDaemonAppSource = GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} GtkNotificationDaemonAppSourceParams
|
||||
* @property {string} appId
|
||||
*/
|
||||
|
||||
export const GtkNotificationDaemonAppSource = GObject.registerClass(
|
||||
class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
||||
_init(appId) {
|
||||
let objectPath = objectPathFromAppId(appId);
|
||||
|
|
@ -651,7 +676,7 @@ class GtkNotificationDaemonAppSource extends MessageTray.Source {
|
|||
|
||||
const GtkNotificationsIface = loadInterfaceXML('org.gtk.Notifications');
|
||||
|
||||
var GtkNotificationDaemon = class GtkNotificationDaemon {
|
||||
export class GtkNotificationDaemon {
|
||||
constructor() {
|
||||
this._sources = {};
|
||||
|
||||
|
|
@ -756,7 +781,7 @@ var GtkNotificationDaemon = class GtkNotificationDaemon {
|
|||
}
|
||||
};
|
||||
|
||||
var NotificationDaemon = class NotificationDaemon {
|
||||
export class NotificationDaemon {
|
||||
constructor() {
|
||||
this._fdoNotificationDaemon = new FdoNotificationDaemon();
|
||||
this._gtkNotificationDaemon = new GtkNotificationDaemon();
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported OsdMonitorLabeler */
|
||||
|
||||
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 Main = imports.ui.main;
|
||||
|
||||
var OsdMonitorLabel = GObject.registerClass(
|
||||
import Main from './main.js';
|
||||
|
||||
export const OsdMonitorLabel = GObject.registerClass(
|
||||
class OsdMonitorLabel extends St.Widget {
|
||||
_init(monitor, label) {
|
||||
super._init({ x_expand: true, y_expand: true });
|
||||
|
|
@ -42,7 +47,7 @@ class OsdMonitorLabel extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var OsdMonitorLabeler = class {
|
||||
export class OsdMonitorLabeler {
|
||||
constructor() {
|
||||
this._monitorManager = Meta.MonitorManager.get();
|
||||
this._client = null;
|
||||
|
|
|
|||
|
|
@ -1,17 +1,21 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported OsdWindowManager */
|
||||
|
||||
const { Clutter, GLib, GObject, Meta, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import St from 'gi://St';
|
||||
|
||||
const BarLevel = imports.ui.barLevel;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
import * as BarLevel from './barLevel.js';
|
||||
import * as Layout from './layout.js';
|
||||
import Main from './main.js';
|
||||
|
||||
var HIDE_TIMEOUT = 1500;
|
||||
var FADE_TIME = 100;
|
||||
var LEVEL_ANIMATION_TIME = 100;
|
||||
export let HIDE_TIMEOUT = 1500;
|
||||
export let FADE_TIME = 100;
|
||||
export let LEVEL_ANIMATION_TIME = 100;
|
||||
|
||||
var OsdWindowConstraint = GObject.registerClass(
|
||||
export const OsdWindowConstraint = GObject.registerClass(
|
||||
class OsdWindowConstraint extends Clutter.Constraint {
|
||||
_init(props) {
|
||||
this._minSize = 0;
|
||||
|
|
@ -41,7 +45,7 @@ class OsdWindowConstraint extends Clutter.Constraint {
|
|||
}
|
||||
});
|
||||
|
||||
var OsdWindow = GObject.registerClass(
|
||||
export const OsdWindow = GObject.registerClass(
|
||||
class OsdWindow extends St.Widget {
|
||||
_init(monitorIndex) {
|
||||
super._init({
|
||||
|
|
@ -199,7 +203,7 @@ class OsdWindow extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var OsdWindowManager = class {
|
||||
export class OsdWindowManager {
|
||||
constructor() {
|
||||
this._osdWindows = [];
|
||||
Main.layoutManager.connect('monitors-changed',
|
||||
|
|
|
|||
|
|
@ -1,27 +1,33 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Overview */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
// Time for initial animation going into Overview mode;
|
||||
// this is defined here to make it available in imports.
|
||||
var ANIMATION_TIME = 250;
|
||||
export let ANIMATION_TIME = 250;
|
||||
|
||||
const DND = imports.ui.dnd;
|
||||
const LayoutManager = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const MessageTray = imports.ui.messageTray;
|
||||
const OverviewControls = imports.ui.overviewControls;
|
||||
const SwipeTracker = imports.ui.swipeTracker;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
|
||||
import * as DND from './dnd.js';
|
||||
import * as LayoutManager from './layout.js';
|
||||
import Main from './main.js';
|
||||
import * as MessageTray from './messageTray.js';
|
||||
import * as OverviewControls from './overviewControls.js';
|
||||
import * as SwipeTracker from './swipeTracker.js';
|
||||
import * as WindowManager from './windowManager.js';
|
||||
import * as WorkspaceThumbnail from './workspaceThumbnail.js';
|
||||
|
||||
var DND_WINDOW_SWITCH_TIMEOUT = 750;
|
||||
export let DND_WINDOW_SWITCH_TIMEOUT = 750;
|
||||
|
||||
var OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
|
||||
export let OVERVIEW_ACTIVATION_TIMEOUT = 0.5;
|
||||
|
||||
var ShellInfo = class {
|
||||
export class ShellInfo {
|
||||
constructor() {
|
||||
this._source = null;
|
||||
}
|
||||
|
|
@ -57,7 +63,7 @@ var ShellInfo = class {
|
|||
}
|
||||
};
|
||||
|
||||
var OverviewActor = GObject.registerClass(
|
||||
export const OverviewActor = GObject.registerClass(
|
||||
class OverviewActor extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -83,6 +89,7 @@ class OverviewActor extends St.BoxLayout {
|
|||
}
|
||||
|
||||
runStartupAnimation(callback) {
|
||||
log('animating...');
|
||||
this._controls.runStartupAnimation(callback);
|
||||
}
|
||||
|
||||
|
|
@ -99,7 +106,7 @@ class OverviewActor extends St.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var Overview = class extends Signals.EventEmitter {
|
||||
export class Overview extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -641,6 +648,7 @@ var Overview = class extends Signals.EventEmitter {
|
|||
}
|
||||
|
||||
runStartupAnimation(callback) {
|
||||
log('trackin')
|
||||
Main.panel.style = 'transition-duration: 0ms;';
|
||||
|
||||
this._shown = true;
|
||||
|
|
@ -654,6 +662,7 @@ var Overview = class extends Signals.EventEmitter {
|
|||
Meta.disable_unredirect_for_display(global.display);
|
||||
|
||||
this.emit('showing');
|
||||
log('SHOWING');
|
||||
|
||||
this._overview.runStartupAnimation(() => {
|
||||
if (!this._syncGrab()) {
|
||||
|
|
|
|||
|
|
@ -1,33 +1,41 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported ControlsManager */
|
||||
|
||||
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const AppDisplay = imports.ui.appDisplay;
|
||||
const Dash = imports.ui.dash;
|
||||
const Layout = imports.ui.layout;
|
||||
const Main = imports.ui.main;
|
||||
const Overview = imports.ui.overview;
|
||||
const SearchController = imports.ui.searchController;
|
||||
const Util = imports.misc.util;
|
||||
const WindowManager = imports.ui.windowManager;
|
||||
const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
|
||||
const WorkspacesView = imports.ui.workspacesView;
|
||||
import * as AppDisplay from './appDisplay.js';
|
||||
import * as Dash from './dash.js';
|
||||
import * as Layout from './layout.js';
|
||||
import Main from './main.js';
|
||||
import * as Overview from './overview.js';
|
||||
import * as SearchController from './searchController.js';
|
||||
import * as Util from '../misc/util.js';
|
||||
import * as WindowManager from './windowManager.js';
|
||||
import * as WorkspaceThumbnail from './workspaceThumbnail.js';
|
||||
import * as WorkspacesView from './workspacesView.js';
|
||||
|
||||
const SMALL_WORKSPACE_RATIO = 0.15;
|
||||
const DASH_MAX_HEIGHT_RATIO = 0.15;
|
||||
|
||||
const A11Y_SCHEMA = 'org.gnome.desktop.a11y.keyboard';
|
||||
|
||||
var SIDE_CONTROLS_ANIMATION_TIME = Overview.ANIMATION_TIME;
|
||||
// TODO
|
||||
// import { ANIMATION_TIME as SIDE_CONTROLS_ANIMATION_TIME } from './overview.js';
|
||||
// export { ANIMATION_TIME as SIDE_CONTROLS_ANIMATION_TIME } from './overview.js';
|
||||
export let SIDE_CONTROLS_ANIMATION_TIME = 250;
|
||||
|
||||
var ControlsState = {
|
||||
export const ControlsState = {
|
||||
HIDDEN: 0,
|
||||
WINDOW_PICKER: 1,
|
||||
APP_GRID: 2,
|
||||
};
|
||||
|
||||
var ControlsManagerLayout = GObject.registerClass(
|
||||
export const ControlsManagerLayout = GObject.registerClass(
|
||||
class ControlsManagerLayout extends Clutter.BoxLayout {
|
||||
_init(searchEntry, appDisplay, workspacesDisplay, workspacesThumbnails,
|
||||
searchController, dash, stateAdjustment) {
|
||||
|
|
@ -118,11 +126,13 @@ class ControlsManagerLayout extends Clutter.BoxLayout {
|
|||
this.hookup_style(container);
|
||||
}
|
||||
|
||||
/** @returns {[number, number]} */
|
||||
vfunc_get_preferred_width(_container, _forHeight) {
|
||||
// The MonitorConstraint will allocate us a fixed size anyway
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
/** @returns {[number, number]} */
|
||||
vfunc_get_preferred_height(_container, _forWidth) {
|
||||
// The MonitorConstraint will allocate us a fixed size anyway
|
||||
return [0, 0];
|
||||
|
|
@ -241,7 +251,7 @@ class ControlsManagerLayout extends Clutter.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var OverviewAdjustment = GObject.registerClass({
|
||||
export const OverviewAdjustment = GObject.registerClass({
|
||||
Properties: {
|
||||
'gesture-in-progress': GObject.ParamSpec.boolean(
|
||||
'gesture-in-progress', 'Gesture in progress', 'Gesture in progress',
|
||||
|
|
@ -249,6 +259,9 @@ var OverviewAdjustment = GObject.registerClass({
|
|||
false),
|
||||
},
|
||||
}, class OverviewAdjustment extends St.Adjustment {
|
||||
/** @type {boolean} */
|
||||
gestureInProgress;
|
||||
|
||||
_init(actor) {
|
||||
super._init({
|
||||
actor,
|
||||
|
|
@ -262,12 +275,14 @@ var OverviewAdjustment = GObject.registerClass({
|
|||
const currentState = this.value;
|
||||
|
||||
const transition = this.get_transition('value');
|
||||
let initialState = transition
|
||||
/** @type {number} */
|
||||
let initialState = (transition
|
||||
? transition.get_interval().peek_initial_value()
|
||||
: currentState;
|
||||
let finalState = transition
|
||||
: currentState);
|
||||
/** @type {number} */
|
||||
let finalState = (transition
|
||||
? transition.get_interval().peek_final_value()
|
||||
: currentState;
|
||||
: currentState);
|
||||
|
||||
if (initialState > finalState) {
|
||||
initialState = Math.ceil(initialState);
|
||||
|
|
@ -292,7 +307,7 @@ var OverviewAdjustment = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ControlsManager = GObject.registerClass(
|
||||
export const ControlsManager = GObject.registerClass(
|
||||
class ControlsManager extends St.Widget {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
@ -375,6 +390,7 @@ class ControlsManager extends St.Widget {
|
|||
this.add_child(this._thumbnailsBox);
|
||||
this.add_child(this._workspacesDisplay);
|
||||
|
||||
/** @type {ControlsManagerLayout["prototype"]} */
|
||||
this.layout_manager = new ControlsManagerLayout(
|
||||
this._searchEntryBin,
|
||||
this._appDisplay,
|
||||
|
|
@ -718,7 +734,7 @@ class ControlsManager extends St.Widget {
|
|||
}
|
||||
|
||||
getWorkspacesBoxForState(state) {
|
||||
return this.layoutManager.getWorkspacesBoxForState(state);
|
||||
return this.layout_manager.getWorkspacesBoxForState(state);
|
||||
}
|
||||
|
||||
gestureBegin(tracker) {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,24 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported PadOsd, PadOsdService */
|
||||
|
||||
const { Atk, Clutter, GDesktopEnums, Gio,
|
||||
GLib, GObject, Gtk, Meta, Pango, Rsvg, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GDesktopEnums from 'gi://GDesktopEnums';
|
||||
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 Pango from 'gi://Pango';
|
||||
import Rsvg from 'gi://Rsvg';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const Layout = imports.ui.layout;
|
||||
import Main from './main.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
import * as Layout from './layout.js';
|
||||
|
||||
const { loadInterfaceXML } = imports.misc.fileUtils;
|
||||
import { loadInterfaceXML } from '../misc/fileUtilsModule.js';
|
||||
|
||||
const ACTIVE_COLOR = "#729fcf";
|
||||
|
||||
|
|
@ -22,9 +31,13 @@ const CCW = 1;
|
|||
const UP = 0;
|
||||
const DOWN = 1;
|
||||
|
||||
var PadChooser = GObject.registerClass({
|
||||
export const PadChooser = GObject.registerClass({
|
||||
Signals: { 'pad-selected': { param_types: [Clutter.InputDevice.$gtype] } },
|
||||
}, class PadChooser extends St.Button {
|
||||
/**
|
||||
* @param {*} device
|
||||
* @param {*} groupDevices
|
||||
*/
|
||||
_init(device, groupDevices) {
|
||||
super._init({
|
||||
style_class: 'pad-chooser-button',
|
||||
|
|
@ -88,7 +101,7 @@ var PadChooser = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var KeybindingEntry = GObject.registerClass({
|
||||
export const KeybindingEntry = GObject.registerClass({
|
||||
Signals: { 'keybinding-edited': { param_types: [GObject.TYPE_STRING] } },
|
||||
}, class KeybindingEntry extends St.Entry {
|
||||
_init() {
|
||||
|
|
@ -109,7 +122,7 @@ var KeybindingEntry = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ActionComboBox = GObject.registerClass({
|
||||
export const ActionComboBox = GObject.registerClass({
|
||||
Signals: { 'action-selected': { param_types: [GObject.TYPE_INT] } },
|
||||
}, class ActionComboBox extends St.Button {
|
||||
_init() {
|
||||
|
|
@ -191,7 +204,7 @@ var ActionComboBox = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ActionEditor = GObject.registerClass({
|
||||
export const ActionEditor = GObject.registerClass({
|
||||
Signals: { 'done': {} },
|
||||
}, class ActionEditor extends St.Widget {
|
||||
_init() {
|
||||
|
|
@ -275,7 +288,7 @@ var ActionEditor = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var PadDiagram = GObject.registerClass({
|
||||
export const PadDiagram = GObject.registerClass({
|
||||
Properties: {
|
||||
'left-handed': GObject.ParamSpec.boolean('left-handed',
|
||||
'left-handed', 'Left handed',
|
||||
|
|
@ -368,7 +381,7 @@ var PadDiagram = GObject.registerClass({
|
|||
let css = this._css;
|
||||
|
||||
for (let i = 0; i < this._activeButtons.length; i++) {
|
||||
let ch = String.fromCharCode('A'.charCodeAt() + this._activeButtons[i]);
|
||||
let ch = String.fromCharCode('A'.charCodeAt(0) + this._activeButtons[i]);
|
||||
css += '.%s.Leader { stroke: %s !important; }'.format(ch, ACTIVE_COLOR);
|
||||
css += '.%s.Button { stroke: %s !important; fill: %s !important; }'.format(ch, ACTIVE_COLOR, ACTIVE_COLOR);
|
||||
}
|
||||
|
|
@ -387,7 +400,8 @@ var PadDiagram = GObject.registerClass({
|
|||
svgData += this._wrappingSvgFooter();
|
||||
|
||||
let istream = new Gio.MemoryInputStream();
|
||||
istream.add_bytes(new GLib.Bytes(svgData));
|
||||
// FIXME
|
||||
istream.add_bytes(imports.byteArray.fromString(svgData));
|
||||
|
||||
return Rsvg.Handle.new_from_stream_sync(istream,
|
||||
Gio.File.new_for_path(this._imagePath), 0, null);
|
||||
|
|
@ -495,7 +509,7 @@ var PadDiagram = GObject.registerClass({
|
|||
}
|
||||
|
||||
_getButtonLabels(button) {
|
||||
let ch = String.fromCharCode('A'.charCodeAt() + button);
|
||||
let ch = String.fromCharCode('A'.charCodeAt(0) + button);
|
||||
let labelName = 'Label%s'.format(ch);
|
||||
let leaderName = 'Leader%s'.format(ch);
|
||||
return [labelName, leaderName];
|
||||
|
|
@ -618,12 +632,19 @@ var PadDiagram = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var PadOsd = GObject.registerClass({
|
||||
export const PadOsd = GObject.registerClass({
|
||||
Signals: {
|
||||
'pad-selected': { param_types: [Clutter.InputDevice.$gtype] },
|
||||
'closed': {},
|
||||
},
|
||||
}, class PadOsd extends St.BoxLayout {
|
||||
/**
|
||||
* @param {*} padDevice
|
||||
* @param {*} settings
|
||||
* @param {*} imagePath
|
||||
* @param {*} editionMode
|
||||
* @param {*} monitorIndex
|
||||
*/
|
||||
_init(padDevice, settings, imagePath, editionMode, monitorIndex) {
|
||||
super._init({
|
||||
style_class: 'pad-osd-window',
|
||||
|
|
@ -894,19 +915,19 @@ var PadOsd = GObject.registerClass({
|
|||
}
|
||||
|
||||
_startButtonActionEdition(button) {
|
||||
let ch = String.fromCharCode('A'.charCodeAt() + button);
|
||||
let ch = String.fromCharCode('A'.charCodeAt(0) + button);
|
||||
let key = 'button%s'.format(ch);
|
||||
this._startActionEdition(key, Meta.PadActionType.BUTTON, button);
|
||||
}
|
||||
|
||||
_startRingActionEdition(ring, dir, mode) {
|
||||
let ch = String.fromCharCode('A'.charCodeAt() + ring);
|
||||
let ch = String.fromCharCode('A'.charCodeAt(0) + ring);
|
||||
let key = 'ring%s-%s-mode-%d'.format(ch, dir == CCW ? 'ccw' : 'cw', mode);
|
||||
this._startActionEdition(key, Meta.PadActionType.RING, ring, dir, mode);
|
||||
}
|
||||
|
||||
_startStripActionEdition(strip, dir, mode) {
|
||||
let ch = String.fromCharCode('A'.charCodeAt() + strip);
|
||||
let ch = String.fromCharCode('A'.charCodeAt(0) + strip);
|
||||
let key = 'strip%s-%s-mode-%d'.format(ch, dir == UP ? 'up' : 'down', mode);
|
||||
this._startActionEdition(key, Meta.PadActionType.STRIP, strip, dir, mode);
|
||||
}
|
||||
|
|
@ -944,7 +965,7 @@ var PadOsd = GObject.registerClass({
|
|||
|
||||
const PadOsdIface = loadInterfaceXML('org.gnome.Shell.Wacom.PadOsd');
|
||||
|
||||
var PadOsdService = class extends Signals.EventEmitter {
|
||||
export class PadOsdService extends Signals.EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported PageIndicators */
|
||||
|
||||
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 INDICATOR_INACTIVE_OPACITY = 128;
|
||||
const INDICATOR_INACTIVE_OPACITY_HOVER = 255;
|
||||
const INDICATOR_INACTIVE_SCALE = 2 / 3;
|
||||
const INDICATOR_INACTIVE_SCALE_PRESSED = 0.5;
|
||||
|
||||
var PageIndicators = GObject.registerClass({
|
||||
export const PageIndicators = GObject.registerClass({
|
||||
Signals: { 'page-activated': { param_types: [GObject.TYPE_INT] } },
|
||||
}, class PageIndicators extends St.BoxLayout {
|
||||
_init(orientation = Clutter.Orientation.VERTICAL) {
|
||||
|
|
@ -29,6 +32,9 @@ var PageIndicators = GObject.registerClass({
|
|||
this._orientation = orientation;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(forWidth) {
|
||||
// We want to request the natural height of all our children as our
|
||||
// natural height, so we chain up to St.BoxLayout, but we only request 0
|
||||
|
|
|
|||
138
js/ui/panel.js
138
js/ui/panel.js
|
|
@ -1,23 +1,29 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Panel */
|
||||
|
||||
const { Atk, Clutter, GLib, GObject, Meta, Shell, St } = imports.gi;
|
||||
const Cairo = imports.cairo;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GLib from 'gi://GLib';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import Cairo from 'cairo';
|
||||
|
||||
const Animation = imports.ui.animation;
|
||||
const { AppMenu } = imports.ui.appMenu;
|
||||
import * as Animation from './animation.js';
|
||||
import { AppMenu } from './appMenu.js';
|
||||
const Config = imports.misc.config;
|
||||
const CtrlAltTab = imports.ui.ctrlAltTab;
|
||||
const DND = imports.ui.dnd;
|
||||
const Overview = imports.ui.overview;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
const PanelMenu = imports.ui.panelMenu;
|
||||
const Main = imports.ui.main;
|
||||
import * as CtrlAltTab from './ctrlAltTab.js';
|
||||
import * as DND from './dnd.js';
|
||||
import * as Overview from './overview.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
import * as PanelMenu from './panelMenu.js';
|
||||
import Main from './main.js';
|
||||
|
||||
var PANEL_ICON_SIZE = 16;
|
||||
var APP_MENU_ICON_MARGIN = 0;
|
||||
export let PANEL_ICON_SIZE = 16;
|
||||
export let APP_MENU_ICON_MARGIN = 0;
|
||||
|
||||
var BUTTON_DND_ACTIVATION_TIMEOUT = 250;
|
||||
export let BUTTON_DND_ACTIVATION_TIMEOUT = 250;
|
||||
|
||||
/**
|
||||
* AppMenuButton:
|
||||
|
|
@ -27,7 +33,7 @@ var BUTTON_DND_ACTIVATION_TIMEOUT = 250;
|
|||
* this menu also handles startup notification for it. So when we
|
||||
* have an active startup notification, we switch modes to display that.
|
||||
*/
|
||||
var AppMenuButton = GObject.registerClass({
|
||||
export const AppMenuButton = GObject.registerClass({
|
||||
Signals: { 'changed': {} },
|
||||
}, class AppMenuButton extends PanelMenu.Button {
|
||||
_init(panel) {
|
||||
|
|
@ -258,7 +264,7 @@ var AppMenuButton = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var ActivitiesButton = GObject.registerClass(
|
||||
export const ActivitiesButton = GObject.registerClass(
|
||||
class ActivitiesButton extends PanelMenu.Button {
|
||||
_init() {
|
||||
super._init(0.0, null, true);
|
||||
|
|
@ -294,6 +300,8 @@ class ActivitiesButton extends PanelMenu.Button {
|
|||
GLib.source_remove(this._xdndTimeOut);
|
||||
this._xdndTimeOut = GLib.timeout_add(GLib.PRIORITY_DEFAULT, BUTTON_DND_ACTIVATION_TIMEOUT, () => {
|
||||
this._xdndToggleOverview();
|
||||
|
||||
return false;
|
||||
});
|
||||
GLib.Source.set_name_by_id(this._xdndTimeOut, '[gnome-shell] this._xdndToggleOverview');
|
||||
|
||||
|
|
@ -344,7 +352,7 @@ class ActivitiesButton extends PanelMenu.Button {
|
|||
}
|
||||
});
|
||||
|
||||
var PanelCorner = GObject.registerClass(
|
||||
export const PanelCorner = GObject.registerClass(
|
||||
class PanelCorner extends St.DrawingArea {
|
||||
_init(side) {
|
||||
this._side = side;
|
||||
|
|
@ -535,6 +543,9 @@ class AggregateLayout extends Clutter.BoxLayout {
|
|||
this.layout_changed();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(container, forHeight) {
|
||||
let themeNode = container.get_theme_node();
|
||||
let minWidth = themeNode.get_min_width();
|
||||
|
|
@ -550,38 +561,44 @@ class AggregateLayout extends Clutter.BoxLayout {
|
|||
}
|
||||
});
|
||||
|
||||
var AggregateMenu = GObject.registerClass(
|
||||
|
||||
|
||||
export const AggregateMenu = GObject.registerClass(
|
||||
class AggregateMenu extends PanelMenu.Button {
|
||||
_init() {
|
||||
super._init(0.0, C_("System menu in the top bar", "System"), false);
|
||||
this.menu.actor.add_style_class_name('aggregate-menu');
|
||||
|
||||
let menuLayout = new AggregateLayout();
|
||||
this.menu.box.set_layout_manager(menuLayout);
|
||||
this._menuLayout = new AggregateLayout();
|
||||
this.menu.box.set_layout_manager(this._menuLayout);
|
||||
|
||||
this._indicators = new St.BoxLayout({ style_class: 'panel-status-indicators-box' });
|
||||
this.add_child(this._indicators);
|
||||
}
|
||||
|
||||
async _asyncInit() {
|
||||
if (Config.HAVE_NETWORKMANAGER)
|
||||
this._network = new imports.ui.status.network.NMApplet();
|
||||
this._network = new ((await import('./status/network.js')).NMApplet)();
|
||||
else
|
||||
this._network = null;
|
||||
|
||||
if (Config.HAVE_BLUETOOTH)
|
||||
this._bluetooth = new imports.ui.status.bluetooth.Indicator();
|
||||
this._bluetooth = new ((await import('./status/bluetooth.js')).Indicator)();
|
||||
else
|
||||
this._bluetooth = null;
|
||||
|
||||
this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet();
|
||||
this._power = new imports.ui.status.power.Indicator();
|
||||
this._powerProfiles = new imports.ui.status.powerProfiles.Indicator();
|
||||
this._rfkill = new imports.ui.status.rfkill.Indicator();
|
||||
this._volume = new imports.ui.status.volume.Indicator();
|
||||
this._brightness = new imports.ui.status.brightness.Indicator();
|
||||
this._system = new imports.ui.status.system.Indicator();
|
||||
this._location = new imports.ui.status.location.Indicator();
|
||||
this._nightLight = new imports.ui.status.nightLight.Indicator();
|
||||
this._thunderbolt = new imports.ui.status.thunderbolt.Indicator();
|
||||
const menuLayout = this._menuLayout;
|
||||
|
||||
this._remoteAccess = new ((await import('./status/remoteAccess.js')).RemoteAccessApplet)();
|
||||
this._powerProfiles = new ((await import('./status/powerProfiles.js')).Indicator)();
|
||||
this._power = new ((await import('./status/power.js')).Indicator)();
|
||||
this._rfkill = new ((await import('./status/rfkill.js')).Indicator)();
|
||||
this._volume = new ((await import('./status/volume.js')).Indicator)();
|
||||
this._brightness = new ((await import('./status/brightness.js')).Indicator)();
|
||||
this._system = new ((await import('./status/system.js')).Indicator)();
|
||||
this._location = new ((await import('./status/location.js')).Indicator)();
|
||||
this._nightLight = new ((await import('./status/nightLight.js')).Indicator)();
|
||||
this._thunderbolt = new ((await import('./status/thunderbolt.js')).Indicator)();
|
||||
this._unsafeMode = new UnsafeModeIndicator();
|
||||
|
||||
this._indicators.add_child(this._remoteAccess);
|
||||
|
|
@ -624,17 +641,22 @@ class AggregateMenu extends PanelMenu.Button {
|
|||
}
|
||||
});
|
||||
|
||||
import {DateMenuButton} from './dateMenu.js';
|
||||
import {ATIndicator} from './status/accessibility.js';
|
||||
import {InputSourceIndicator} from './status/keyboard.js';
|
||||
import {DwellClickIndicator} from './status/dwellClick.js';
|
||||
|
||||
const PANEL_ITEM_IMPLEMENTATIONS = {
|
||||
'activities': ActivitiesButton,
|
||||
'aggregateMenu': AggregateMenu,
|
||||
'appMenu': AppMenuButton,
|
||||
'dateMenu': imports.ui.dateMenu.DateMenuButton,
|
||||
'a11y': imports.ui.status.accessibility.ATIndicator,
|
||||
'keyboard': imports.ui.status.keyboard.InputSourceIndicator,
|
||||
'dwellClick': imports.ui.status.dwellClick.DwellClickIndicator,
|
||||
'dateMenu': DateMenuButton,
|
||||
'a11y': ATIndicator,
|
||||
'keyboard': InputSourceIndicator,
|
||||
'dwellClick': DwellClickIndicator,
|
||||
};
|
||||
|
||||
var Panel = GObject.registerClass(
|
||||
export const Panel = GObject.registerClass(
|
||||
class Panel extends St.Widget {
|
||||
_init() {
|
||||
super._init({ name: 'panel',
|
||||
|
|
@ -673,13 +695,26 @@ class Panel extends St.Widget {
|
|||
Main.layoutManager.panelBox.add(this);
|
||||
Main.ctrlAltTabManager.addGroup(this, _("Top Bar"), 'focus-top-bar-symbolic',
|
||||
{ sortGroup: CtrlAltTab.SortGroup.TOP });
|
||||
|
||||
Main.sessionMode.connect('updated', this._updatePanel.bind(this));
|
||||
log('updating panel...');
|
||||
Main.sessionMode.connect('updated', () => {
|
||||
this._updatePanel().then(() => {
|
||||
log('Panel Updated!');
|
||||
}).catch(err => {
|
||||
logError(err)
|
||||
});
|
||||
});
|
||||
|
||||
global.display.connect('workareas-changed', () => this.queue_relayout());
|
||||
this._updatePanel();
|
||||
this._updatePanel().then(() => {
|
||||
log('Panel Updated! (1)');
|
||||
}).catch(err => {
|
||||
logError(err)
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(_forHeight) {
|
||||
let primaryMonitor = Main.layoutManager.primaryMonitor;
|
||||
|
||||
|
|
@ -863,12 +898,14 @@ class Panel extends St.Widget {
|
|||
return this._leftBox.opacity;
|
||||
}
|
||||
|
||||
_updatePanel() {
|
||||
async _updatePanel() {
|
||||
try {
|
||||
log('Updating panel...');
|
||||
let panel = Main.sessionMode.panel;
|
||||
this._hideIndicators();
|
||||
this._updateBox(panel.left, this._leftBox);
|
||||
this._updateBox(panel.center, this._centerBox);
|
||||
this._updateBox(panel.right, this._rightBox);
|
||||
await this._updateBox(panel.left, this._leftBox);
|
||||
await this._updateBox(panel.center, this._centerBox);
|
||||
await this._updateBox(panel.right, this._rightBox);
|
||||
|
||||
if (panel.left.includes('dateMenu'))
|
||||
Main.messageTray.bannerAlignment = Clutter.ActorAlign.START;
|
||||
|
|
@ -892,6 +929,10 @@ class Panel extends St.Widget {
|
|||
this._leftCorner.setStyleParent(this._leftBox);
|
||||
this._rightCorner.setStyleParent(this._rightBox);
|
||||
}
|
||||
}catch(error) {
|
||||
log('FAILED TO UPDATE PANEL...');
|
||||
logError(error);
|
||||
}
|
||||
}
|
||||
|
||||
_hideIndicators() {
|
||||
|
|
@ -903,7 +944,7 @@ class Panel extends St.Widget {
|
|||
}
|
||||
}
|
||||
|
||||
_ensureIndicator(role) {
|
||||
async _ensureIndicator(role) {
|
||||
let indicator = this.statusArea[role];
|
||||
if (!indicator) {
|
||||
let constructor = PANEL_ITEM_IMPLEMENTATIONS[role];
|
||||
|
|
@ -912,17 +953,22 @@ class Panel extends St.Widget {
|
|||
return null;
|
||||
}
|
||||
indicator = new constructor(this);
|
||||
|
||||
// TODO
|
||||
if (indicator._asyncInit)
|
||||
await indicator._asyncInit();
|
||||
|
||||
this.statusArea[role] = indicator;
|
||||
}
|
||||
return indicator;
|
||||
}
|
||||
|
||||
_updateBox(elements, box) {
|
||||
async _updateBox(elements, box) {
|
||||
let nChildren = box.get_n_children();
|
||||
|
||||
for (let i = 0; i < elements.length; i++) {
|
||||
let role = elements[i];
|
||||
let indicator = this._ensureIndicator(role);
|
||||
let indicator = await this._ensureIndicator(role);
|
||||
if (indicator == null)
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,15 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Button, SystemIndicator */
|
||||
|
||||
const { Atk, Clutter, GObject, St } = imports.gi;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import St from 'gi://St';
|
||||
|
||||
const Main = imports.ui.main;
|
||||
const PopupMenu = imports.ui.popupMenu;
|
||||
import Main from './main.js';
|
||||
import * as PopupMenu from './popupMenu.js';
|
||||
|
||||
var ButtonBox = GObject.registerClass(
|
||||
export const ButtonBox = GObject.registerClass(
|
||||
class ButtonBox extends St.Widget {
|
||||
_init(params) {
|
||||
const {
|
||||
|
|
@ -34,6 +37,9 @@ class ButtonBox extends St.Widget {
|
|||
this._natHPadding = themeNode.get_length('-natural-hpadding');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_width(_forHeight) {
|
||||
let child = this.get_first_child();
|
||||
let minimumSize, naturalSize;
|
||||
|
|
@ -49,6 +55,9 @@ class ButtonBox extends St.Widget {
|
|||
return [minimumSize, naturalSize];
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {[number, number]}
|
||||
*/
|
||||
vfunc_get_preferred_height(_forWidth) {
|
||||
let child = this.get_first_child();
|
||||
|
||||
|
|
@ -91,7 +100,7 @@ class ButtonBox extends St.Widget {
|
|||
}
|
||||
});
|
||||
|
||||
var Button = GObject.registerClass({
|
||||
export const Button = GObject.registerClass({
|
||||
Signals: { 'menu-set': {} },
|
||||
}, class PanelMenuButton extends ButtonBox {
|
||||
_init(menuAlignment, nameText, dontCreateMenu) {
|
||||
|
|
@ -106,7 +115,7 @@ var Button = GObject.registerClass({
|
|||
if (dontCreateMenu)
|
||||
this.menu = new PopupMenu.PopupDummyMenu(this);
|
||||
else
|
||||
this.setMenu(new PopupMenu.PopupMenu(this, menuAlignment, St.Side.TOP, 0));
|
||||
this.setMenu(new PopupMenu.PopupMenu(this, menuAlignment, St.Side.TOP));
|
||||
}
|
||||
|
||||
setSensitive(sensitive) {
|
||||
|
|
@ -180,7 +189,7 @@ var Button = GObject.registerClass({
|
|||
// measures are in logical pixels, so make sure to consider the scale
|
||||
// factor when computing max-height
|
||||
let maxHeight = Math.round((workArea.height - verticalMargins) / scaleFactor);
|
||||
this.menu.actor.style = 'max-height: %spx;'.format(maxHeight);
|
||||
this.menu.actor.style = 'max-height: %spx;'.format(maxHeight.toFixed(0));
|
||||
}
|
||||
|
||||
_onDestroy() {
|
||||
|
|
@ -197,7 +206,7 @@ var Button = GObject.registerClass({
|
|||
* of an icon and a menu section, which will be composed into the
|
||||
* aggregate menu.
|
||||
*/
|
||||
var SystemIndicator = GObject.registerClass(
|
||||
export const SystemIndicator = GObject.registerClass(
|
||||
class SystemIndicator extends St.BoxLayout {
|
||||
_init() {
|
||||
super._init({
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
/* exported PointerA11yTimeout */
|
||||
const { Clutter, GObject, Meta, St } = imports.gi;
|
||||
const Main = imports.ui.main;
|
||||
const Cairo = imports.cairo;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import GObject from 'gi://GObject';
|
||||
import Meta from 'gi://Meta';
|
||||
import St from 'gi://St';
|
||||
|
||||
import Main from './main.js';
|
||||
|
||||
import Cairo from 'gi://cairo';
|
||||
|
||||
const SUCCESS_ZOOM_OUT_DURATION = 150;
|
||||
|
||||
var PieTimer = GObject.registerClass({
|
||||
export const PieTimer = GObject.registerClass({
|
||||
Properties: {
|
||||
'angle': GObject.ParamSpec.double(
|
||||
'angle', 'angle', 'angle',
|
||||
|
|
@ -106,7 +111,7 @@ var PieTimer = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var PointerA11yTimeout = class PointerA11yTimeout {
|
||||
export class PointerA11yTimeout {
|
||||
constructor() {
|
||||
let seat = Clutter.get_default_backend().get_default_seat();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,24 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported getPointerWatcher */
|
||||
|
||||
const { GLib } = imports.gi;
|
||||
import GLib from 'gi://GLib';
|
||||
|
||||
// We stop polling if the user is idle for more than this amount of time
|
||||
var IDLE_TIME = 1000;
|
||||
export const IDLE_TIME = 1000;
|
||||
|
||||
// This file implements a reasonably efficient system for tracking the position
|
||||
// of the mouse pointer. We simply query the pointer from the X server in a loop,
|
||||
// but we turn off the polling when the user is idle.
|
||||
|
||||
let _pointerWatcher = null;
|
||||
function getPointerWatcher() {
|
||||
export function getPointerWatcher() {
|
||||
if (_pointerWatcher == null)
|
||||
_pointerWatcher = new PointerWatcher();
|
||||
|
||||
return _pointerWatcher;
|
||||
}
|
||||
|
||||
var PointerWatch = class {
|
||||
export class PointerWatch {
|
||||
constructor(watcher, interval, callback) {
|
||||
this.watcher = watcher;
|
||||
this.interval = interval;
|
||||
|
|
@ -33,7 +33,7 @@ var PointerWatch = class {
|
|||
}
|
||||
};
|
||||
|
||||
var PointerWatcher = class {
|
||||
export class PointerWatcher {
|
||||
constructor() {
|
||||
this._idleMonitor = global.backend.get_core_idle_monitor();
|
||||
this._idleMonitor.add_idle_watch(IDLE_TIME, this._onIdleMonitorBecameIdle.bind(this));
|
||||
|
|
|
|||
|
|
@ -3,14 +3,21 @@
|
|||
PopupImageMenuItem, PopupMenu, PopupDummyMenu, PopupSubMenu,
|
||||
PopupMenuSection, PopupSubMenuMenuItem, PopupMenuManager */
|
||||
|
||||
const { Atk, Clutter, Gio, GObject, Graphene, Shell, St } = imports.gi;
|
||||
const Signals = imports.misc.signals;
|
||||
import Atk from 'gi://Atk';
|
||||
import Clutter from 'gi://Clutter';
|
||||
import Gio from 'gi://Gio';
|
||||
import GObject from 'gi://GObject';
|
||||
import Graphene from 'gi://Graphene';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
import * as Signals from '../misc/signals.js';
|
||||
|
||||
const BoxPointer = imports.ui.boxpointer;
|
||||
const GrabHelper = imports.ui.grabHelper;
|
||||
const Main = imports.ui.main;
|
||||
import * as BoxPointer from './boxpointer.js';
|
||||
import * as GrabHelper from './grabHelper.js';
|
||||
import Main from './main.js';
|
||||
|
||||
var Ornament = {
|
||||
/** @enum {number} */
|
||||
export const Ornament = {
|
||||
NONE: 0,
|
||||
DOT: 1,
|
||||
CHECK: 2,
|
||||
|
|
@ -30,7 +37,7 @@ function isPopupMenuItemVisible(child) {
|
|||
* @param {St.Side} side - Side to which the arrow points.
|
||||
* @returns {St.Icon} a new arrow icon
|
||||
*/
|
||||
function arrowIcon(side) {
|
||||
export function arrowIcon(side) {
|
||||
let iconName;
|
||||
switch (side) {
|
||||
case St.Side.TOP:
|
||||
|
|
@ -56,7 +63,9 @@ function arrowIcon(side) {
|
|||
return arrow;
|
||||
}
|
||||
|
||||
var PopupBaseMenuItem = GObject.registerClass({
|
||||
/** @typedef {{active?: boolean} & Partial<Pick<St.BoxLayout.ConstructorProperties, 'style_class' | 'can_focus' | 'hover' | 'activate' | 'reactive'>>} PopupBaseMenuItemParams */
|
||||
|
||||
export const PopupBaseMenuItem = GObject.registerClass({
|
||||
Properties: {
|
||||
'active': GObject.ParamSpec.boolean('active', 'active', 'active',
|
||||
GObject.ParamFlags.READWRITE,
|
||||
|
|
@ -69,7 +78,7 @@ var PopupBaseMenuItem = GObject.registerClass({
|
|||
'activate': { param_types: [Clutter.Event.$gtype] },
|
||||
},
|
||||
}, class PopupBaseMenuItem extends St.BoxLayout {
|
||||
_init(params = {}) {
|
||||
_init(params = {}, ..._) {
|
||||
const {
|
||||
reactive = true,
|
||||
activate = true,
|
||||
|
|
@ -85,6 +94,11 @@ var PopupBaseMenuItem = GObject.registerClass({
|
|||
accessible_role: Atk.Role.MENU_ITEM });
|
||||
this._delegate = this;
|
||||
|
||||
/** @type {any} */
|
||||
this.prop
|
||||
/** @type {any} */
|
||||
this.radioGroup
|
||||
|
||||
this._ornament = Ornament.NONE;
|
||||
this._ornamentLabel = new St.Label({ style_class: 'popup-menu-ornament' });
|
||||
this.add(this._ornamentLabel);
|
||||
|
|
@ -267,9 +281,18 @@ var PopupBaseMenuItem = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var PopupMenuItem = GObject.registerClass(
|
||||
/**
|
||||
* @typedef {object} PopupMenuItemParams
|
||||
* @property {string} [text]
|
||||
* @property {boolean} [active]
|
||||
*/
|
||||
|
||||
export const PopupMenuItem = GObject.registerClass(
|
||||
class PopupMenuItem extends PopupBaseMenuItem {
|
||||
_init(text, params) {
|
||||
/**
|
||||
* @param {PopupMenuItemParams & PopupBaseMenuItemParams} [params]
|
||||
*/
|
||||
_init(text, params) {
|
||||
super._init(params);
|
||||
|
||||
this.label = new St.Label({ text });
|
||||
|
|
@ -279,8 +302,11 @@ class PopupMenuItem extends PopupBaseMenuItem {
|
|||
});
|
||||
|
||||
|
||||
var PopupSeparatorMenuItem = GObject.registerClass(
|
||||
export const PopupSeparatorMenuItem = GObject.registerClass(
|
||||
class PopupSeparatorMenuItem extends PopupBaseMenuItem {
|
||||
/**
|
||||
* @param {string | any} text
|
||||
*/
|
||||
_init(text) {
|
||||
super._init({
|
||||
style_class: 'popup-separator-menu-item',
|
||||
|
|
@ -310,7 +336,7 @@ class PopupSeparatorMenuItem extends PopupBaseMenuItem {
|
|||
}
|
||||
});
|
||||
|
||||
var Switch = GObject.registerClass({
|
||||
export const Switch = GObject.registerClass({
|
||||
Properties: {
|
||||
'state': GObject.ParamSpec.boolean(
|
||||
'state', 'state', 'state',
|
||||
|
|
@ -350,10 +376,10 @@ var Switch = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var PopupSwitchMenuItem = GObject.registerClass({
|
||||
export const PopupSwitchMenuItem = GObject.registerClass({
|
||||
Signals: { 'toggled': { param_types: [GObject.TYPE_BOOLEAN] } },
|
||||
}, class PopupSwitchMenuItem extends PopupBaseMenuItem {
|
||||
_init(text, active, params) {
|
||||
_init(text, active, params) {
|
||||
super._init(params);
|
||||
|
||||
this.label = new St.Label({ text });
|
||||
|
|
@ -434,8 +460,13 @@ var PopupSwitchMenuItem = GObject.registerClass({
|
|||
}
|
||||
});
|
||||
|
||||
var PopupImageMenuItem = GObject.registerClass(
|
||||
export const PopupImageMenuItem = GObject.registerClass(
|
||||
class PopupImageMenuItem extends PopupBaseMenuItem {
|
||||
/**
|
||||
* @param {string | any} text
|
||||
* @param {string | Gio.Icon} [icon]
|
||||
* @param {PopupBaseMenuItemParams} [params]
|
||||
*/
|
||||
_init(text, icon, params) {
|
||||
super._init(params);
|
||||
|
||||
|
|
@ -446,9 +477,14 @@ class PopupImageMenuItem extends PopupBaseMenuItem {
|
|||
this.add_child(this.label);
|
||||
this.label_actor = this.label;
|
||||
|
||||
this.setIcon(icon);
|
||||
if (icon) {
|
||||
this.setIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string | Gio.Icon} icon
|
||||
*/
|
||||
setIcon(icon) {
|
||||
// The 'icon' parameter can be either a Gio.Icon or a string.
|
||||
if (icon instanceof GObject.Object && GObject.type_is_a(icon, Gio.Icon))
|
||||
|
|
@ -458,7 +494,7 @@ class PopupImageMenuItem extends PopupBaseMenuItem {
|
|||
}
|
||||
});
|
||||
|
||||
var PopupMenuBase = class extends Signals.EventEmitter {
|
||||
export class PopupMenuBase extends Signals.EventEmitter {
|
||||
constructor(sourceActor, styleClass) {
|
||||
super();
|
||||
|
||||
|
|
@ -467,6 +503,10 @@ var PopupMenuBase = class extends Signals.EventEmitter {
|
|||
|
||||
this.sourceActor = sourceActor;
|
||||
this.focusActor = sourceActor;
|
||||
|
||||
/** @type {St.Widget} */
|
||||
this.actor;
|
||||
|
||||
this._parent = null;
|
||||
|
||||
this.box = new St.BoxLayout({
|
||||
|
|
@ -695,6 +735,10 @@ var PopupMenuBase = class extends Signals.EventEmitter {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {PopupMenuBase | PopupBaseMenuItem["prototype"]} menuItem
|
||||
* @param {number} [position]
|
||||
*/
|
||||
addMenuItem(menuItem, position) {
|
||||
let beforeItem = null;
|
||||
if (position == undefined) {
|
||||
|
|
@ -774,9 +818,12 @@ var PopupMenuBase = class extends Signals.EventEmitter {
|
|||
}
|
||||
|
||||
_getMenuItems() {
|
||||
return this.box.get_children().map(a => a._delegate).filter(item => {
|
||||
return item instanceof PopupBaseMenuItem || item instanceof PopupMenuSection;
|
||||
});
|
||||
return this.box.get_children().map(a => a._delegate).filter(
|
||||
/**
|
||||
* @returns {item is PopupMenuBase | PopupMenuSection}
|
||||
*/
|
||||
item => item instanceof PopupBaseMenuItem || item instanceof PopupMenuSection
|
||||
);
|
||||
}
|
||||
|
||||
get firstMenuItem() {
|
||||
|
|
@ -791,6 +838,20 @@ var PopupMenuBase = class extends Signals.EventEmitter {
|
|||
return this._getMenuItems().length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BoxPointer.PopupAnimation} _animation
|
||||
*/
|
||||
open(_animation) {
|
||||
throw new GObject.NotImplementedError(`open in ${this.constructor.name}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {BoxPointer.PopupAnimation} [_animation]
|
||||
*/
|
||||
close(_animation) {
|
||||
throw new GObject.NotImplementedError(`close in ${this.constructor.name}`);
|
||||
}
|
||||
|
||||
removeAll() {
|
||||
let children = this._getMenuItems();
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
|
|
@ -818,7 +879,7 @@ var PopupMenuBase = class extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var PopupMenu = class extends PopupMenuBase {
|
||||
export class PopupMenu extends PopupMenuBase {
|
||||
constructor(sourceActor, arrowAlignment, arrowSide) {
|
||||
super(sourceActor, 'popup-menu-content');
|
||||
|
||||
|
|
@ -969,7 +1030,7 @@ var PopupMenu = class extends PopupMenuBase {
|
|||
}
|
||||
};
|
||||
|
||||
var PopupDummyMenu = class extends Signals.EventEmitter {
|
||||
export class PopupDummyMenu extends Signals.EventEmitter {
|
||||
constructor(sourceActor) {
|
||||
super();
|
||||
|
||||
|
|
@ -1001,7 +1062,7 @@ var PopupDummyMenu = class extends Signals.EventEmitter {
|
|||
}
|
||||
};
|
||||
|
||||
var PopupSubMenu = class extends PopupMenuBase {
|
||||
export class PopupSubMenu extends PopupMenuBase {
|
||||
constructor(sourceActor, sourceArrow) {
|
||||
super(sourceActor);
|
||||
|
||||
|
|
@ -1146,7 +1207,7 @@ var PopupSubMenu = class extends PopupMenuBase {
|
|||
* can add it to another menu), but is completely transparent
|
||||
* to the user
|
||||
*/
|
||||
var PopupMenuSection = class extends PopupMenuBase {
|
||||
export class PopupMenuSection extends PopupMenuBase {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
|
|
@ -1166,7 +1227,7 @@ var PopupMenuSection = class extends PopupMenuBase {
|
|||
}
|
||||
};
|
||||
|
||||
var PopupSubMenuMenuItem = GObject.registerClass(
|
||||
export const PopupSubMenuMenuItem = GObject.registerClass(
|
||||
class PopupSubMenuMenuItem extends PopupBaseMenuItem {
|
||||
_init(text, wantIcon) {
|
||||
super._init();
|
||||
|
|
@ -1287,7 +1348,7 @@ class PopupSubMenuMenuItem extends PopupBaseMenuItem {
|
|||
/* Basic implementation of a menu manager.
|
||||
* Call addMenu to add menus
|
||||
*/
|
||||
var PopupMenuManager = class {
|
||||
export class PopupMenuManager {
|
||||
constructor(owner, grabParams = {}) {
|
||||
this._grabHelper = new GrabHelper.GrabHelper(owner, {
|
||||
actionMode: Shell.ActionMode.POPUP,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported loadRemoteSearchProviders */
|
||||
|
||||
const { GdkPixbuf, Gio, GLib, Shell, St } = imports.gi;
|
||||
import GdkPixbuf from 'gi://GdkPixbuf';
|
||||
import Gio from 'gi://Gio';
|
||||
import GLib from 'gi://GLib';
|
||||
import Shell from 'gi://Shell';
|
||||
import St from 'gi://St';
|
||||
|
||||
const FileUtils = imports.misc.fileUtils;
|
||||
import * as FileUtils from '../misc/fileUtilsModule.js';
|
||||
|
||||
const KEY_FILE_GROUP = 'Shell Search Provider';
|
||||
|
||||
|
|
@ -57,10 +61,10 @@ const SearchProvider2Iface = `
|
|||
</interface>
|
||||
</node>`;
|
||||
|
||||
var SearchProviderProxyInfo = Gio.DBusInterfaceInfo.new_for_xml(SearchProviderIface);
|
||||
var SearchProvider2ProxyInfo = Gio.DBusInterfaceInfo.new_for_xml(SearchProvider2Iface);
|
||||
export const SearchProviderProxyInfo = Gio.DBusInterfaceInfo.new_for_xml(SearchProviderIface);
|
||||
export const SearchProvider2ProxyInfo = Gio.DBusInterfaceInfo.new_for_xml(SearchProvider2Iface);
|
||||
|
||||
function loadRemoteSearchProviders(searchSettings, callback) {
|
||||
export function loadRemoteSearchProviders(searchSettings, callback) {
|
||||
let objectPaths = {};
|
||||
let loadedProviders = [];
|
||||
|
||||
|
|
@ -104,9 +108,9 @@ function loadRemoteSearchProviders(searchSettings, callback) {
|
|||
// ignore error
|
||||
}
|
||||
|
||||
let version = '1';
|
||||
let version = 1;
|
||||
try {
|
||||
version = keyfile.get_string(group, 'Version');
|
||||
version = Number.parseInt(keyfile.get_string(group, 'Version'), 10);
|
||||
} catch (e) {
|
||||
// ignore error
|
||||
}
|
||||
|
|
@ -187,7 +191,7 @@ function loadRemoteSearchProviders(searchSettings, callback) {
|
|||
callback(loadedProviders);
|
||||
}
|
||||
|
||||
var RemoteSearchProvider = class {
|
||||
export class RemoteSearchProvider {
|
||||
constructor(appInfo, dbusName, dbusPath, autoStart, proxyInfo) {
|
||||
if (!proxyInfo)
|
||||
proxyInfo = SearchProviderProxyInfo;
|
||||
|
|
@ -210,6 +214,7 @@ var RemoteSearchProvider = class {
|
|||
this.id = appInfo.get_id();
|
||||
this.isRemoteProvider = true;
|
||||
this.canLaunchSearch = false;
|
||||
this.defaultEnabled = false;
|
||||
}
|
||||
|
||||
createIcon(size, meta) {
|
||||
|
|
@ -318,7 +323,7 @@ var RemoteSearchProvider = class {
|
|||
}
|
||||
};
|
||||
|
||||
var RemoteSearchProvider2 = class extends RemoteSearchProvider {
|
||||
export class RemoteSearchProvider2 extends RemoteSearchProvider {
|
||||
constructor(appInfo, dbusName, dbusPath, autoStart) {
|
||||
super(appInfo, dbusName, dbusPath, autoStart, SearchProvider2ProxyInfo);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||
/* exported Ripples */
|
||||
|
||||
const { Clutter, St } = imports.gi;
|
||||
import Clutter from 'gi://Clutter';
|
||||
import St from 'gi://St';
|
||||
|
||||
// Shamelessly copied from the layout "hotcorner" ripples implementation
|
||||
var Ripples = class Ripples {
|
||||
export class Ripples {
|
||||
constructor(px, py, styleClass) {
|
||||
this._x = 0;
|
||||
this._y = 0;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue