fix(runtime): keep the Linux desktop installed across a runtime update (#2021)

* fix(runtime): keep the Linux desktop installed across a runtime update

A runtime update replaces the whole runtime tree, and the desktop pack
is built against one runtime, so every update removed the installed
desktop. Since the runtime started updating by itself, this happened
without the user doing anything: the next Open showed "Install & open"
and downloaded the whole desktop again.

When the desktop was installed before the update, the same update job
now installs the new runtime's desktop pack right after the runtime,
with the update's progress. If that install fails, the runtime update
still counts as done and Open offers the install as before. A repair
from the session no longer installs the desktop a second time when the
runtime install already did.

* fix(runtime): roll back a failed desktop restore after a runtime update

If putting the desktop back fails after its archive started unpacking,
the install journal stayed behind, and every later launch, Steam
included, tried to resume it and stopped when that failed. The update
now rolls back the partial desktop with the desktop removal, which
restores the runtime's own files and clears the journal. Open then
offers the desktop install as before.

Whether the desktop was installed is now checked on its own, so a
repair of a damaged runtime also restores it.

* fix(session): do not install the desktop again after resuming it

Opening the desktop with an interrupted desktop install resumed that
install and then installed the desktop a second time. The second
install is now skipped when the resume already completed the desktop.
This commit is contained in:
MaxsTechReview authored and GitHub committed 2026-11-02 21:20:18 -05:00
1 parent 4b8f63d84d
commit 2b790a8a71
3 files changed
+32 -4

No files matched your search

@@ -1944,7 +1944,8 @@ class SessionActivity : ComponentActivity(), SurfaceHolder.Callback {
}
if (problem == null) SessionEvents.record("package.ready") else failedComponent = "package"
}
if (problem == null && desktop && !SessionState.stopRequested) {
if (problem == null && desktop && !SessionState.stopRequested &&
!((runtime || resume) && com.droiddeck.launcher.runtime.DesktopCatalog.desktopInstalled(this))) {
if (activeInstallWorker === worker) SessionState.installing = "desktop"
SessionEvents.transition(SessionPhase.INSTALLING_RUNTIME, "desktop.installing", mapOf("component" to "desktop"))
problem = installDesktop()
@@ -130,7 +130,8 @@ public final class LinuxRuntimeInstaller {
}
if (!owner) return join(job, listener);
try {
job.ok = installOnce(context.getApplicationContext(), release, new ProgressListener() {
Context app = context.getApplicationContext();
ProgressListener progress = new ProgressListener() {
@Override public void onProgress(String stage, int percent) {
onProgress(Step.OTHER, stage, percent);
}
@@ -141,7 +142,10 @@ public final class LinuxRuntimeInstaller {
job.percent = percent;
for (ProgressListener l : job.listeners) l.onProgress(step, stage, percent);
}
});
};
boolean desktop = DesktopCatalog.INSTANCE.desktopInstalled(app);
job.ok = installOnce(app, release, progress);
if (job.ok && desktop) keepDesktop(app, progress);
return job.ok;
} finally {
synchronized (JOB_LOCK) {
@@ -151,6 +155,28 @@ public final class LinuxRuntimeInstaller {
}
}
private static void keepDesktop(Context context, ProgressListener progress) {
String problem;
try {
problem = DesktopCatalog.INSTANCE.install(context, DesktopCatalog.INSTANCE.desktopEntry(context), progress);
} catch (RuntimeException e) {
problem = e.toString();
}
if (problem == null) {
Log.i(TAG, "desktop installed again for the new runtime");
return;
}
Log.w(TAG, "desktop not installed again for the new runtime: " + problem);
boolean started = false;
for (DesktopCatalog.Entry entry : DesktopCatalog.INSTANCE.interrupted(context)) {
if (DesktopCatalog.DESKTOP_ID.equals(entry.getId())) started = true;
}
if (!started) return;
String undone = DesktopCatalog.INSTANCE.removeDesktop(context, progress);
if (undone == null) Log.i(TAG, "rolled back the partial desktop install");
else Log.w(TAG, "could not roll back the partial desktop install: " + undone);
}
public static boolean isInstalling() {
synchronized (JOB_LOCK) {
return running != null && !running.removal && !running.maintenance;
+2 -1
View File
@@ -29,7 +29,8 @@ Steam on the desktop). The app installs it into `files/linuxfs` and runs it unde
- The desktop pack's `usr/share/droiddeck/desktop/files.tsv.gz` lists each path the desktop added
(N), changed (C) or removed (R), and `originals/` keeps the runtime's copies of changed and removed
files. Removing the desktop restores those and deletes the added files the user has not changed;
a runtime update replaces the tree, and the desktop is downloaded again when it is next opened.
a runtime update replaces the tree, so when the desktop was installed the update installs the new
runtime's desktop pack right after it.
At run time: