screenshot: Move HAVE_RECORDER check into screencast service
Some gstreamer plugins require a connection to the display server, so if we end up initializing gstreamer before we are ourselves fully initialized, we may end up with a locked compositor. Avoid this by moving the runtime recorder check into the screencast D-Bus service, so that all gstreamer calls happen out of process. https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5710 Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2519>
This commit is contained in:
parent
cff56d4b03
commit
f266c2ca15
@ -10,6 +10,7 @@
|
||||
The interface used to record screen contents.
|
||||
-->
|
||||
<interface name="org.gnome.Shell.Screencast">
|
||||
<property name="ScreencastSupported" type="b" access="read"/>
|
||||
|
||||
<!--
|
||||
Screencast:
|
||||
|
@ -1,13 +1,12 @@
|
||||
/* exported main */
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const {DBusService} = imports.dbusService;
|
||||
|
||||
function main() {
|
||||
if (!Config.HAVE_RECORDER)
|
||||
const {ScreencastService} = imports.screencastService;
|
||||
if (!ScreencastService.canScreencast())
|
||||
return;
|
||||
|
||||
const { ScreencastService } = imports.screencastService;
|
||||
const service = new DBusService(
|
||||
'org.gnome.Shell.Screencast',
|
||||
new ScreencastService());
|
||||
|
@ -258,9 +258,17 @@ var Recorder = class {
|
||||
};
|
||||
|
||||
var ScreencastService = class extends ServiceImplementation {
|
||||
static canScreencast() {
|
||||
return Gst.init_check(null) &&
|
||||
Gst.ElementFactory.find('pipewiresrc') &&
|
||||
Gst.ElementFactory.find('filesink');
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super(ScreencastIface, '/org/gnome/Shell/Screencast');
|
||||
|
||||
this._canScreencast = ScreencastService.canScreencast();
|
||||
|
||||
Gst.init(null);
|
||||
Gtk.init();
|
||||
|
||||
@ -280,6 +288,10 @@ var ScreencastService = class extends ServiceImplementation {
|
||||
'/org/gnome/Shell/Introspect');
|
||||
}
|
||||
|
||||
get ScreencastSupported() {
|
||||
return this._canScreencast;
|
||||
}
|
||||
|
||||
_removeRecorder(sender) {
|
||||
this._recorders.delete(sender);
|
||||
if (this._recorders.size === 0)
|
||||
|
@ -21,8 +21,3 @@ var LIBMUTTER_API_VERSION = '@LIBMUTTER_API_VERSION@'
|
||||
|
||||
var HAVE_BLUETOOTH = pkg.checkSymbol('GnomeBluetooth', '3.0',
|
||||
'Client.default_adapter_state')
|
||||
var HAVE_RECORDER =
|
||||
pkg.checkSymbol('Gst', '1.0') &&
|
||||
imports.gi.Gst.init_check(null) &&
|
||||
imports.gi.Gst.ElementFactory.find('pipewiresrc') &&
|
||||
imports.gi.Gst.ElementFactory.find('filesink');
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
const { Clutter, Cogl, Gio, GObject, GLib, Graphene, Gtk, Meta, Shell, St } = imports.gi;
|
||||
|
||||
const Config = imports.misc.config;
|
||||
const GrabHelper = imports.ui.grabHelper;
|
||||
const Layout = imports.ui.layout;
|
||||
const Lightbox = imports.ui.lightbox;
|
||||
@ -1019,6 +1018,19 @@ var ScreenshotUI = GObject.registerClass({
|
||||
|
||||
this._screencastInProgress = false;
|
||||
|
||||
this._screencastProxy = new ScreencastProxy(
|
||||
Gio.DBus.session,
|
||||
'org.gnome.Shell.Screencast',
|
||||
'/org/gnome/Shell/Screencast',
|
||||
(object, error) => {
|
||||
if (error !== null) {
|
||||
log('Error connecting to the screencast service');
|
||||
return;
|
||||
}
|
||||
|
||||
this._castButton.visible = this._screencastProxy.ScreencastSupported;
|
||||
});
|
||||
|
||||
this._lockdownSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.lockdown' });
|
||||
|
||||
// The full-screen screenshot has a separate container so that we can
|
||||
@ -1212,7 +1224,7 @@ var ScreenshotUI = GObject.registerClass({
|
||||
style_class: 'screenshot-ui-shot-cast-button',
|
||||
icon_name: 'camera-web-symbolic',
|
||||
toggle_mode: true,
|
||||
visible: Config.HAVE_RECORDER,
|
||||
visible: false,
|
||||
});
|
||||
this._castButton.connect('notify::checked',
|
||||
this._onCastButtonToggled.bind(this));
|
||||
@ -1438,7 +1450,7 @@ var ScreenshotUI = GObject.registerClass({
|
||||
if (this._screencastInProgress)
|
||||
return;
|
||||
|
||||
if (mode === UIMode.SCREENCAST && !Config.HAVE_RECORDER)
|
||||
if (mode === UIMode.SCREENCAST && !this._screencastProxy.ScreencastSupported)
|
||||
return;
|
||||
|
||||
this._castButton.checked = mode === UIMode.SCREENCAST;
|
||||
@ -1809,7 +1821,7 @@ var ScreenshotUI = GObject.registerClass({
|
||||
}
|
||||
}
|
||||
|
||||
_startScreencast() {
|
||||
async _startScreencast() {
|
||||
if (this._windowButton.checked)
|
||||
return; // TODO
|
||||
|
||||
@ -1833,7 +1845,6 @@ var ScreenshotUI = GObject.registerClass({
|
||||
this.close(true);
|
||||
|
||||
// This is a bit awkward because creating a proxy synchronously hangs Shell.
|
||||
const doStartScreencast = async () => {
|
||||
let method =
|
||||
this._screencastProxy.ScreencastAsync.bind(this._screencastProxy);
|
||||
if (w !== -1) {
|
||||
@ -1841,6 +1852,10 @@ var ScreenshotUI = GObject.registerClass({
|
||||
this._screencastProxy, x, y, w, h);
|
||||
}
|
||||
|
||||
// Set this before calling the method as the screen recording indicator
|
||||
// will check it before the success callback fires.
|
||||
this._setScreencastInProgress(true);
|
||||
|
||||
try {
|
||||
const [success, path] = await method(
|
||||
GLib.build_filenamev([
|
||||
@ -1865,30 +1880,6 @@ var ScreenshotUI = GObject.registerClass({
|
||||
else
|
||||
log('Error starting screencast');
|
||||
}
|
||||
};
|
||||
|
||||
// Set this before calling the method as the screen recording indicator
|
||||
// will check it before the success callback fires.
|
||||
this._setScreencastInProgress(true);
|
||||
|
||||
if (this._screencastProxy) {
|
||||
doStartScreencast();
|
||||
} else {
|
||||
new ScreencastProxy(
|
||||
Gio.DBus.session,
|
||||
'org.gnome.Shell.Screencast',
|
||||
'/org/gnome/Shell/Screencast',
|
||||
(object, error) => {
|
||||
if (error !== null) {
|
||||
log('Error connecting to the screencast service');
|
||||
return;
|
||||
}
|
||||
|
||||
this._screencastProxy = object;
|
||||
doStartScreencast();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async stopScreencast() {
|
||||
|
Loading…
Reference in New Issue
Block a user