8fb8f7f827
gjs now has an internal mainloop that it can spin to resolve module imports. That loop uses the thread default context, so its possible that other sources, namely from mutter, get dispatched when iterating the context. If that happens before mutter is properly initialized, this will lead to a crash. GjsContext needs to iterate its internal mainloop when initializing to resolve internal modules, to avoid iterating Meta's mainloop and triggering events before Meta is ready we will initialize the Shell global and thus the GjsContext (js_context) before Meta. Once GjsContext is initialized, we can call meta_context_setup(). Once Meta is setup and started, we'll run init.js which uses GJS' internal promises API to set a "mainloop hook". The mainloop hook is run immediately after the module returns so GJS will not attempt to iterate the main loop again before exiting. Also adjust the 'headlessStart' test to not wait for the MetaContext::started signal, as that signal has now already been emitted when the code is executed. https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6691 Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2781>
109 lines
2.7 KiB
JavaScript
109 lines
2.7 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
/* exported init, run, finish, script_monitorsChanged, script_overviewHideDone,
|
|
script_overviewShowDone, METRICS,
|
|
*/
|
|
/* eslint camelcase: ["error", { properties: "never", allow: ["^script_"] }] */
|
|
|
|
const {GLib, MetaTest, Shell} = imports.gi;
|
|
|
|
const Main = imports.ui.main;
|
|
const Scripting = imports.ui.scripting;
|
|
|
|
// This script tests that the shell handles connecting monitors after startup
|
|
// is properly handled.
|
|
|
|
var METRICS = {};
|
|
|
|
let _testMonitor = null;
|
|
|
|
/**
|
|
* init:
|
|
*/
|
|
function init() {
|
|
global.connect('shutdown', () => {
|
|
_testMonitor?.destroy();
|
|
});
|
|
GLib.timeout_add_seconds(
|
|
GLib.PRIORITY_LOW, 2,
|
|
() => {
|
|
log('Connecting 1280x720 test monitor');
|
|
_testMonitor = MetaTest.TestMonitor.new(
|
|
global.context, 1280, 720, 60.0);
|
|
});
|
|
Scripting.defineScriptEvent('monitorsChanged', 'Monitors changed');
|
|
|
|
const display = global.display;
|
|
console.assert(display.get_n_monitors() === 0, 'Not running headless');
|
|
|
|
const monitorManager = global.backend.get_monitor_manager();
|
|
const monitorsChangedHandlerId = monitorManager.connect('monitors-changed',
|
|
() => {
|
|
console.assert(display.get_n_monitors() === 1,
|
|
'Expected a single monitor');
|
|
Scripting.scriptEvent('monitorsChanged');
|
|
monitorManager.disconnect(monitorsChangedHandlerId);
|
|
});
|
|
Shell.PerfLog.get_default().set_enabled(true);
|
|
}
|
|
|
|
/**
|
|
* run:
|
|
*/
|
|
async function run() {
|
|
/* eslint-disable no-await-in-loop */
|
|
Scripting.defineScriptEvent('overviewShowDone', 'Overview finished showing');
|
|
Scripting.defineScriptEvent('overviewHideDone', 'Overview finished hiding');
|
|
|
|
Main.overview.connect('shown',
|
|
() => Scripting.scriptEvent('overviewShowDone'));
|
|
Main.overview.connect('hidden',
|
|
() => Scripting.scriptEvent('overviewHideDone'));
|
|
|
|
Main.overview.hide();
|
|
await Scripting.waitLeisure();
|
|
|
|
Main.overview.show();
|
|
await Scripting.waitLeisure();
|
|
|
|
/* eslint-enable no-await-in-loop */
|
|
}
|
|
|
|
let monitorsChanged = false;
|
|
let overviewHidden = false;
|
|
let overviewShown = false;
|
|
|
|
/**
|
|
* script_monitorsChanged:
|
|
*/
|
|
function script_monitorsChanged() {
|
|
monitorsChanged = true;
|
|
}
|
|
|
|
/**
|
|
* script_overviewHideDone:
|
|
*/
|
|
function script_overviewHideDone() {
|
|
overviewHidden = true;
|
|
}
|
|
|
|
/**
|
|
* script_overviewShowDone:
|
|
*/
|
|
function script_overviewShowDone() {
|
|
overviewShown = true;
|
|
}
|
|
|
|
/**
|
|
* finish:
|
|
*/
|
|
function finish() {
|
|
if (!monitorsChanged)
|
|
throw new Error('Monitors never changed');
|
|
|
|
if (!overviewHidden)
|
|
throw new Error('Failed to hide overview');
|
|
|
|
if (!overviewShown)
|
|
throw new Error('Failed to show overview');
|
|
}
|