[gnome-sound-recorder/bilelmoussaoui/fixes: 10/12] handle closing the window more carefully




commit d65d38ac5745d17177baa76498b1b5763bd13446
Author: Bilal Elmoussaoui <bil elmoussaoui gmail com>
Date:   Wed Sep 9 05:05:18 2020 +0200

    handle closing the window more carefully
    
    cancel copying old recordings, generating the waveforms

 src/application.js   |   6 ++-
 src/recording.js     |  14 ++++---
 src/recordingList.js | 111 +++++++++++++++++++++++++++++----------------------
 src/window.js        |  23 +++++++----
 4 files changed, 91 insertions(+), 63 deletions(-)
---
diff --git a/src/application.js b/src/application.js
index 2d9249d..78a9cca 100644
--- a/src/application.js
+++ b/src/application.js
@@ -61,7 +61,9 @@ var Application = GObject.registerClass(class Application extends Gtk.Applicatio
         this.add_action(aboutAction);
 
         let quitAction = new Gio.SimpleAction({ name: 'quit' });
-        quitAction.connect('activate', this.quit.bind(this));
+        quitAction.connect('activate', () => {
+            this.get_active_window().close();
+        });
         this.add_action(quitAction);
 
         this.add_accelerator('<Primary>q', 'app.quit', null);
@@ -88,8 +90,8 @@ var Application = GObject.registerClass(class Application extends Gtk.Applicatio
         Gst.init(null);
 
         try {
-            RecordingsDir.make_directory_with_parents(null);
             CacheDir.make_directory_with_parents(null);
+            RecordingsDir.make_directory_with_parents(null);
         } catch (e) {
             if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.EXISTS))
                 error(`Failed to create directory ${e}`);
diff --git a/src/recording.js b/src/recording.js
index d234b6d..ac3ac3e 100644
--- a/src/recording.js
+++ b/src/recording.js
@@ -143,17 +143,18 @@ var Recording = new GObject.registerClass({
     }
 
     generatePeaks() {
-        const pipeline = Gst.parse_launch('uridecodebin name=uridecodebin ! audioconvert ! 
audio/x-raw,channels=1 ! level name=level ! fakesink name=faked');
+        this.pipeline = Gst.parse_launch('uridecodebin name=uridecodebin ! audioconvert ! 
audio/x-raw,channels=1 ! level name=level ! fakesink name=faked');
 
-        let uridecodebin = pipeline.get_by_name('uridecodebin');
+
+        let uridecodebin = this.pipeline.get_by_name('uridecodebin');
         uridecodebin.set_property('uri', this.uri);
 
-        let fakesink = pipeline.get_by_name('faked');
+        let fakesink = this.pipeline.get_by_name('faked');
         fakesink.set_property('qos', false);
         fakesink.set_property('sync', true);
 
-        const bus = pipeline.get_bus();
-        pipeline.set_state(Gst.State.PLAYING);
+        const bus = this.pipeline.get_bus();
+        this.pipeline.set_state(Gst.State.PLAYING);
         bus.add_signal_watch();
 
         bus.connect('message', (_bus, message) => {
@@ -172,7 +173,8 @@ var Recording = new GObject.registerClass({
                 break;
             case Gst.MessageType.EOS:
                 this.peaks = this._loadedPeaks;
-                pipeline.set_state(Gst.State.NULL);
+                this.pipeline.set_state(Gst.State.NULL);
+                this.pipeline = null;
                 break;
             }
         });
diff --git a/src/recordingList.js b/src/recordingList.js
index a17bc05..f747ab7 100644
--- a/src/recordingList.js
+++ b/src/recordingList.js
@@ -8,8 +8,9 @@ var RecordingList = new GObject.registerClass(class RecordingList extends Gio.Li
     _init() {
         super._init({ });
 
+        this.cancellable = new Gio.Cancellable();
         // Monitor Direcotry actions
-        this.dirMonitor = RecordingsDir.monitor_directory(Gio.FileMonitorFlags.WATCH_MOVES, null);
+        this.dirMonitor = RecordingsDir.monitor_directory(Gio.FileMonitorFlags.WATCH_MOVES, 
this.cancellable);
         this.dirMonitor.connect('changed', (_dirMonitor, file1, file2, eventType) => {
             const index = this.getIndex(file1);
 
@@ -29,7 +30,7 @@ var RecordingList = new GObject.registerClass(class RecordingList extends Gio.Li
         RecordingsDir.enumerate_children_async('standard::name',
             Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
             GLib.PRIORITY_LOW,
-            null,
+            this.cancellable,
             this._enumerateDirectory.bind(this));
 
         this.copyOldFiles();
@@ -40,51 +41,59 @@ var RecordingList = new GObject.registerClass(class RecordingList extends Gio.Li
         // FIXME: Remove by 3.40/3.42
         const oldDir = Gio.file_new_for_path(GLib.build_filenamev([GLib.get_home_dir(), _('Recordings')]));
 
-        if (!oldDir.query_exists(null))
+        if (!oldDir.query_exists(this.cancellable))
             return;
 
-        const fileEnumerator = oldDir.enumerate_children('standard::name', 
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
+        const fileEnumerator = oldDir.enumerate_children('standard::name', 
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, this.cancellable);
         let allCopied = true;
 
         const copyFiles = function (obj, res) {
-            const fileInfos = obj.next_files_finish(res);
-            if (fileInfos.length) {
-                fileInfos.forEach(info => {
-                    const name = info.get_name();
-                    const src = oldDir.get_child(name);
-                    /* Translators: ""%s (Old)"" is the new name assigned to a file moved from
-                        the old recordings location */
-                    const dest = RecordingsDir.get_child(_('%s (Old)').format(name));
-
-                    src.copy_async(dest, Gio.FileCopyFlags.BACKUP, GLib.PRIORITY_LOW, null, null, (objCopy, 
resCopy) => {
-                        try {
-                            objCopy.copy_finish(resCopy);
-                            objCopy.trash_async(GLib.PRIORITY_LOW, null, null);
-                            this.dirMonitor.emit_event(dest, src, Gio.FileMonitorEvent.MOVED_IN);
-                        } catch (e) {
-                            log(`Failed to copy recording ${name} to the new location`);
-                            log(e);
-                            allCopied = false;
-                        }
-                    });
+            try {
+                const fileInfos = obj.next_files_finish(res);
+                if (fileInfos.length) {
+                    fileInfos.forEach(info => {
+                        const name = info.get_name();
+                        const src = oldDir.get_child(name);
+                        /* Translators: ""%s (Old)"" is the new name assigned to a file moved from
+                            the old recordings location */
+                        const dest = RecordingsDir.get_child(_('%s (Old)').format(name));
+
+                        src.copy_async(dest, Gio.FileCopyFlags.OVERWRITE, GLib.PRIORITY_LOW, 
this.cancellable, null, (objCopy, resCopy) => {
+                            try {
+                                objCopy.copy_finish(resCopy);
+                                objCopy.trash_async(GLib.PRIORITY_LOW, this.cancellable, null);
+                                this.dirMonitor.emit_event(dest, src, Gio.FileMonitorEvent.MOVED_IN);
+                            } catch (e) {
+                                if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED)) {
+                                    error(`Failed to copy recording ${name} to the new location`);
+                                    log(e);
+                                }
+                                allCopied = false;
+                            }
+                        });
 
-                });
-                fileEnumerator.next_files_async(5, GLib.PRIORITY_LOW, null, copyFiles);
-            } else {
-                fileEnumerator.close(null);
-                if (allCopied) {
-                    oldDir.delete_async(GLib.PRIORITY_LOW, null, (objDelete, resDelete) => {
-                        try {
-                            objDelete.delete_finish(resDelete);
-                        } catch (e) {
-                            log('Failed to remove the old Recordings directory. Ignore if you\'re using 
flatpak');
-                            log(e);
-                        }
                     });
+                    fileEnumerator.next_files_async(5, GLib.PRIORITY_LOW, this.cancellable, copyFiles);
+                } else {
+                    fileEnumerator.close(this.cancellable);
+                    if (allCopied) {
+                        oldDir.delete_async(GLib.PRIORITY_LOW, this.cancellable, (objDelete, resDelete) => {
+                            try {
+                                objDelete.delete_finish(resDelete);
+                            } catch (e) {
+                                log('Failed to remove the old Recordings directory. Ignore if you\'re using 
flatpak');
+                                log(e);
+                            }
+                        });
+                    }
                 }
+            } catch (e) {
+                if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+                    error(`Failed to copy old  recordings ${e}`);
+
             }
         }.bind(this);
-        fileEnumerator.next_files_async(5, GLib.PRIORITY_LOW, null, copyFiles);
+        fileEnumerator.next_files_async(5, GLib.PRIORITY_LOW, this.cancellable, copyFiles);
     }
 
     _enumerateDirectory(obj, res) {
@@ -93,20 +102,26 @@ var RecordingList = new GObject.registerClass(class RecordingList extends Gio.Li
             log('The contents of the Recordings directory were not indexed.');
             return;
         }
-        this._enumerator.next_files_async(5, GLib.PRIORITY_LOW, null, this._onNextFiles.bind(this));
+        this._enumerator.next_files_async(5, GLib.PRIORITY_LOW, this.cancellable, 
this._onNextFiles.bind(this));
     }
 
     _onNextFiles(obj, res) {
-        let fileInfos = obj.next_files_finish(res);
-        if (fileInfos.length) {
-            fileInfos.forEach(info => {
-                const file = RecordingsDir.get_child(info.get_name());
-                const recording = new Recording(file);
-                this.sortedInsert(recording);
-            });
-            this._enumerator.next_files_async(5, GLib.PRIORITY_LOW, null, this._onNextFiles.bind(this));
-        } else {
-            this._enumerator.close(null);
+        try {
+            let fileInfos = obj.next_files_finish(res);
+            if (fileInfos.length) {
+                fileInfos.forEach(info => {
+                    const file = RecordingsDir.get_child(info.get_name());
+                    const recording = new Recording(file);
+                    this.sortedInsert(recording);
+                });
+                this._enumerator.next_files_async(5, GLib.PRIORITY_LOW, this.cancellable, 
this._onNextFiles.bind(this));
+            } else {
+                this._enumerator.close(this.cancellable);
+            }
+        } catch (e) {
+            if (!e.matches(Gio.IOErrorEnum, Gio.IOErrorEnum.CANCELLED))
+                error(`Failed to load recordings ${e}`);
+
         }
     }
 
diff --git a/src/window.js b/src/window.js
index 4dc0c41..4ab0417 100644
--- a/src/window.js
+++ b/src/window.js
@@ -18,7 +18,7 @@
 *
 */
 
-const { GLib, GObject, GstPlayer, Handy } = imports.gi;
+const { GLib, GObject, Gst, GstPlayer, Handy } = imports.gi;
 
 const { Recorder } = imports.recorder;
 const { RecordingList } = imports.recordingList;
@@ -54,13 +54,8 @@ var Window = GObject.registerClass({
         this.player.connect('end-of-stream', _p => this.player.stop());
 
 
-        this.connect('destroy', () => {
-            this.player.stop();
-            this.recorder.stop();
-        });
-
         this._recordingList = new RecordingList();
-        this._recordingList.connect('items-changed', _ => {
+        this.itemsSignalId = this._recordingList.connect('items-changed', _ => {
             if (this.state !== WindowState.RECORDER) {
                 if (this._recordingList.get_n_items() === 0)
                     this.state = WindowState.EMPTY;
@@ -97,6 +92,20 @@ var Window = GObject.registerClass({
         this.show();
     }
 
+    vfunc_delete_event() {
+        this._recordingList.cancellable.cancel();
+        if (this.itemsSignalId)
+            this._recordingList.disconnect(this.itemsSignalId);
+
+        for (let i = 0; i < this._recordingList.get_n_items(); i++) {
+            const recording = this._recordingList.get_item(i);
+            if (recording.pipeline)
+                recording.pipeline.set_state(Gst.State.NULL);
+        }
+
+        this.recorder.stop();
+    }
+
     onRecorderStarted() {
         this.player.stop();
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]