From d868124bc889c71146ccdbfc7b8dcbdad1c21d55 Mon Sep 17 00:00:00 2001 From: Dadoum Date: Thu, 19 Oct 2023 20:23:56 +0200 Subject: [PATCH] Fix the memory leak in adw.TimedAnimation, and disable i686 builds --- .github/workflows/build.yml | 2 ++ linux/gtk/ui/manageappidwindow.d | 20 ++++++++++++-- linux/gtk/ui/sideloadprogresswindow.d | 2 +- linux/gtk/ui/utils.d | 38 ++++++++++++++++++++------- source/server/developersession.d | 15 +++++++++++ 5 files changed, 64 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f60ca5b..3fe096f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,6 +41,8 @@ jobs: ${{github.workspace}}/bin/sideloader-x86_64.dbg build-i686: + # Does not work yet + if: false runs-on: ubuntu-22.04 steps: diff --git a/linux/gtk/ui/manageappidwindow.d b/linux/gtk/ui/manageappidwindow.d index 32f389a..c735ef6 100644 --- a/linux/gtk/ui/manageappidwindow.d +++ b/linux/gtk/ui/manageappidwindow.d @@ -41,9 +41,9 @@ class ManageAppIdWindow: Dialog { setBusy(true); new Thread({ auto team = session.listTeams().unwrap()[0]; - auto appIds = session.listAppIds!iOS(team).unwrap().appIds; + auto appIdsResponse = session.listAppIds!iOS(team).unwrap(); runInUIThread({ - foreach (appId; appIds) { + foreach (appId; appIdsResponse.appIds) { appIdListBox.append(new CertificateRow(this, session, team, appId)); } setBusy(false); @@ -112,6 +112,22 @@ class ManageAppIdWindow: Dialog { fileChooser.show(); }); this.addRow(downloadMPRow); + + ActionRow deleteAppIdRow = new ActionRow(); + deleteAppIdRow.setTitle("Delete App ID"); + deleteAppIdRow.setSubtitle("That won't let you create more App IDs though"); + deleteAppIdRow.setActivatable(true); + deleteAppIdRow.addOnActivated((_) { + setBusy(true); + new Thread({ + uiTry({ + scope(exit) runInUIThread(() => setBusy(false)); + session.deleteAppId!iOS(team, appId).unwrap(); + runInUIThread(() => unparent()); + }); + }).start(); + }); + this.addRow(deleteAppIdRow); } } } diff --git a/linux/gtk/ui/sideloadprogresswindow.d b/linux/gtk/ui/sideloadprogresswindow.d index 938c67a..d05659f 100644 --- a/linux/gtk/ui/sideloadprogresswindow.d +++ b/linux/gtk/ui/sideloadprogresswindow.d @@ -65,7 +65,7 @@ class SideloadProgressWindow: Window { } auto progressBar = progressWindow.progressBar; - auto anim = TimedAnimation(progressBar, progressBar.getFraction(), progress, dur!"msecs"(200), (progress) { + auto anim = new LeaklessTimedAnimation(progressBar, progressBar.getFraction(), progress, dur!"msecs"(200), (progress) { progressBar.setFraction(progress); progressBar.setText(message); }); diff --git a/linux/gtk/ui/utils.d b/linux/gtk/ui/utils.d index 6e90912..e58688e 100644 --- a/linux/gtk/ui/utils.d +++ b/linux/gtk/ui/utils.d @@ -72,19 +72,37 @@ import core.memory; import core.time; import adw.CallbackAnimationTarget; -import adw.TimedAnimation: AdwTimedAnimation = TimedAnimation; +import adw.TimedAnimation; + +import gobject.Signals; import gtk.Widget; -AdwTimedAnimation TimedAnimation(Widget widget, double from, double to, Duration duration, void delegate(double value) del) { - struct Callback { +class LeaklessTimedAnimation: TimedAnimation { + private struct Callback { void delegate(double value) cb; } - auto cb = new Callback(del); - GC.addRoot(cb); - return new AdwTimedAnimation(widget, from, to, cast(uint) duration.total!"msecs"(), new CallbackAnimationTarget((progress, data) { - auto cb = cast(Callback*) data; - GC.removeRoot(cb); - cb.cb(progress); - }, cb, null)); + + Callback* cb; + CallbackAnimationTarget animationTarget; + + this(Widget widget, double from, double to, Duration duration, void delegate(double value) del) { + cb = new Callback(del); + animationTarget = new CallbackAnimationTarget((progress, data) { + auto cb = cast(Callback*) data; + cb.cb(progress); + }, cb, null); + GC.addRoot(cast(void*) animationTarget); + GC.addRoot(cb); + + super(widget, from, to, cast(uint) duration.total!"msecs"(), animationTarget); + } + + ~this() { + GC.removeRoot(cast(void*) animationTarget); + GC.removeRoot(cast(void*) cb); + animationTarget.destroy(); + GC.free(cast(void*) animationTarget); + GC.free(cast(void*) cb); + } } diff --git a/source/server/developersession.d b/source/server/developersession.d index 56f8299..6416f55 100644 --- a/source/server/developersession.d +++ b/source/server/developersession.d @@ -300,6 +300,21 @@ class DeveloperSession { ); } + DeveloperPortalResponse!None deleteAppId(DeveloperDeviceType deviceType)(DeveloperTeam team, AppId appId) { + alias DeveloperPortalResponse = typeof(return); + auto log = getLogger(); + + auto request = dict( + "appIdId", appId.appIdId, + "teamId", team.teamId, + ); + + return sendRequest(developerPortal!("deleteAppId.action", deviceType), request).match!( + (PlistDict dict) => DeveloperPortalResponse(None()), + (DeveloperPortalError err) => DeveloperPortalResponse(err) + ); + } + DeveloperPortalResponse!(ApplicationGroup[]) listApplicationGroups(DeveloperDeviceType deviceType)(DeveloperTeam team) { alias DeveloperPortalResponse = typeof(return); auto log = getLogger();