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