Skip to content

commit 39314f5

abduznik edited this page May 23, 2026 · 1 revision

fix(storage): robust linux path detection and sd card priority

Commit: 39314f5f31176f2f44a7a61bd0353416b0da8f89

Author: abduznik

Date: 2026-04-28

Why: Fixes a bug or regression in the existing codebase.

Files Changed

.../linux_strategies/emudeck_strategy.dart         | 49 ++++++++++++++++------
 lib/core/storage/directory_service.dart            | 29 ++++++++-----
 2 files changed, 54 insertions(+), 24 deletions(-)
  • lib/core/emulator/linux_strategies/emudeck_strategy.dart
  • lib/core/storage/directory_service.dart

Diff

diff --git a/lib/core/emulator/linux_strategies/emudeck_strategy.dart b/lib/core/emulator/linux_strategies/emudeck_strategy.dart
index ff0d1cb..21a76f1 100644
--- a/lib/core/emulator/linux_strategies/emudeck_strategy.dart
+++ b/lib/core/emulator/linux_strategies/emudeck_strategy.dart
@@ -13,30 +13,53 @@ class EmuDeckStrategy extends LinuxEnvironmentStrategy {
   @override
   String getRomsRoot(String home, String? customPath, String? emudeckRoot) {
     if (emudeckRoot != null) {
-      // Robustness: if user pointed directly to 'Emulation' or 'Emulation/roms', handle it
-      if (p.basename(emudeckRoot).toLowerCase() == 'roms' && p.basename(p.dirname(emudeckRoot)).toLowerCase() == 'emulation') {
-        return customPath ?? emudeckRoot;
-      }
+      // 1. Check if user pointed directly to a 'roms' folder
+      if (p.basename(emudeckRoot).toLowerCase() == 'roms') return emudeckRoot;
+      
+      // 2. Try standard Emulation/roms (lowercase)
+      final standard = p.join(emudeckRoot, 'Emulation', 'roms');
+      if (io.Directory(standard).existsSync()) return standard;
+
+      // 3. Try Emulation/ROMs (uppercase)
+      final upper = p.join(emudeckRoot, 'Emulation', 'ROMs');
+      if (io.Directory(upper).existsSync()) return upper;
+
+      // 4. Try root/roms (some manual move scenarios)
+      final direct = p.join(emudeckRoot, 'roms');
+      if (io.Directory(direct).existsSync()) return direct;
+
+      // 5. If they pointed to 'Emulation' itself but roms folder isn't detected yet
       if (p.basename(emudeckRoot).toLowerCase() == 'emulation') {
-        return customPath ?? p.join(emudeckRoot, 'roms');
+        return p.join(emudeckRoot, 'roms');
       }
-      return customPath ?? p.join(emudeckRoot, 'Emulation/roms');
+
+      // Default back to standard EmuDeck expectation
+      return p.join(emudeckRoot, 'Emulation', 'roms');
     }
-    return customPath ?? p.join(home, 'ROMs');
+    return p.join(home, 'ROMs');
   }
 
   @override
   String getEmulatorsRoot(String home, String? customPath, String? emudeckRoot) {
     if (emudeckRoot != null) {
-      if (p.basename(emudeckRoot).toLowerCase() == 'tools' && p.basename(p.dirname(emudeckRoot)).toLowerCase() == 'emulation') {
-        return customPath ?? emudeckRoot;
-      }
+      // 1. Check if user pointed directly to 'tools'
+      if (p.basename(emudeckRoot).toLowerCase() == 'tools') return emudeckRoot;
+
+      // 2. Standard Emulation/tools
+      final standard = p.join(emudeckRoot, 'Emulation', 'tools');
+      if (io.Directory(standard).existsSync()) return standard;
+
+      // 3. Root/tools
+      final direct = p.join(emudeckRoot, 'tools');
+      if (io.Directory(direct).existsSync()) return direct;
+
       if (p.basename(emudeckRoot).toLowerCase() == 'emulation') {
-        return customPath ?? p.join(emudeckRoot, 'tools');
+        return p.join(emudeckRoot, 'tools');
       }
-      return customPath ?? p.join(emudeckRoot, 'Emulation/tools');
+
+      return p.join(emudeckRoot, 'Emulation', 'tools');
     }
-    return customPath ?? p.join(home, 'Emulators');
+    return p.join(home, 'Emulators');
   }
 
   @override
diff --git a/lib/core/storage/directory_service.dart b/lib/core/storage/directory_service.dart
index 3aafe63..c75554c 100644
--- a/lib/core/storage/directory_service.dart
+++ b/lib/core/storage/directory_service.dart
@@ -75,23 +75,21 @@ class DirectoryService {
   Future<String?> detectEmuDeckRoot() async {
     final home = io.Platform.environment['HOME'] ?? '/home/deck';
     
-    // 1. Check Internal Home
-    final internal = p.join(home, 'Emulation');
-    if (await io.Directory(internal).exists()) return internal.replaceAll('/Emulation', '');
-
-    // 2. Check External SD / Removable Media
+    // 1. Check External SD / Removable Media FIRST (Most Steam Deck users prefer SD)
     final mediaDir = io.Directory('/run/media');
     if (await mediaDir.exists()) {
       try {
-        await for (final userDir in mediaDir.list()) {
+        final List<io.FileSystemEntity> users = await mediaDir.list().toList();
+        for (final userDir in users) {
           if (userDir is! io.Directory) continue;
 
-          // Check 1 level deep: /run/media/LABEL/Emulation
+          // Check 1 level deep: /run/media/deck/Emulation
           final candidate1 = p.join(userDir.path, 'Emulation');
           if (await io.Directory(candidate1).exists()) return userDir.path;
 
-          // Check 2 levels deep: /run/media/USER/LABEL/Emulation
-          await for (final mountDir in userDir.list()) {
+          // Check 2 levels deep: /run/media/deck/LABEL/Emulation
+          final List<io.FileSystemEntity> mounts = await userDir.list().toList();
+          for (final mountDir in mounts) {
             if (mountDir is! io.Directory) continue;
             final candidate2 = p.join(mountDir.path, 'Emulation');
             if (await io.Directory(candidate2).exists()) {
@@ -102,6 +100,10 @@ class DirectoryService {
       } catch (_) {}
     }
 
+    // 2. Check Internal Home LAST
+    final internal = p.join(home, 'Emulation');
+    if (await io.Directory(internal).exists()) return home;
+
     return null;
   }
 
@@ -172,8 +174,13 @@ class DirectoryService {
         final customRoms = _prefs.getString(_romsRootPathKey);
         final customEmus = _prefs.getString(_emulatorsRootPathKey);
         
-        romsRootPath = activeLinuxEnvironment.getRomsRoot(home, customRoms, emudeckRootPath);
-        emulatorsRootPath = activeLinuxEnvironment.getEmulatorsRoot(home, customEmus, emudeckRootPath);
+        // IMPORTANT: If we are using a preset (EmuDeck/RetroDeck), we IGNORE the manual custom paths
+        // to ensure the computed paths from the root always take precedence.
+        final String? effectiveCustomRoms = (linuxSyncPreset == 'default') ? customRoms : null;
+        final String? effectiveCustomEmus = (linuxSyncPreset == 'default') ? customEmus : null;
+
+        romsRootPath = activeLinuxEnvironment.getRomsRoot(home, effectiveCustomRoms, emudeckRootPath);
+        emulatorsRootPath = activeLinuxEnvironment.getEmulatorsRoot(home, effectiveCustomEmus, emudeckRootPath);
       } else {
         romsRootPath = _prefs.getString(_romsRootPathKey) ?? p.join(defaultBase, 'ROMs');
         emulatorsRootPath =

Clone this wiki locally