screenshot: Promisify SelectArea

The screenshot code has a fair bit of nested callbacks, which means
that it is a good use case for async functions and Promises.

Most code uses GIO's async pattern, which means it can be easily turned
into promises with Gio._promisify(); first handle the couple of cases
that need custom code though, starting with SelectArea.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/903
This commit is contained in:
Florian Müllner 2019-12-19 03:39:39 +01:00
parent 93fa1034f5
commit 9db62236da

View File

@ -227,20 +227,19 @@ var ScreenshotService = class {
});
}
SelectAreaAsync(params, invocation) {
async SelectAreaAsync(params, invocation) {
let selectArea = new SelectArea();
selectArea.show();
selectArea.connect('finished', (o, areaRectangle) => {
if (areaRectangle) {
let retRectangle = this._unscaleArea(areaRectangle.x, areaRectangle.y,
areaRectangle.width, areaRectangle.height);
let retval = GLib.Variant.new('(iiii)', retRectangle);
invocation.return_value(retval);
} else {
invocation.return_error_literal(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
"Operation was cancelled");
}
});
try {
let areaRectangle = await selectArea.selectAsync();
let retRectangle = this._unscaleArea(
areaRectangle.x, areaRectangle.y,
areaRectangle.width, areaRectangle.height);
invocation.return_value(GLib.Variant.new('(iiii)', retRectangle));
} catch (e) {
invocation.return_error_literal(
Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED,
'Operation was cancelled');
}
}
FlashAreaAsync(params, invocation) {
@ -286,9 +285,8 @@ var ScreenshotService = class {
}
};
var SelectArea = GObject.registerClass({
Signals: { 'finished': { param_types: [Meta.Rectangle.$gtype] } },
}, class SelectArea extends St.Widget {
var SelectArea = GObject.registerClass(
class SelectArea extends St.Widget {
_init() {
this._startX = -1;
this._startY = -1;
@ -317,14 +315,21 @@ var SelectArea = GObject.registerClass({
this.add_actor(this._rubberband);
}
vfunc_show() {
if (!this._grabHelper.grab({ actor: this,
onUngrab: this._onUngrab.bind(this) }))
return;
async selectAsync() {
global.display.set_cursor(Meta.Cursor.CROSSHAIR);
Main.uiGroup.set_child_above_sibling(this, null);
super.vfunc_show();
this.show();
await this._grabHelper.grabAsync({ actor: this });
global.display.set_cursor(Meta.Cursor.DEFAULT);
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.destroy();
return GLib.SOURCE_REMOVE;
});
return this._result;
}
_getGeometry() {
@ -371,16 +376,6 @@ var SelectArea = GObject.registerClass({
});
return Clutter.EVENT_PROPAGATE;
}
_onUngrab() {
global.display.set_cursor(Meta.Cursor.DEFAULT);
this.emit('finished', this._result);
GLib.idle_add(GLib.PRIORITY_DEFAULT, () => {
this.destroy();
return GLib.SOURCE_REMOVE;
});
}
});
var PickPixel = GObject.registerClass({