فهرست منبع

config(apple): fix custom icon

Fixes #3477
osy 3 سال پیش
والد
کامیت
b11224f2e2

+ 25 - 2
Configuration/UTMAppleConfiguration.swift

@@ -31,7 +31,7 @@ final class UTMAppleConfiguration: UTMConfigurable, Codable, ObservableObject {
     
     @Published var architecture: String
     
-    @Published var existingPath: URL?
+    @Published var iconBasePath: URL?
     
     @Published var selectedCustomIconPath: URL?
     
@@ -51,6 +51,26 @@ final class UTMAppleConfiguration: UTMConfigurable, Codable, ObservableObject {
     
     @Published var consoleResizeCommand: String?
     
+    var iconUrl: URL? {
+        if self.iconCustom {
+            if let current = self.selectedCustomIconPath {
+                return current // if we just selected a path
+            }
+            guard let icon = self.icon else {
+                return nil
+            }
+            guard let base = self.iconBasePath?.appendingPathComponent("Data") else {
+                return nil
+            }
+            return base.appendingPathComponent(icon) // from saved config
+        } else {
+            guard let icon = self.icon else {
+                return nil
+            }
+            return Bundle.main.url(forResource: icon, withExtension: "png", subdirectory: "Icons")
+        }
+    }
+    
     var cpuCount: Int {
         get {
             apple.cpuCount
@@ -418,7 +438,9 @@ final class UTMAppleConfiguration: UTMConfigurable, Codable, ObservableObject {
         let configData = try Data(contentsOf: configURL)
         let decoder = PropertyListDecoder()
         decoder.userInfo = [.dataURL: dataURL]
-        return try decoder.decode(UTMAppleConfiguration.self, from: configData)
+        let config = try decoder.decode(UTMAppleConfiguration.self, from: configData)
+        config.iconBasePath = packageURL
+        return config
     }
     
     func save(to packageURL: URL) throws {
@@ -478,6 +500,7 @@ final class UTMAppleConfiguration: UTMConfigurable, Codable, ObservableObject {
         // save new icon
         if iconCustom {
             if let iconURL = selectedCustomIconPath {
+                // FIXME: cannot modify state outside of main thread
                 icon = iconURL.lastPathComponent
                 return [try copyItemIfChanged(from: iconURL, to: dataURL)]
             } else if let existingName = icon {

+ 1 - 1
Configuration/UTMConfigurable.h

@@ -21,7 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
 @protocol UTMConfigurable
 
 @property (nonatomic, copy) NSString *name;
-@property (nonatomic, nullable, copy) NSURL *existingPath;
+@property (nonatomic, nullable, readonly) NSURL *iconUrl;
 @property (nonatomic, nullable, copy) NSURL *selectedCustomIconPath;
 @property (nonatomic, nullable, copy) NSString *icon;
 @property (nonatomic, assign) BOOL iconCustom;

+ 18 - 0
Configuration/UTMQemuConfiguration.m

@@ -70,6 +70,24 @@ const NSString *const kUTMConfigAppleVirtualizationKey = @"isAppleVirtualization
     _selectedCustomIconPath = selectedCustomIconPath;
 }
 
+- (NSURL *)iconUrl {
+    if (self.iconCustom) {
+        if (self.selectedCustomIconPath != nil) {
+            return self.selectedCustomIconPath;
+        } else if (self.icon == nil) {
+            return nil;
+        } else {
+            return [self.existingPath URLByAppendingPathComponent:self.icon];
+        }
+    } else {
+        if (self.icon == nil) {
+            return nil;
+        } else {
+            return [[NSBundle mainBundle] URLForResource:self.icon withExtension:@"png" subdirectory:@"Icons"];
+        }
+    }
+}
+
 #pragma mark - Migration
 
 - (void)migrateConfigurationIfNecessary {

+ 0 - 26
Configuration/UTMQemuConfigurationExtension.swift

@@ -16,32 +16,6 @@
 
 import Combine
 
-extension UTMConfigurable {
-    var existingCustomIconURL: URL? {
-        if let current = self.selectedCustomIconPath {
-            return current // if we just selected a path
-        }
-        guard let parent = self.existingPath else {
-            return nil
-        }
-        guard let icon = self.icon else {
-            return nil
-        }
-        return parent.appendingPathComponent(icon) // from saved config
-    }
-    
-    var existingIconURL: URL? {
-        guard let icon = self.icon else {
-            return nil
-        }
-        if let path = Bundle.main.path(forResource: icon, ofType: "png", inDirectory: "Icons") {
-            return URL(fileURLWithPath: path)
-        } else {
-            return nil
-        }
-    }
-}
-
 @objc extension UTMQemuConfiguration: ObservableObject {
     func propertyWillChange() -> Void {
         if #available(iOS 13, macOS 11, *) {

+ 0 - 8
Managers/UTMAppleVirtualMachine.swift

@@ -34,14 +34,6 @@ import Virtualization
         systemTarget
     }
     
-    override var icon: URL? {
-        if appleConfig.iconCustom {
-            return appleConfig.existingCustomIconURL
-        } else {
-            return appleConfig.existingIconURL
-        }
-    }
-    
     override var notes: String? {
         appleConfig.notes
     }

+ 4 - 0
Managers/UTMVirtualMachine.m

@@ -66,6 +66,10 @@ NSString *const kUTMBundleScreenshotFilename = @"screenshot.png";
     self.anyCancellable = [self subscribeToConfiguration];
 }
 
+- (NSURL *)icon {
+    return self.config.iconUrl;
+}
+
 + (BOOL)URLisVirtualMachine:(NSURL *)url {
     return [url.pathExtension isEqualToString:kUTMBundleExtension];
 }

+ 0 - 8
Managers/UTMVirtualMachineExtension.swift

@@ -66,14 +66,6 @@ public extension UTMQemuVirtualMachine {
         self.systemTarget
     }
     
-    override var icon: URL? {
-        if qemuConfig.iconCustom {
-            return qemuConfig.existingCustomIconURL
-        } else {
-            return qemuConfig.existingIconURL
-        }
-    }
-    
     override var notes: String? {
         qemuConfig.notes
     }

+ 4 - 4
Platform/Shared/VMConfigInfoView.swift

@@ -75,7 +75,7 @@ struct VMConfigInfoView<Config: ObservableObject & UTMConfigurable>: View {
                     case .custom:
                         #if os(macOS)
                         Button(action: { imageSelectVisible.toggle() }, label: {
-                            IconPreview(url: config.existingCustomIconURL)
+                            IconPreview(url: config.iconUrl)
                         }).fileImporter(isPresented: $imageSelectVisible, allowedContentTypes: [.image]) { result in
                             switch result {
                             case .success(let url):
@@ -86,14 +86,14 @@ struct VMConfigInfoView<Config: ObservableObject & UTMConfigurable>: View {
                         }.buttonStyle(PlainButtonStyle())
                         #else
                         Button(action: { imageSelectVisible.toggle() }, label: {
-                            IconPreview(url: config.existingCustomIconURL)
+                            IconPreview(url: config.iconUrl)
                         }).popover(isPresented: $imageSelectVisible, arrowEdge: .bottom) {
                             ImagePicker(onImageSelected: imageCustomSelected)
                         }.buttonStyle(PlainButtonStyle())
                         #endif
                     case .operatingSystem:
                         Button(action: { imageSelectVisible.toggle() }, label: {
-                            IconPreview(url: config.existingIconURL)
+                            IconPreview(url: config.iconUrl)
                         }).popover(isPresented: $imageSelectVisible, arrowEdge: .bottom) {
                             IconSelect(onIconSelected: imageSelected)
                         }.buttonStyle(PlainButtonStyle())
@@ -105,7 +105,7 @@ struct VMConfigInfoView<Config: ObservableObject & UTMConfigurable>: View {
         }.onAppear {
             if config.iconCustom {
                 iconStyle = .custom
-            } else if config.existingIconURL != nil {
+            } else if config.iconUrl != nil {
                 iconStyle = .operatingSystem
             }
         }.alert(item: $warningMessage) { warning in