2011-09-28 13:16:26 +00:00
|
|
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
2019-01-31 14:07:06 +00:00
|
|
|
/* exported componentManager, notificationDaemon, windowAttentionHandler,
|
|
|
|
ctrlAltTabManager, padOsdService, osdWindowManager,
|
|
|
|
osdMonitorLabeler, shellMountOpDBusService, shellDBusService,
|
|
|
|
shellAccessDialogDBusService, shellAudioSelectionDBusService,
|
2020-04-23 18:46:44 +00:00
|
|
|
screenSaverDBus, uiGroup, magnifier, xdndHandler, keyboard,
|
|
|
|
kbdA11yDialog, introspectService, start, pushModal, popModal,
|
|
|
|
activateWindow, createLookingGlass, initializeDeferredWork,
|
|
|
|
getThemeStylesheet, setThemeStylesheet */
|
2008-10-31 18:09:20 +00:00
|
|
|
|
2019-05-23 20:45:44 +00:00
|
|
|
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
|
2008-10-31 04:22:44 +00:00
|
|
|
|
2016-07-12 20:47:32 +00:00
|
|
|
const AccessDialog = imports.ui.accessDialog;
|
2016-02-09 22:03:26 +00:00
|
|
|
const AudioDeviceSelection = imports.ui.audioDeviceSelection;
|
2012-09-03 01:23:50 +00:00
|
|
|
const Components = imports.ui.components;
|
2010-07-01 18:13:42 +00:00
|
|
|
const CtrlAltTab = imports.ui.ctrlAltTab;
|
2011-01-06 15:30:15 +00:00
|
|
|
const EndSessionDialog = imports.ui.endSessionDialog;
|
2009-10-25 22:53:10 +00:00
|
|
|
const ExtensionSystem = imports.ui.extensionSystem;
|
2012-05-25 23:07:31 +00:00
|
|
|
const ExtensionDownloader = imports.ui.extensionDownloader;
|
2017-12-05 19:05:00 +00:00
|
|
|
const InputMethod = imports.misc.inputMethod;
|
2018-09-05 09:15:30 +00:00
|
|
|
const Introspect = imports.misc.introspect;
|
2011-08-29 15:11:22 +00:00
|
|
|
const Keyboard = imports.ui.keyboard;
|
2010-01-13 20:05:20 +00:00
|
|
|
const MessageTray = imports.ui.messageTray;
|
2014-05-08 22:56:23 +00:00
|
|
|
const ModalDialog = imports.ui.modalDialog;
|
2013-03-02 09:48:25 +00:00
|
|
|
const OsdWindow = imports.ui.osdWindow;
|
2015-01-26 14:52:10 +00:00
|
|
|
const OsdMonitorLabeler = imports.ui.osdMonitorLabeler;
|
2009-08-11 11:46:10 +00:00
|
|
|
const Overview = imports.ui.overview;
|
2016-06-22 17:57:12 +00:00
|
|
|
const PadOsd = imports.ui.padOsd;
|
2009-02-02 23:02:16 +00:00
|
|
|
const Panel = imports.ui.panel;
|
2012-08-10 15:54:39 +00:00
|
|
|
const Params = imports.misc.params;
|
2008-12-09 22:10:43 +00:00
|
|
|
const RunDialog = imports.ui.runDialog;
|
2021-02-01 09:20:48 +00:00
|
|
|
const WelcomeDialog = imports.ui.welcomeDialog;
|
2011-06-13 13:54:05 +00:00
|
|
|
const Layout = imports.ui.layout;
|
2013-03-04 18:20:12 +00:00
|
|
|
const LoginManager = imports.misc.loginManager;
|
2009-08-02 07:46:01 +00:00
|
|
|
const LookingGlass = imports.ui.lookingGlass;
|
2010-01-13 20:05:20 +00:00
|
|
|
const NotificationDaemon = imports.ui.notificationDaemon;
|
2010-02-22 18:53:41 +00:00
|
|
|
const WindowAttentionHandler = imports.ui.windowAttentionHandler;
|
2012-02-06 22:28:48 +00:00
|
|
|
const ScreenShield = imports.ui.screenShield;
|
2010-05-09 17:42:35 +00:00
|
|
|
const Scripting = imports.ui.scripting;
|
2012-05-16 22:26:44 +00:00
|
|
|
const SessionMode = imports.ui.sessionMode;
|
2009-09-23 18:30:05 +00:00
|
|
|
const ShellDBus = imports.ui.shellDBus;
|
2012-06-20 21:23:34 +00:00
|
|
|
const ShellMountOperation = imports.ui.shellMountOperation;
|
2008-12-09 22:10:43 +00:00
|
|
|
const WindowManager = imports.ui.windowManager;
|
2010-05-10 16:40:03 +00:00
|
|
|
const Magnifier = imports.ui.magnifier;
|
2011-01-05 14:47:27 +00:00
|
|
|
const XdndHandler = imports.ui.xdndHandler;
|
2017-11-07 14:40:51 +00:00
|
|
|
const KbdA11yDialog = imports.ui.kbdA11yDialog;
|
2019-02-20 09:12:36 +00:00
|
|
|
const LocatePointer = imports.ui.locatePointer;
|
2019-03-20 16:46:12 +00:00
|
|
|
const PointerA11yTimeout = imports.ui.pointerA11yTimeout;
|
2019-04-24 09:37:10 +00:00
|
|
|
const ParentalControlsManager = imports.misc.parentalControlsManager;
|
2021-02-01 12:31:41 +00:00
|
|
|
const Config = imports.misc.config;
|
|
|
|
const Util = imports.misc.util;
|
2008-10-31 18:09:20 +00:00
|
|
|
|
2021-02-01 12:31:41 +00:00
|
|
|
const WELCOME_DIALOG_LAST_SHOWN_VERSION = 'welcome-dialog-last-shown-version';
|
|
|
|
// Make sure to mention the point release, otherwise it will show every time
|
|
|
|
// until this version is current
|
|
|
|
const WELCOME_DIALOG_LAST_TOUR_CHANGE = '40.beta';
|
2019-06-15 12:48:58 +00:00
|
|
|
const LOG_DOMAIN = 'GNOME Shell';
|
2014-04-18 14:31:18 +00:00
|
|
|
const GNOMESHELL_STARTED_MESSAGE_ID = 'f3ea493c22934e26811cd62abe8e203a';
|
2013-04-17 23:59:02 +00:00
|
|
|
|
2017-07-18 17:48:08 +00:00
|
|
|
var componentManager = null;
|
2019-03-07 00:45:45 +00:00
|
|
|
var extensionManager = null;
|
2017-07-18 17:48:08 +00:00
|
|
|
var panel = null;
|
|
|
|
var overview = null;
|
|
|
|
var runDialog = null;
|
|
|
|
var lookingGlass = null;
|
2021-02-01 09:20:48 +00:00
|
|
|
var welcomeDialog = null;
|
2017-07-18 17:48:08 +00:00
|
|
|
var wm = null;
|
|
|
|
var messageTray = null;
|
|
|
|
var screenShield = null;
|
|
|
|
var notificationDaemon = null;
|
|
|
|
var windowAttentionHandler = null;
|
|
|
|
var ctrlAltTabManager = null;
|
|
|
|
var padOsdService = null;
|
|
|
|
var osdWindowManager = null;
|
|
|
|
var osdMonitorLabeler = null;
|
|
|
|
var sessionMode = null;
|
|
|
|
var shellAccessDialogDBusService = null;
|
|
|
|
var shellAudioSelectionDBusService = null;
|
|
|
|
var shellDBusService = null;
|
|
|
|
var shellMountOpDBusService = null;
|
|
|
|
var screenSaverDBus = null;
|
|
|
|
var modalCount = 0;
|
|
|
|
var actionMode = Shell.ActionMode.NONE;
|
|
|
|
var modalActorFocusStack = [];
|
|
|
|
var uiGroup = null;
|
|
|
|
var magnifier = null;
|
|
|
|
var xdndHandler = null;
|
|
|
|
var keyboard = null;
|
|
|
|
var layoutManager = null;
|
2017-11-07 14:40:51 +00:00
|
|
|
var kbdA11yDialog = null;
|
2017-12-05 19:05:00 +00:00
|
|
|
var inputMethod = null;
|
2018-09-05 09:15:30 +00:00
|
|
|
var introspectService = null;
|
2019-02-20 09:12:36 +00:00
|
|
|
var locatePointer = null;
|
2009-10-24 17:36:52 +00:00
|
|
|
let _startDate;
|
2011-02-01 15:11:00 +00:00
|
|
|
let _defaultCssStylesheet = null;
|
|
|
|
let _cssStylesheet = null;
|
2015-10-21 17:27:19 +00:00
|
|
|
let _themeResource = null;
|
2017-08-10 19:27:25 +00:00
|
|
|
let _oskResource = null;
|
2008-10-31 18:09:20 +00:00
|
|
|
|
2020-03-20 11:42:04 +00:00
|
|
|
Gio._promisify(Gio._LocalFilePrototype, 'delete_async', 'delete_finish');
|
|
|
|
Gio._promisify(Gio._LocalFilePrototype, 'touch_async', 'touch_finish');
|
|
|
|
|
2020-04-21 14:13:20 +00:00
|
|
|
let _remoteAccessInhibited = false;
|
|
|
|
|
2012-09-01 12:42:53 +00:00
|
|
|
function _sessionUpdated() {
|
2014-11-29 13:37:19 +00:00
|
|
|
if (sessionMode.isPrimary)
|
|
|
|
_loadDefaultStylesheet();
|
2013-02-18 10:23:08 +00:00
|
|
|
|
2014-12-11 14:35:40 +00:00
|
|
|
wm.allowKeybinding('overlay-key', Shell.ActionMode.NORMAL |
|
|
|
|
Shell.ActionMode.OVERVIEW);
|
2012-08-11 04:34:53 +00:00
|
|
|
|
2019-02-20 09:12:36 +00:00
|
|
|
wm.allowKeybinding('locate-pointer-key', Shell.ActionMode.ALL);
|
|
|
|
|
2012-08-11 04:34:53 +00:00
|
|
|
wm.setCustomKeybindingHandler('panel-run-dialog',
|
2014-12-11 14:35:40 +00:00
|
|
|
Shell.ActionMode.NORMAL |
|
|
|
|
Shell.ActionMode.OVERVIEW,
|
2012-08-11 04:34:53 +00:00
|
|
|
sessionMode.hasRunDialog ? openRunDialog : null);
|
2013-03-08 21:59:02 +00:00
|
|
|
|
2013-09-18 17:47:59 +00:00
|
|
|
if (!sessionMode.hasRunDialog) {
|
|
|
|
if (runDialog)
|
|
|
|
runDialog.close();
|
|
|
|
if (lookingGlass)
|
|
|
|
lookingGlass.close();
|
2021-02-01 09:20:48 +00:00
|
|
|
if (welcomeDialog)
|
|
|
|
welcomeDialog.close();
|
2013-09-18 17:47:59 +00:00
|
|
|
}
|
2020-04-21 14:13:20 +00:00
|
|
|
|
|
|
|
let remoteAccessController = global.backend.get_remote_access_controller();
|
|
|
|
if (remoteAccessController) {
|
|
|
|
if (sessionMode.allowScreencast && _remoteAccessInhibited) {
|
|
|
|
remoteAccessController.uninhibit_remote_access();
|
|
|
|
_remoteAccessInhibited = false;
|
|
|
|
} else if (!sessionMode.allowScreencast && !_remoteAccessInhibited) {
|
|
|
|
remoteAccessController.inhibit_remote_access();
|
|
|
|
_remoteAccessInhibited = true;
|
|
|
|
}
|
|
|
|
}
|
2012-09-01 12:42:53 +00:00
|
|
|
}
|
|
|
|
|
2008-10-31 04:22:44 +00:00
|
|
|
function start() {
|
2012-04-29 20:42:45 +00:00
|
|
|
// These are here so we don't break compatibility.
|
2020-04-23 23:06:36 +00:00
|
|
|
global.logError = globalThis.log;
|
|
|
|
global.log = globalThis.log;
|
2009-10-24 17:36:52 +00:00
|
|
|
|
2011-03-15 22:31:16 +00:00
|
|
|
// Chain up async errors reported from C
|
2017-10-31 00:38:18 +00:00
|
|
|
global.connect('notify-error', (global, msg, detail) => {
|
|
|
|
notifyError(msg, detail);
|
|
|
|
});
|
2011-03-15 22:31:16 +00:00
|
|
|
|
2020-03-31 18:13:46 +00:00
|
|
|
let currentDesktop = GLib.getenv('XDG_CURRENT_DESKTOP');
|
|
|
|
if (!currentDesktop || !currentDesktop.split(':').includes('GNOME'))
|
|
|
|
Gio.DesktopAppInfo.set_desktop_env('GNOME');
|
2009-01-22 21:28:19 +00:00
|
|
|
|
2013-02-18 10:26:25 +00:00
|
|
|
sessionMode = new SessionMode.SessionMode();
|
|
|
|
sessionMode.connect('updated', _sessionUpdated);
|
2018-11-27 13:59:09 +00:00
|
|
|
|
|
|
|
St.Settings.get().connect('notify::gtk-theme', _loadDefaultStylesheet);
|
2019-04-24 09:37:10 +00:00
|
|
|
|
|
|
|
// Initialize ParentalControlsManager before the UI
|
|
|
|
ParentalControlsManager.getDefault();
|
|
|
|
|
2013-02-18 10:26:25 +00:00
|
|
|
_initializeUI();
|
2013-03-08 20:04:15 +00:00
|
|
|
|
2016-07-12 20:47:32 +00:00
|
|
|
shellAccessDialogDBusService = new AccessDialog.AccessDialogDBus();
|
2016-02-09 22:03:26 +00:00
|
|
|
shellAudioSelectionDBusService = new AudioDeviceSelection.AudioDeviceSelectionDBus();
|
2013-03-08 20:04:15 +00:00
|
|
|
shellDBusService = new ShellDBus.GnomeShell();
|
|
|
|
shellMountOpDBusService = new ShellMountOperation.GnomeShellMountOpHandler();
|
|
|
|
|
2020-03-12 22:23:37 +00:00
|
|
|
const watchId = Gio.DBus.session.watch_name('org.gnome.Shell.Notifications',
|
|
|
|
Gio.BusNameWatcherFlags.AUTO_START,
|
|
|
|
bus => bus.unwatch_name(watchId),
|
|
|
|
bus => bus.unwatch_name(watchId));
|
2020-03-04 01:35:21 +00:00
|
|
|
|
2013-02-18 10:26:25 +00:00
|
|
|
_sessionUpdated();
|
|
|
|
}
|
2013-03-06 22:25:28 +00:00
|
|
|
|
2013-02-18 10:26:25 +00:00
|
|
|
function _initializeUI() {
|
2009-10-15 23:28:29 +00:00
|
|
|
// Ensure ShellWindowTracker and ShellAppUsage are initialized; this will
|
2019-06-26 10:54:09 +00:00
|
|
|
// also initialize ShellAppSystem first. ShellAppSystem
|
2009-10-15 23:28:29 +00:00
|
|
|
// needs to load all the .desktop files, and ShellWindowTracker
|
2019-06-26 10:54:09 +00:00
|
|
|
// will use those to associate with windows. Right now
|
2009-08-12 17:32:54 +00:00
|
|
|
// the Monitor doesn't listen for installed app changes
|
|
|
|
// and recalculate application associations, so to avoid
|
2019-06-26 10:54:09 +00:00
|
|
|
// races for now we initialize it here. It's better to
|
2009-08-12 17:32:54 +00:00
|
|
|
// be predictable anyways.
|
2012-12-23 03:10:27 +00:00
|
|
|
Shell.WindowTracker.get_default();
|
2009-10-15 23:28:29 +00:00
|
|
|
Shell.AppUsage.get_default();
|
2009-08-12 17:32:54 +00:00
|
|
|
|
2015-10-21 17:27:19 +00:00
|
|
|
reloadThemeResource();
|
2017-08-10 19:27:25 +00:00
|
|
|
_loadOskLayouts();
|
2013-02-05 03:13:44 +00:00
|
|
|
_loadDefaultStylesheet();
|
2009-09-10 05:36:41 +00:00
|
|
|
|
2019-10-01 10:02:31 +00:00
|
|
|
new AnimationsSettings();
|
|
|
|
|
2013-01-10 21:02:20 +00:00
|
|
|
// Setup the stage hierarchy early
|
2011-06-13 13:54:05 +00:00
|
|
|
layoutManager = new Layout.LayoutManager();
|
2013-02-14 03:45:43 +00:00
|
|
|
|
2019-06-26 10:54:09 +00:00
|
|
|
// Various parts of the codebase still refer to Main.uiGroup
|
|
|
|
// instead of using the layoutManager. This keeps that code
|
2013-01-10 21:02:20 +00:00
|
|
|
// working until it's updated.
|
|
|
|
uiGroup = layoutManager.uiGroup;
|
|
|
|
|
2016-06-22 17:57:12 +00:00
|
|
|
padOsdService = new PadOsd.PadOsdService();
|
2011-01-05 14:47:27 +00:00
|
|
|
xdndHandler = new XdndHandler.XdndHandler();
|
2011-02-07 16:29:34 +00:00
|
|
|
ctrlAltTabManager = new CtrlAltTab.CtrlAltTabManager();
|
2014-04-17 08:23:30 +00:00
|
|
|
osdWindowManager = new OsdWindow.OsdWindowManager();
|
2015-01-26 14:52:10 +00:00
|
|
|
osdMonitorLabeler = new OsdMonitorLabeler.OsdMonitorLabeler();
|
2012-05-16 22:59:02 +00:00
|
|
|
overview = new Overview.Overview();
|
2017-11-07 14:40:51 +00:00
|
|
|
kbdA11yDialog = new KbdA11yDialog.KbdA11yDialog();
|
2012-11-30 00:27:16 +00:00
|
|
|
wm = new WindowManager.WindowManager();
|
2010-07-21 08:44:59 +00:00
|
|
|
magnifier = new Magnifier.Magnifier();
|
2019-06-29 12:30:23 +00:00
|
|
|
locatePointer = new LocatePointer.LocatePointer();
|
2019-02-20 09:12:36 +00:00
|
|
|
|
2013-03-04 18:20:12 +00:00
|
|
|
if (LoginManager.canLock())
|
2012-07-08 15:42:15 +00:00
|
|
|
screenShield = new ScreenShield.ScreenShield();
|
2013-02-17 04:28:29 +00:00
|
|
|
|
2017-12-05 19:05:00 +00:00
|
|
|
inputMethod = new InputMethod.InputMethod();
|
|
|
|
Clutter.get_default_backend().set_input_method(inputMethod);
|
|
|
|
|
2010-02-02 15:21:47 +00:00
|
|
|
messageTray = new MessageTray.MessageTray();
|
2015-02-11 19:41:56 +00:00
|
|
|
panel = new Panel.Panel();
|
2019-08-28 21:52:52 +00:00
|
|
|
keyboard = new Keyboard.KeyboardManager();
|
2010-01-13 20:05:20 +00:00
|
|
|
notificationDaemon = new NotificationDaemon.NotificationDaemon();
|
2010-02-22 18:53:41 +00:00
|
|
|
windowAttentionHandler = new WindowAttentionHandler.WindowAttentionHandler();
|
2012-09-03 01:23:50 +00:00
|
|
|
componentManager = new Components.ComponentManager();
|
2011-01-31 17:48:18 +00:00
|
|
|
|
2018-09-05 09:15:30 +00:00
|
|
|
introspectService = new Introspect.IntrospectService();
|
|
|
|
|
2011-09-01 17:35:15 +00:00
|
|
|
layoutManager.init();
|
2011-08-24 01:53:02 +00:00
|
|
|
overview.init();
|
2009-03-13 21:14:31 +00:00
|
|
|
|
2019-08-19 19:38:51 +00:00
|
|
|
new PointerA11yTimeout.PointerA11yTimeout();
|
2019-03-20 16:46:12 +00:00
|
|
|
|
2019-02-20 09:12:36 +00:00
|
|
|
global.connect('locate-pointer', () => {
|
|
|
|
locatePointer.show();
|
|
|
|
});
|
|
|
|
|
2017-10-31 00:38:18 +00:00
|
|
|
global.display.connect('show-restart-message', (display, message) => {
|
2014-05-08 22:56:23 +00:00
|
|
|
showRestartMessage(message);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
2017-10-31 00:38:18 +00:00
|
|
|
global.display.connect('restart', () => {
|
2014-05-08 22:56:23 +00:00
|
|
|
global.reexec_self();
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
2016-06-03 13:20:20 +00:00
|
|
|
global.display.connect('gl-video-memory-purged', loadTheme);
|
|
|
|
|
2011-01-06 15:30:15 +00:00
|
|
|
// Provide the bus object for gnome-session to
|
|
|
|
// initiate logouts.
|
|
|
|
EndSessionDialog.init();
|
|
|
|
|
2013-02-28 15:43:39 +00:00
|
|
|
// We're ready for the session manager to move to the next phase
|
2019-10-04 11:11:06 +00:00
|
|
|
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
|
|
|
|
Shell.util_sd_notify();
|
2021-07-15 17:46:47 +00:00
|
|
|
global.context.notify_ready();
|
2019-10-04 11:11:06 +00:00
|
|
|
return GLib.SOURCE_REMOVE;
|
|
|
|
});
|
2013-02-28 15:43:39 +00:00
|
|
|
|
2011-08-24 01:53:02 +00:00
|
|
|
_startDate = new Date();
|
2009-08-28 19:11:25 +00:00
|
|
|
|
2012-09-01 12:42:53 +00:00
|
|
|
ExtensionDownloader.init();
|
2019-03-07 00:45:45 +00:00
|
|
|
extensionManager = new ExtensionSystem.ExtensionManager();
|
2019-07-07 21:38:27 +00:00
|
|
|
extensionManager.init();
|
2013-02-14 03:45:43 +00:00
|
|
|
|
2013-03-06 23:01:12 +00:00
|
|
|
if (sessionMode.isGreeter && screenShield) {
|
2017-10-31 00:38:18 +00:00
|
|
|
layoutManager.connect('startup-prepared', () => {
|
2013-03-06 23:01:12 +00:00
|
|
|
screenShield.showDialog();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-10-31 00:38:18 +00:00
|
|
|
layoutManager.connect('startup-complete', () => {
|
2019-08-20 00:51:42 +00:00
|
|
|
if (actionMode == Shell.ActionMode.NONE)
|
2014-12-11 14:35:40 +00:00
|
|
|
actionMode = Shell.ActionMode.NORMAL;
|
2019-08-20 00:51:42 +00:00
|
|
|
|
|
|
|
if (screenShield)
|
2014-09-05 00:55:05 +00:00
|
|
|
screenShield.lockIfWasLocked();
|
2019-08-20 00:51:42 +00:00
|
|
|
|
2015-02-13 09:27:27 +00:00
|
|
|
if (sessionMode.currentMode != 'gdm' &&
|
2014-09-05 00:55:05 +00:00
|
|
|
sessionMode.currentMode != 'initial-setup') {
|
2019-06-15 12:48:58 +00:00
|
|
|
GLib.log_structured(LOG_DOMAIN, GLib.LogLevelFlags.LEVEL_MESSAGE, {
|
2020-02-14 15:10:34 +00:00
|
|
|
'MESSAGE': 'GNOME Shell started at %s'.format(_startDate),
|
2019-08-20 21:43:54 +00:00
|
|
|
'MESSAGE_ID': GNOMESHELL_STARTED_MESSAGE_ID,
|
2019-06-15 12:48:58 +00:00
|
|
|
});
|
2014-09-05 00:55:05 +00:00
|
|
|
}
|
2019-03-05 18:31:01 +00:00
|
|
|
|
2013-06-08 17:32:35 +00:00
|
|
|
let credentials = new Gio.Credentials();
|
|
|
|
if (credentials.get_unix_user() === 0) {
|
|
|
|
notify(_('Logged in as a privileged user'),
|
|
|
|
_('Running a session as a privileged user should be avoided for security reasons. If possible, you should log in as a normal user.'));
|
2021-04-05 17:36:29 +00:00
|
|
|
} else if (sessionMode.showWelcomeDialog) {
|
2021-02-01 12:31:41 +00:00
|
|
|
_handleShowWelcomeScreen();
|
2013-06-08 17:32:35 +00:00
|
|
|
}
|
|
|
|
|
2013-06-08 17:33:58 +00:00
|
|
|
if (sessionMode.currentMode !== 'gdm' &&
|
2020-03-20 11:42:04 +00:00
|
|
|
sessionMode.currentMode !== 'initial-setup')
|
|
|
|
_handleLockScreenWarning();
|
2013-06-08 17:33:58 +00:00
|
|
|
|
2019-05-02 09:49:12 +00:00
|
|
|
LoginManager.registerSessionWithGDM();
|
|
|
|
|
2019-03-05 18:31:01 +00:00
|
|
|
let perfModuleName = GLib.getenv("SHELL_PERF_MODULE");
|
|
|
|
if (perfModuleName) {
|
|
|
|
let perfOutput = GLib.getenv("SHELL_PERF_OUTPUT");
|
2020-02-14 15:10:34 +00:00
|
|
|
let module = eval('imports.perf.%s;'.format(perfModuleName));
|
2019-03-05 18:31:01 +00:00
|
|
|
Scripting.runPerfScript(module, perfOutput);
|
|
|
|
}
|
2014-09-05 00:55:05 +00:00
|
|
|
});
|
2011-01-25 21:29:45 +00:00
|
|
|
}
|
|
|
|
|
2021-02-01 12:31:41 +00:00
|
|
|
function _handleShowWelcomeScreen() {
|
|
|
|
const lastShownVersion = global.settings.get_string(WELCOME_DIALOG_LAST_SHOWN_VERSION);
|
|
|
|
if (Util.GNOMEversionCompare(WELCOME_DIALOG_LAST_TOUR_CHANGE, lastShownVersion) > 0) {
|
|
|
|
openWelcomeDialog();
|
|
|
|
global.settings.set_string(WELCOME_DIALOG_LAST_SHOWN_VERSION, Config.PACKAGE_VERSION);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-20 11:42:04 +00:00
|
|
|
async function _handleLockScreenWarning() {
|
|
|
|
const path = '%s/lock-warning-shown'.format(global.userdatadir);
|
|
|
|
const file = Gio.File.new_for_path(path);
|
|
|
|
|
|
|
|
const hasLockScreen = screenShield !== null;
|
|
|
|
if (hasLockScreen) {
|
|
|
|
try {
|
|
|
|
await file.delete_async(0, null);
|
|
|
|
} catch (e) {
|
|
|
|
if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.NOT_FOUND))
|
|
|
|
logError(e);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
try {
|
|
|
|
if (!await file.touch_async())
|
|
|
|
return;
|
|
|
|
} catch (e) {
|
|
|
|
logError(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
notify(
|
|
|
|
_('Screen Lock disabled'),
|
|
|
|
_('Screen Locking requires the GNOME display manager.'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-29 13:37:19 +00:00
|
|
|
function _getStylesheet(name) {
|
2014-10-15 05:25:30 +00:00
|
|
|
let stylesheet;
|
|
|
|
|
2020-02-14 15:10:34 +00:00
|
|
|
stylesheet = Gio.File.new_for_uri('resource:///org/gnome/shell/theme/%s'.format(name));
|
2014-10-15 05:25:30 +00:00
|
|
|
if (stylesheet.query_exists(null))
|
|
|
|
return stylesheet;
|
|
|
|
|
2018-03-30 07:44:14 +00:00
|
|
|
let dataDirs = GLib.get_system_data_dirs();
|
|
|
|
for (let i = 0; i < dataDirs.length; i++) {
|
|
|
|
let path = GLib.build_filenamev([dataDirs[i], 'gnome-shell', 'theme', name]);
|
2019-08-20 00:20:08 +00:00
|
|
|
stylesheet = Gio.file_new_for_path(path);
|
2018-03-30 07:44:14 +00:00
|
|
|
if (stylesheet.query_exists(null))
|
|
|
|
return stylesheet;
|
|
|
|
}
|
|
|
|
|
2020-02-14 15:10:34 +00:00
|
|
|
stylesheet = Gio.File.new_for_path('%s/theme/%s'.format(global.datadir, name));
|
2014-10-15 05:25:30 +00:00
|
|
|
if (stylesheet.query_exists(null))
|
|
|
|
return stylesheet;
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2014-11-29 13:37:19 +00:00
|
|
|
function _getDefaultStylesheet() {
|
|
|
|
let stylesheet = null;
|
|
|
|
let name = sessionMode.stylesheetName;
|
2013-02-05 03:13:44 +00:00
|
|
|
|
2014-11-29 13:37:19 +00:00
|
|
|
// Look for a high-contrast variant first when using GTK+'s HighContrast
|
|
|
|
// theme
|
2018-11-27 13:59:09 +00:00
|
|
|
if (St.Settings.get().gtk_theme == 'HighContrast')
|
2014-11-29 13:37:19 +00:00
|
|
|
stylesheet = _getStylesheet(name.replace('.css', '-high-contrast.css'));
|
|
|
|
|
|
|
|
if (stylesheet == null)
|
|
|
|
stylesheet = _getStylesheet(sessionMode.stylesheetName);
|
|
|
|
|
|
|
|
return stylesheet;
|
|
|
|
}
|
|
|
|
|
|
|
|
function _loadDefaultStylesheet() {
|
2014-10-15 05:25:30 +00:00
|
|
|
let stylesheet = _getDefaultStylesheet();
|
2014-09-19 02:22:02 +00:00
|
|
|
if (_defaultCssStylesheet && _defaultCssStylesheet.equal(stylesheet))
|
2013-02-05 03:13:44 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
_defaultCssStylesheet = stylesheet;
|
|
|
|
loadTheme();
|
|
|
|
}
|
|
|
|
|
2011-01-11 11:15:26 +00:00
|
|
|
/**
|
2011-02-01 14:44:15 +00:00
|
|
|
* getThemeStylesheet:
|
|
|
|
*
|
|
|
|
* Get the theme CSS file that the shell will load
|
|
|
|
*
|
2019-10-17 16:41:52 +00:00
|
|
|
* @returns {?Gio.File}: A #GFile that contains the theme CSS,
|
2011-02-01 14:44:15 +00:00
|
|
|
* null if using the default
|
|
|
|
*/
|
2014-07-08 18:29:50 +00:00
|
|
|
function getThemeStylesheet() {
|
2011-02-01 15:11:00 +00:00
|
|
|
return _cssStylesheet;
|
2011-02-01 14:44:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* setThemeStylesheet:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {string=} cssStylesheet: A file path that contains the theme CSS,
|
|
|
|
* set it to null to use the default
|
2011-01-11 11:15:26 +00:00
|
|
|
*
|
|
|
|
* Set the theme CSS file that the shell will load
|
|
|
|
*/
|
2014-07-08 18:29:50 +00:00
|
|
|
function setThemeStylesheet(cssStylesheet) {
|
2014-11-27 14:24:49 +00:00
|
|
|
_cssStylesheet = cssStylesheet ? Gio.File.new_for_path(cssStylesheet) : null;
|
2011-01-11 11:15:26 +00:00
|
|
|
}
|
|
|
|
|
2015-10-21 17:27:19 +00:00
|
|
|
function reloadThemeResource() {
|
|
|
|
if (_themeResource)
|
|
|
|
_themeResource._unregister();
|
|
|
|
|
2020-03-03 09:05:54 +00:00
|
|
|
_themeResource = Gio.Resource.load('%s/%s'.format(global.datadir,
|
|
|
|
sessionMode.themeResourceName));
|
2015-10-21 17:27:19 +00:00
|
|
|
_themeResource._register();
|
|
|
|
}
|
|
|
|
|
2017-08-10 19:27:25 +00:00
|
|
|
function _loadOskLayouts() {
|
2020-02-14 15:10:34 +00:00
|
|
|
_oskResource = Gio.Resource.load('%s/gnome-shell-osk-layouts.gresource'.format(global.datadir));
|
2017-08-10 19:27:25 +00:00
|
|
|
_oskResource._register();
|
|
|
|
}
|
|
|
|
|
2011-01-04 19:30:03 +00:00
|
|
|
/**
|
|
|
|
* loadTheme:
|
|
|
|
*
|
2011-01-11 11:15:26 +00:00
|
|
|
* Reloads the theme CSS file
|
2011-01-04 19:30:03 +00:00
|
|
|
*/
|
|
|
|
function loadTheme() {
|
2019-08-19 17:55:49 +00:00
|
|
|
let themeContext = St.ThemeContext.get_for_stage(global.stage);
|
2011-06-02 15:05:08 +00:00
|
|
|
let previousTheme = themeContext.get_theme();
|
2011-01-11 11:15:26 +00:00
|
|
|
|
2019-08-19 17:55:49 +00:00
|
|
|
let theme = new St.Theme({
|
|
|
|
application_stylesheet: _cssStylesheet,
|
2019-08-20 21:43:54 +00:00
|
|
|
default_stylesheet: _defaultCssStylesheet,
|
2019-08-19 17:55:49 +00:00
|
|
|
});
|
2011-06-02 15:05:08 +00:00
|
|
|
|
2018-08-15 01:33:13 +00:00
|
|
|
if (theme.default_stylesheet == null)
|
|
|
|
throw new Error("No valid stylesheet found for '%s'".format(sessionMode.stylesheetName));
|
|
|
|
|
2011-06-02 15:05:08 +00:00
|
|
|
if (previousTheme) {
|
|
|
|
let customStylesheets = previousTheme.get_custom_stylesheets();
|
|
|
|
|
|
|
|
for (let i = 0; i < customStylesheets.length; i++)
|
|
|
|
theme.load_stylesheet(customStylesheets[i]);
|
|
|
|
}
|
|
|
|
|
2019-08-19 17:55:49 +00:00
|
|
|
themeContext.set_theme(theme);
|
2011-01-04 19:30:03 +00:00
|
|
|
}
|
|
|
|
|
2011-07-28 18:06:24 +00:00
|
|
|
/**
|
|
|
|
* notify:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {string} msg: A message
|
|
|
|
* @param {string} details: Additional information
|
2011-07-28 18:06:24 +00:00
|
|
|
*/
|
|
|
|
function notify(msg, details) {
|
|
|
|
let source = new MessageTray.SystemNotificationSource();
|
|
|
|
messageTray.add(source);
|
|
|
|
let notification = new MessageTray.Notification(source, msg, details);
|
|
|
|
notification.setTransient(true);
|
2019-05-13 21:32:31 +00:00
|
|
|
source.showNotification(notification);
|
2011-07-28 18:06:24 +00:00
|
|
|
}
|
|
|
|
|
2011-03-15 22:31:16 +00:00
|
|
|
/**
|
|
|
|
* notifyError:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {string} msg: An error message
|
|
|
|
* @param {string} details: Additional information
|
2011-03-15 22:31:16 +00:00
|
|
|
*
|
|
|
|
* See shell_global_notify_problem().
|
|
|
|
*/
|
|
|
|
function notifyError(msg, details) {
|
|
|
|
// Also print to stderr so it's logged somewhere
|
|
|
|
if (details)
|
2020-02-14 15:10:34 +00:00
|
|
|
log('error: %s: %s'.format(msg, details));
|
2011-03-15 22:31:16 +00:00
|
|
|
else
|
2020-02-14 15:10:34 +00:00
|
|
|
log('error: %s'.format(msg));
|
2011-03-15 22:31:16 +00:00
|
|
|
|
2011-07-28 18:06:24 +00:00
|
|
|
notify(msg, details);
|
2011-03-15 22:31:16 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 19:53:07 +00:00
|
|
|
function _findModal(actor) {
|
|
|
|
for (let i = 0; i < modalActorFocusStack.length; i++) {
|
2011-02-24 22:29:20 +00:00
|
|
|
if (modalActorFocusStack[i].actor == actor)
|
2009-09-15 19:53:07 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* pushModal:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {Clutter.Actor} actor: actor which will be given keyboard focus
|
|
|
|
* @param {Object=} params: optional parameters
|
2009-09-15 19:53:07 +00:00
|
|
|
*
|
|
|
|
* Ensure we are in a mode where all keyboard and mouse input goes to
|
2010-11-03 17:30:08 +00:00
|
|
|
* the stage, and focus @actor. Multiple calls to this function act in
|
|
|
|
* a stacking fashion; the effect will be undone when an equal number
|
|
|
|
* of popModal() invocations have been made.
|
2009-09-15 19:53:07 +00:00
|
|
|
*
|
2010-11-03 17:30:08 +00:00
|
|
|
* Next, record the current Clutter keyboard focus on a stack. If the
|
|
|
|
* modal stack returns to this actor, reset the focus to the actor
|
|
|
|
* which was focused at the time pushModal() was invoked.
|
2009-09-16 15:37:51 +00:00
|
|
|
*
|
2012-08-10 15:54:39 +00:00
|
|
|
* @params may be used to provide the following parameters:
|
|
|
|
* - timestamp: used to associate the call with a specific user initiated
|
2019-06-26 10:54:09 +00:00
|
|
|
* event. If not provided then the value of
|
2012-08-10 15:54:39 +00:00
|
|
|
* global.get_current_time() is assumed.
|
2010-10-20 19:08:14 +00:00
|
|
|
*
|
2012-08-10 15:54:39 +00:00
|
|
|
* - options: Meta.ModalOptions flags to indicate that the pointer is
|
|
|
|
* already grabbed
|
2011-10-21 07:12:17 +00:00
|
|
|
*
|
2014-12-11 14:35:40 +00:00
|
|
|
* - actionMode: used to set the current Shell.ActionMode to filter
|
2019-06-26 10:54:09 +00:00
|
|
|
* global keybindings; the default of NONE will filter
|
|
|
|
* out all keybindings
|
2012-08-10 18:35:59 +00:00
|
|
|
*
|
2019-10-17 16:41:52 +00:00
|
|
|
* @returns {bool}: true iff we successfully acquired a grab or already had one
|
2009-09-15 19:53:07 +00:00
|
|
|
*/
|
2012-08-10 15:54:39 +00:00
|
|
|
function pushModal(actor, params) {
|
|
|
|
params = Params.parse(params, { timestamp: global.get_current_time(),
|
2012-08-10 18:35:59 +00:00
|
|
|
options: 0,
|
2014-12-11 14:35:40 +00:00
|
|
|
actionMode: Shell.ActionMode.NONE });
|
2010-10-20 19:08:14 +00:00
|
|
|
|
2009-09-16 15:37:51 +00:00
|
|
|
if (modalCount == 0) {
|
2012-08-10 15:54:39 +00:00
|
|
|
if (!global.begin_modal(params.timestamp, params.options)) {
|
2010-05-13 19:46:04 +00:00
|
|
|
log('pushModal: invocation of begin_modal failed');
|
2009-09-16 15:37:51 +00:00
|
|
|
return false;
|
|
|
|
}
|
2018-01-03 07:55:38 +00:00
|
|
|
Meta.disable_unredirect_for_display(global.display);
|
2009-09-16 15:37:51 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 19:53:07 +00:00
|
|
|
modalCount += 1;
|
2017-10-31 00:38:18 +00:00
|
|
|
let actorDestroyId = actor.connect('destroy', () => {
|
2009-09-15 19:53:07 +00:00
|
|
|
let index = _findModal(actor);
|
|
|
|
if (index >= 0)
|
2012-05-21 16:44:21 +00:00
|
|
|
popModal(actor);
|
2009-09-15 19:53:07 +00:00
|
|
|
});
|
2013-01-02 14:13:24 +00:00
|
|
|
|
|
|
|
let prevFocus = global.stage.get_key_focus();
|
|
|
|
let prevFocusDestroyId;
|
|
|
|
if (prevFocus != null) {
|
2017-10-31 00:38:18 +00:00
|
|
|
prevFocusDestroyId = prevFocus.connect('destroy', () => {
|
2020-04-28 21:26:11 +00:00
|
|
|
const index = modalActorFocusStack.findIndex(
|
|
|
|
record => record.prevFocus === prevFocus);
|
|
|
|
|
2009-09-15 19:53:07 +00:00
|
|
|
if (index >= 0)
|
2013-01-02 14:13:24 +00:00
|
|
|
modalActorFocusStack[index].prevFocus = null;
|
2009-09-15 19:53:07 +00:00
|
|
|
});
|
|
|
|
}
|
2019-08-19 19:06:04 +00:00
|
|
|
modalActorFocusStack.push({ actor,
|
2011-02-24 22:29:20 +00:00
|
|
|
destroyId: actorDestroyId,
|
2019-08-19 19:06:04 +00:00
|
|
|
prevFocus,
|
|
|
|
prevFocusDestroyId,
|
|
|
|
actionMode });
|
2008-11-24 19:07:18 +00:00
|
|
|
|
2014-12-11 14:35:40 +00:00
|
|
|
actionMode = params.actionMode;
|
2010-11-03 17:30:08 +00:00
|
|
|
global.stage.set_key_focus(actor);
|
2009-09-16 15:37:51 +00:00
|
|
|
return true;
|
2008-10-31 23:09:46 +00:00
|
|
|
}
|
|
|
|
|
2009-09-15 19:53:07 +00:00
|
|
|
/**
|
|
|
|
* popModal:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {Clutter.Actor} actor: the actor passed to original invocation
|
|
|
|
* of pushModal()
|
|
|
|
* @param {number=} timestamp: optional timestamp
|
2009-09-15 19:53:07 +00:00
|
|
|
*
|
2019-06-26 10:54:09 +00:00
|
|
|
* Reverse the effect of pushModal(). If this invocation is undoing
|
2009-09-15 19:53:07 +00:00
|
|
|
* the topmost invocation, then the focus will be restored to the
|
|
|
|
* previous focus at the time when pushModal() was invoked.
|
2010-10-20 19:08:14 +00:00
|
|
|
*
|
|
|
|
* @timestamp is optionally used to associate the call with a specific user
|
2019-06-26 10:54:09 +00:00
|
|
|
* initiated event. If not provided then the value of
|
2010-10-20 19:08:14 +00:00
|
|
|
* global.get_current_time() is assumed.
|
2009-09-15 19:53:07 +00:00
|
|
|
*/
|
2010-10-20 19:08:14 +00:00
|
|
|
function popModal(actor, timestamp) {
|
|
|
|
if (timestamp == undefined)
|
|
|
|
timestamp = global.get_current_time();
|
|
|
|
|
2009-09-15 19:53:07 +00:00
|
|
|
let focusIndex = _findModal(actor);
|
2011-02-24 22:29:20 +00:00
|
|
|
if (focusIndex < 0) {
|
|
|
|
global.stage.set_key_focus(null);
|
|
|
|
global.end_modal(timestamp);
|
2014-12-11 14:35:40 +00:00
|
|
|
actionMode = Shell.ActionMode.NORMAL;
|
2011-02-24 22:29:20 +00:00
|
|
|
|
|
|
|
throw new Error('incorrect pop');
|
|
|
|
}
|
|
|
|
|
|
|
|
modalCount -= 1;
|
|
|
|
|
|
|
|
let record = modalActorFocusStack[focusIndex];
|
|
|
|
record.actor.disconnect(record.destroyId);
|
|
|
|
|
|
|
|
if (focusIndex == modalActorFocusStack.length - 1) {
|
2013-01-02 14:13:24 +00:00
|
|
|
if (record.prevFocus)
|
|
|
|
record.prevFocus.disconnect(record.prevFocusDestroyId);
|
2014-12-11 14:35:40 +00:00
|
|
|
actionMode = record.actionMode;
|
2013-01-02 14:13:24 +00:00
|
|
|
global.stage.set_key_focus(record.prevFocus);
|
2011-02-24 22:29:20 +00:00
|
|
|
} else {
|
2013-01-02 14:19:41 +00:00
|
|
|
// If we have:
|
|
|
|
// global.stage.set_focus(a);
|
|
|
|
// Main.pushModal(b);
|
|
|
|
// Main.pushModal(c);
|
|
|
|
// Main.pushModal(d);
|
|
|
|
//
|
|
|
|
// then we have the stack:
|
|
|
|
// [{ prevFocus: a, actor: b },
|
|
|
|
// { prevFocus: b, actor: c },
|
|
|
|
// { prevFocus: c, actor: d }]
|
|
|
|
//
|
|
|
|
// When actor c is destroyed/popped, if we only simply remove the
|
|
|
|
// record, then the focus stack will be [a, c], rather than the correct
|
|
|
|
// [a, b]. Shift the focus stack up before removing the record to ensure
|
|
|
|
// that we get the correct result.
|
2011-02-24 22:29:20 +00:00
|
|
|
let t = modalActorFocusStack[modalActorFocusStack.length - 1];
|
2013-01-02 14:13:24 +00:00
|
|
|
if (t.prevFocus)
|
|
|
|
t.prevFocus.disconnect(t.prevFocusDestroyId);
|
2011-02-24 22:29:20 +00:00
|
|
|
// Remove from the middle, shift the focus chain up
|
|
|
|
for (let i = modalActorFocusStack.length - 1; i > focusIndex; i--) {
|
2013-01-02 14:13:24 +00:00
|
|
|
modalActorFocusStack[i].prevFocus = modalActorFocusStack[i - 1].prevFocus;
|
|
|
|
modalActorFocusStack[i].prevFocusDestroyId = modalActorFocusStack[i - 1].prevFocusDestroyId;
|
2014-12-11 14:35:40 +00:00
|
|
|
modalActorFocusStack[i].actionMode = modalActorFocusStack[i - 1].actionMode;
|
2009-09-15 19:53:07 +00:00
|
|
|
}
|
|
|
|
}
|
2011-02-24 22:29:20 +00:00
|
|
|
modalActorFocusStack.splice(focusIndex, 1);
|
|
|
|
|
2009-09-15 19:53:07 +00:00
|
|
|
if (modalCount > 0)
|
|
|
|
return;
|
|
|
|
|
2014-09-20 00:54:31 +00:00
|
|
|
layoutManager.modalEnded();
|
2010-10-20 19:08:14 +00:00
|
|
|
global.end_modal(timestamp);
|
2018-01-03 07:55:38 +00:00
|
|
|
Meta.enable_unredirect_for_display(global.display);
|
2014-12-11 14:35:40 +00:00
|
|
|
actionMode = Shell.ActionMode.NORMAL;
|
2008-10-31 04:22:44 +00:00
|
|
|
}
|
2008-11-24 19:07:18 +00:00
|
|
|
|
2009-08-02 07:46:01 +00:00
|
|
|
function createLookingGlass() {
|
2019-08-20 00:51:42 +00:00
|
|
|
if (lookingGlass == null)
|
2009-08-02 07:46:01 +00:00
|
|
|
lookingGlass = new LookingGlass.LookingGlass();
|
2019-08-20 00:51:42 +00:00
|
|
|
|
2009-08-02 07:46:01 +00:00
|
|
|
return lookingGlass;
|
|
|
|
}
|
|
|
|
|
2012-09-01 12:42:53 +00:00
|
|
|
function openRunDialog() {
|
2019-08-20 00:51:42 +00:00
|
|
|
if (runDialog == null)
|
2009-09-14 19:08:20 +00:00
|
|
|
runDialog = new RunDialog.RunDialog();
|
2019-08-20 00:51:42 +00:00
|
|
|
|
2012-09-01 12:42:53 +00:00
|
|
|
runDialog.open();
|
2009-09-14 19:08:20 +00:00
|
|
|
}
|
|
|
|
|
2021-02-01 09:20:48 +00:00
|
|
|
function openWelcomeDialog() {
|
|
|
|
if (welcomeDialog === null)
|
|
|
|
welcomeDialog = new WelcomeDialog.WelcomeDialog();
|
|
|
|
|
|
|
|
welcomeDialog.open();
|
|
|
|
}
|
|
|
|
|
2009-09-21 20:29:37 +00:00
|
|
|
/**
|
|
|
|
* activateWindow:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {Meta.Window} window: the window to activate
|
|
|
|
* @param {number=} time: current event time
|
|
|
|
* @param {number=} workspaceNum: window's workspace number
|
2009-09-21 20:29:37 +00:00
|
|
|
*
|
2010-02-17 19:05:06 +00:00
|
|
|
* Activates @window, switching to its workspace first if necessary,
|
|
|
|
* and switching out of the overview if it's currently active
|
2009-09-21 20:29:37 +00:00
|
|
|
*/
|
2010-02-19 16:42:36 +00:00
|
|
|
function activateWindow(window, time, workspaceNum) {
|
2018-01-03 07:55:38 +00:00
|
|
|
let workspaceManager = global.workspace_manager;
|
|
|
|
let activeWorkspaceNum = workspaceManager.get_active_workspace_index();
|
2019-08-19 19:38:51 +00:00
|
|
|
let windowWorkspaceNum = workspaceNum !== undefined ? workspaceNum : window.get_workspace().index();
|
2009-09-21 20:29:37 +00:00
|
|
|
|
|
|
|
if (!time)
|
2009-12-03 20:59:52 +00:00
|
|
|
time = global.get_current_time();
|
2009-09-21 20:29:37 +00:00
|
|
|
|
|
|
|
if (windowWorkspaceNum != activeWorkspaceNum) {
|
2018-01-03 07:55:38 +00:00
|
|
|
let workspace = workspaceManager.get_workspace_by_index(windowWorkspaceNum);
|
2009-09-21 20:29:37 +00:00
|
|
|
workspace.activate_with_focus(window, time);
|
|
|
|
} else {
|
|
|
|
window.activate(time);
|
|
|
|
}
|
2010-02-17 19:05:06 +00:00
|
|
|
|
|
|
|
overview.hide();
|
2015-02-23 12:02:08 +00:00
|
|
|
panel.closeCalendar();
|
2009-09-21 20:29:37 +00:00
|
|
|
}
|
2009-12-03 17:19:38 +00:00
|
|
|
|
|
|
|
// TODO - replace this timeout with some system to guess when the user might
|
|
|
|
// be e.g. just reading the screen and not likely to interact.
|
2017-07-18 17:47:27 +00:00
|
|
|
var DEFERRED_TIMEOUT_SECONDS = 20;
|
2009-12-03 17:19:38 +00:00
|
|
|
var _deferredWorkData = {};
|
|
|
|
// Work scheduled for some point in the future
|
|
|
|
var _deferredWorkQueue = [];
|
|
|
|
// Work we need to process before the next redraw
|
|
|
|
var _beforeRedrawQueue = [];
|
|
|
|
// Counter to assign work ids
|
|
|
|
var _deferredWorkSequence = 0;
|
|
|
|
var _deferredTimeoutId = 0;
|
|
|
|
|
|
|
|
function _runDeferredWork(workId) {
|
|
|
|
if (!_deferredWorkData[workId])
|
|
|
|
return;
|
|
|
|
let index = _deferredWorkQueue.indexOf(workId);
|
|
|
|
if (index < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
_deferredWorkQueue.splice(index, 1);
|
|
|
|
_deferredWorkData[workId].callback();
|
|
|
|
if (_deferredWorkQueue.length == 0 && _deferredTimeoutId > 0) {
|
2019-08-19 18:50:33 +00:00
|
|
|
GLib.source_remove(_deferredTimeoutId);
|
2009-12-03 17:19:38 +00:00
|
|
|
_deferredTimeoutId = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function _runAllDeferredWork() {
|
|
|
|
while (_deferredWorkQueue.length > 0)
|
|
|
|
_runDeferredWork(_deferredWorkQueue[0]);
|
|
|
|
}
|
|
|
|
|
|
|
|
function _runBeforeRedrawQueue() {
|
|
|
|
for (let i = 0; i < _beforeRedrawQueue.length; i++) {
|
|
|
|
let workId = _beforeRedrawQueue[i];
|
|
|
|
_runDeferredWork(workId);
|
|
|
|
}
|
|
|
|
_beforeRedrawQueue = [];
|
|
|
|
}
|
|
|
|
|
|
|
|
function _queueBeforeRedraw(workId) {
|
|
|
|
_beforeRedrawQueue.push(workId);
|
|
|
|
if (_beforeRedrawQueue.length == 1) {
|
2017-10-31 00:38:18 +00:00
|
|
|
Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => {
|
2009-12-03 17:19:38 +00:00
|
|
|
_runBeforeRedrawQueue();
|
|
|
|
return false;
|
2010-04-12 22:05:50 +00:00
|
|
|
});
|
2009-12-03 17:19:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* initializeDeferredWork:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {Clutter.Actor} actor: an actor
|
|
|
|
* @param {callback} callback: Function to invoke to perform work
|
2009-12-03 17:19:38 +00:00
|
|
|
*
|
|
|
|
* This function sets up a callback to be invoked when either the
|
|
|
|
* given actor is mapped, or after some period of time when the machine
|
2019-06-26 10:54:09 +00:00
|
|
|
* is idle. This is useful if your actor isn't always visible on the
|
2009-12-03 17:19:38 +00:00
|
|
|
* screen (for example, all actors in the overview), and you don't want
|
|
|
|
* to consume resources updating if the actor isn't actually going to be
|
|
|
|
* displaying to the user.
|
|
|
|
*
|
|
|
|
* Note that queueDeferredWork is called by default immediately on
|
|
|
|
* initialization as well, under the assumption that new actors
|
|
|
|
* will need it.
|
|
|
|
*
|
2019-10-17 16:41:52 +00:00
|
|
|
* @returns {string}: A string work identifier
|
2009-12-03 17:19:38 +00:00
|
|
|
*/
|
2019-02-04 11:30:53 +00:00
|
|
|
function initializeDeferredWork(actor, callback) {
|
2009-12-03 17:19:38 +00:00
|
|
|
// Turn into a string so we can use as an object property
|
2020-02-14 15:10:34 +00:00
|
|
|
let workId = (++_deferredWorkSequence).toString();
|
2019-08-19 19:06:04 +00:00
|
|
|
_deferredWorkData[workId] = { actor,
|
|
|
|
callback };
|
2017-10-31 00:38:18 +00:00
|
|
|
actor.connect('notify::mapped', () => {
|
2018-07-14 20:56:22 +00:00
|
|
|
if (!(actor.mapped && _deferredWorkQueue.includes(workId)))
|
2009-12-03 17:19:38 +00:00
|
|
|
return;
|
|
|
|
_queueBeforeRedraw(workId);
|
|
|
|
});
|
2017-10-31 00:38:18 +00:00
|
|
|
actor.connect('destroy', () => {
|
2009-12-03 17:19:38 +00:00
|
|
|
let index = _deferredWorkQueue.indexOf(workId);
|
|
|
|
if (index >= 0)
|
|
|
|
_deferredWorkQueue.splice(index, 1);
|
|
|
|
delete _deferredWorkData[workId];
|
|
|
|
});
|
|
|
|
queueDeferredWork(workId);
|
|
|
|
return workId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* queueDeferredWork:
|
2019-10-17 16:41:52 +00:00
|
|
|
* @param {string} workId: work identifier
|
2009-12-03 17:19:38 +00:00
|
|
|
*
|
|
|
|
* Ensure that the work identified by @workId will be
|
2019-06-26 10:54:09 +00:00
|
|
|
* run on map or timeout. You should call this function
|
2009-12-03 17:19:38 +00:00
|
|
|
* for example when data being displayed by the actor has
|
|
|
|
* changed.
|
|
|
|
*/
|
|
|
|
function queueDeferredWork(workId) {
|
|
|
|
let data = _deferredWorkData[workId];
|
|
|
|
if (!data) {
|
2012-05-10 01:37:42 +00:00
|
|
|
let message = 'Invalid work id %d'.format(workId);
|
|
|
|
logError(new Error(message), message);
|
2009-12-03 17:19:38 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-07-14 20:56:22 +00:00
|
|
|
if (!_deferredWorkQueue.includes(workId))
|
2009-12-03 17:19:38 +00:00
|
|
|
_deferredWorkQueue.push(workId);
|
|
|
|
if (data.actor.mapped) {
|
|
|
|
_queueBeforeRedraw(workId);
|
|
|
|
} else if (_deferredTimeoutId == 0) {
|
2019-08-19 18:50:33 +00:00
|
|
|
_deferredTimeoutId = GLib.timeout_add_seconds(GLib.PRIORITY_DEFAULT, DEFERRED_TIMEOUT_SECONDS, () => {
|
2009-12-03 17:19:38 +00:00
|
|
|
_runAllDeferredWork();
|
|
|
|
_deferredTimeoutId = 0;
|
2013-11-29 00:45:39 +00:00
|
|
|
return GLib.SOURCE_REMOVE;
|
2009-12-03 17:19:38 +00:00
|
|
|
});
|
2014-04-10 17:26:52 +00:00
|
|
|
GLib.Source.set_name_by_id(_deferredTimeoutId, '[gnome-shell] _runAllDeferredWork');
|
2009-12-03 17:19:38 +00:00
|
|
|
}
|
|
|
|
}
|
2014-05-08 22:56:23 +00:00
|
|
|
|
2019-05-23 20:45:44 +00:00
|
|
|
var RestartMessage = GObject.registerClass(
|
|
|
|
class RestartMessage extends ModalDialog.ModalDialog {
|
|
|
|
_init(message) {
|
|
|
|
super._init({ shellReactive: true,
|
|
|
|
styleClass: 'restart-message headline',
|
|
|
|
shouldFadeIn: false,
|
|
|
|
destroyOnClose: true });
|
2014-05-08 22:56:23 +00:00
|
|
|
|
2019-10-21 18:44:00 +00:00
|
|
|
let label = new St.Label({
|
|
|
|
text: message,
|
|
|
|
x_align: Clutter.ActorAlign.CENTER,
|
|
|
|
y_align: Clutter.ActorAlign.CENTER,
|
|
|
|
});
|
2014-05-08 22:56:23 +00:00
|
|
|
|
2019-10-21 18:44:00 +00:00
|
|
|
this.contentLayout.add_child(label);
|
2014-05-08 22:56:23 +00:00
|
|
|
this.buttonLayout.hide();
|
|
|
|
}
|
2019-05-23 20:45:44 +00:00
|
|
|
});
|
2014-05-08 22:56:23 +00:00
|
|
|
|
|
|
|
function showRestartMessage(message) {
|
|
|
|
let restartMessage = new RestartMessage(message);
|
|
|
|
restartMessage.open();
|
|
|
|
}
|
2019-10-01 10:02:31 +00:00
|
|
|
|
|
|
|
var AnimationsSettings = class {
|
|
|
|
constructor() {
|
2020-04-21 16:04:56 +00:00
|
|
|
let backend = global.backend;
|
2019-10-01 10:02:31 +00:00
|
|
|
if (!backend.is_rendering_hardware_accelerated()) {
|
|
|
|
St.Settings.get().inhibit_animations();
|
|
|
|
return;
|
|
|
|
}
|
2019-10-01 10:03:52 +00:00
|
|
|
|
|
|
|
let isXvnc = Shell.util_has_x11_display_extension(
|
|
|
|
global.display, 'VNC-EXTENSION');
|
|
|
|
if (isXvnc) {
|
|
|
|
St.Settings.get().inhibit_animations();
|
|
|
|
return;
|
|
|
|
}
|
2019-10-01 10:04:52 +00:00
|
|
|
|
|
|
|
let remoteAccessController = backend.get_remote_access_controller();
|
|
|
|
if (!remoteAccessController)
|
|
|
|
return;
|
|
|
|
|
|
|
|
this._handles = new Set();
|
|
|
|
remoteAccessController.connect('new-handle',
|
|
|
|
(_, handle) => this._onNewRemoteAccessHandle(handle));
|
|
|
|
}
|
|
|
|
|
|
|
|
_onRemoteAccessHandleStopped(handle) {
|
|
|
|
let settings = St.Settings.get();
|
|
|
|
|
|
|
|
settings.uninhibit_animations();
|
|
|
|
this._handles.delete(handle);
|
|
|
|
}
|
|
|
|
|
|
|
|
_onNewRemoteAccessHandle(handle) {
|
|
|
|
if (!handle.get_disable_animations())
|
|
|
|
return;
|
|
|
|
|
|
|
|
let settings = St.Settings.get();
|
|
|
|
|
|
|
|
settings.inhibit_animations();
|
|
|
|
this._handles.add(handle);
|
|
|
|
handle.connect('stopped', this._onRemoteAccessHandleStopped.bind(this));
|
2019-10-01 10:02:31 +00:00
|
|
|
}
|
|
|
|
};
|