Skip to content

Commit

Permalink
Fix the memory leak in adw.TimedAnimation, and disable i686 builds
Browse files Browse the repository at this point in the history
  • Loading branch information
Dadoum committed Oct 19, 2023
1 parent e07b53e commit d868124
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 13 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
20 changes: 18 additions & 2 deletions linux/gtk/ui/manageappidwindow.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}
}
2 changes: 1 addition & 1 deletion linux/gtk/ui/sideloadprogresswindow.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
Expand Down
38 changes: 28 additions & 10 deletions linux/gtk/ui/utils.d
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
15 changes: 15 additions & 0 deletions source/server/developersession.d
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down

0 comments on commit d868124

Please sign in to comment.