screenshot-ui: Add area and screen recording
It works by passing the selected area to org.gnome.Shell.ScreencastArea. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2103>
This commit is contained in:
parent
6d0c2ae697
commit
003eb4c4e0
@ -27,6 +27,9 @@ const { DBusSenderChecker } = imports.misc.util;
|
|||||||
|
|
||||||
const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot');
|
const ScreenshotIface = loadInterfaceXML('org.gnome.Shell.Screenshot');
|
||||||
|
|
||||||
|
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
|
||||||
|
const ScreencastProxy = Gio.DBusProxy.makeProxyWrapper(ScreencastIface);
|
||||||
|
|
||||||
var IconLabelButton = GObject.registerClass(
|
var IconLabelButton = GObject.registerClass(
|
||||||
class IconLabelButton extends St.Button {
|
class IconLabelButton extends St.Button {
|
||||||
_init(iconName, label, params) {
|
_init(iconName, label, params) {
|
||||||
@ -1332,6 +1335,9 @@ var ScreenshotUI = GObject.registerClass({
|
|||||||
if (this._openingCoroutineInProgress)
|
if (this._openingCoroutineInProgress)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (this._screencastInProgress)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!this.visible) {
|
if (!this.visible) {
|
||||||
// Screenshot UI is opening from completely closed state
|
// Screenshot UI is opening from completely closed state
|
||||||
// (rather than opening back from in process of closing).
|
// (rather than opening back from in process of closing).
|
||||||
@ -1601,7 +1607,7 @@ var ScreenshotUI = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_getSelectedGeometry() {
|
_getSelectedGeometry(rescale) {
|
||||||
let x, y, w, h;
|
let x, y, w, h;
|
||||||
|
|
||||||
if (this._selectionButton.checked) {
|
if (this._selectionButton.checked) {
|
||||||
@ -1617,21 +1623,24 @@ var ScreenshotUI = GObject.registerClass({
|
|||||||
h = monitor.height;
|
h = monitor.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
x *= this._scale;
|
if (rescale) {
|
||||||
y *= this._scale;
|
x *= this._scale;
|
||||||
w *= this._scale;
|
y *= this._scale;
|
||||||
h *= this._scale;
|
w *= this._scale;
|
||||||
|
h *= this._scale;
|
||||||
|
}
|
||||||
|
|
||||||
return [x, y, w, h];
|
return [x, y, w, h];
|
||||||
}
|
}
|
||||||
|
|
||||||
_onCaptureButtonClicked() {
|
_onCaptureButtonClicked() {
|
||||||
if (this._shotButton.checked)
|
if (this._shotButton.checked) {
|
||||||
this._saveScreenshot();
|
this._saveScreenshot();
|
||||||
|
this.close();
|
||||||
// TODO: screencasting.
|
} else {
|
||||||
|
// Screencast closes the UI on its own.
|
||||||
this.close();
|
this._startScreencast();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_storeScreenshot(bytes, pixbuf) {
|
_storeScreenshot(bytes, pixbuf) {
|
||||||
@ -1773,7 +1782,7 @@ var ScreenshotUI = GObject.registerClass({
|
|||||||
const texture = content.get_texture();
|
const texture = content.get_texture();
|
||||||
const stream = Gio.MemoryOutputStream.new_resizable();
|
const stream = Gio.MemoryOutputStream.new_resizable();
|
||||||
|
|
||||||
const [x, y, w, h] = this._getSelectedGeometry();
|
const [x, y, w, h] = this._getSelectedGeometry(true);
|
||||||
|
|
||||||
let cursorTexture = this._cursor.content?.get_texture();
|
let cursorTexture = this._cursor.content?.get_texture();
|
||||||
if (!this._cursor.visible)
|
if (!this._cursor.visible)
|
||||||
@ -1830,6 +1839,71 @@ var ScreenshotUI = GObject.registerClass({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_startScreencast() {
|
||||||
|
if (this._windowButton.checked)
|
||||||
|
return; // TODO
|
||||||
|
|
||||||
|
const [x, y, w, h] = this._getSelectedGeometry(false);
|
||||||
|
const drawCursor = this._cursor.visible;
|
||||||
|
|
||||||
|
// Close instantly so the fade-out doesn't get recorded.
|
||||||
|
this.close(true);
|
||||||
|
|
||||||
|
// This is a bit awkward because creating a proxy synchronously hangs Shell.
|
||||||
|
const doStartScreencast = () => {
|
||||||
|
let method =
|
||||||
|
this._screencastProxy.ScreencastRemote.bind(this._screencastProxy);
|
||||||
|
if (w !== -1) {
|
||||||
|
method = this._screencastProxy.ScreencastAreaRemote.bind(
|
||||||
|
this._screencastProxy, x, y, w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
method(
|
||||||
|
/* Translators: this is a filename used for screencast
|
||||||
|
* recording, where "%d" and "%t" date and time, e.g.
|
||||||
|
* "Screencast from 07-17-2013 10:00:46 PM.webm" */
|
||||||
|
/* xgettext:no-c-format */
|
||||||
|
_('Screencast from %d %t.webm'),
|
||||||
|
{ 'draw-cursor': new GLib.Variant('b', drawCursor) },
|
||||||
|
([success, _filename], error) => {
|
||||||
|
if (error !== null) {
|
||||||
|
this._setScreencastInProgress(false);
|
||||||
|
log('Error starting screencast: %s'.format(error.message));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
this._setScreencastInProgress(false);
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stopScreencast() {
|
stopScreencast() {
|
||||||
if (!this._screencastInProgress)
|
if (!this._screencastInProgress)
|
||||||
return;
|
return;
|
||||||
@ -1837,6 +1911,16 @@ var ScreenshotUI = GObject.registerClass({
|
|||||||
// Set this before calling the method as the screen recording indicator
|
// Set this before calling the method as the screen recording indicator
|
||||||
// will check it before the success callback fires.
|
// will check it before the success callback fires.
|
||||||
this._setScreencastInProgress(false);
|
this._setScreencastInProgress(false);
|
||||||
|
|
||||||
|
this._screencastProxy.StopScreencastRemote((success, error) => {
|
||||||
|
if (error !== null) {
|
||||||
|
log('Error stopping screencast: %s'.format(error.message));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
log('Error stopping screencast');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get screencast_in_progress() {
|
get screencast_in_progress() {
|
||||||
|
Loading…
Reference in New Issue
Block a user