From 9db62236da5021b0f4cd062fe3d3e9a39f64c4b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 19 Dec 2019 03:39:39 +0100 Subject: [PATCH] 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 --- js/ui/screenshot.js | 59 +++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 32 deletions(-) diff --git a/js/ui/screenshot.js b/js/ui/screenshot.js index fab8ed7e4..e2526ebdb 100644 --- a/js/ui/screenshot.js +++ b/js/ui/screenshot.js @@ -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({