diff --git a/MiniSim/AppleScript Commands/ExecuteCommand.swift b/MiniSim/AppleScript Commands/ExecuteCommand.swift index d3f0e55..e1864e9 100644 --- a/MiniSim/AppleScript Commands/ExecuteCommand.swift +++ b/MiniSim/AppleScript Commands/ExecuteCommand.swift @@ -19,28 +19,30 @@ class ExecuteCommand: NSScriptCommand { let deviceId = self.property(forKey: "deviceId") as? String else { scriptErrorNumber = NSRequiredArgumentsMissingScriptError; - return nil; + return nil } let device = Device(name: deviceName, ID: deviceId, platform: platform) let rawTag = Int(tag) ?? 0 - guard let menuItem = SubMenuItems.Tags(rawValue: rawTag) else { + guard let menuItem = SubMenuItems.Tags(rawValue: rawTag) else { return nil } - platform == .android ? - DeviceService.handleAndroidAction( - device: device, - commandTag: menuItem, - itemName: commandName - ) : - DeviceService.handleiOSAction( - device: device, - commandTag: menuItem, - itemName: commandName - ) - - return Never.self; + switch platform { + case .android: + DeviceService.handleAndroidAction( + device: device, + commandTag: menuItem, + itemName: commandName + ) + case .ios: + DeviceService.handleiOSAction( + device: device, + commandTag: menuItem, + itemName: commandName + ) + } + return nil } } diff --git a/MiniSim/Menu.swift b/MiniSim/Menu.swift index 190350e..1814ba5 100644 --- a/MiniSim/Menu.swift +++ b/MiniSim/Menu.swift @@ -33,6 +33,39 @@ class Menu: NSMenu { self.delegate = self } + func populateDefaultMenu() { + var sections: [DeviceListSection] = [] + if UserDefaults.standard.enableiOSSimulators { + sections.append(.iOS) + } + + if UserDefaults.standard.enableAndroidEmulators { + sections.append(.android) + } + + guard !sections.isEmpty else { + return + } + + var menuItems: [NSMenuItem] = [] + + sections.forEach { section in + var menuItem: NSMenuItem + if #available(macOS 14.0, *) { + menuItem = NSMenuItem.sectionHeader(title: "") + } else { + menuItem = NSMenuItem() + } + menuItem.tag = section.rawValue + menuItem.title = section.title + menuItem.toolTip = section.title + + menuItems.append(menuItem) + menuItems.append(NSMenuItem.separator()) + } + self.items = menuItems + } + func updateDevicesList() { let userDefaults = UserDefaults.standard DeviceService.getAllDevices( @@ -52,7 +85,8 @@ class Menu: NSMenu { } private func removeMenuItems(removedDevices: Set) { - self.items.filter({ removedDevices.contains($0.title) }) + self.items + .filter({ removedDevices.contains($0.title) }) .forEach(safeRemoveItem) } @@ -154,14 +188,12 @@ class Menu: NSMenu { return } - var count = 0 - items.forEach { menuItem in - count += 1 + for (index, menuItem) in items.enumerated() { if let itemIndex = self.items.firstIndex(where: { $0.title == menuItem.title }) { self.replaceMenuItem(at: itemIndex, with: menuItem) return } - self.safeInsertItem(menuItem, at: startIndex + count) + self.safeInsertItem(menuItem, at: startIndex + index + 1) } } @@ -174,7 +206,7 @@ class Menu: NSMenu { ) menuItem.target = self - menuItem.keyEquivalentModifierMask = [.command] + menuItem.keyEquivalentModifierMask = device.platform == .android ? [.option] : [.command] menuItem.submenu = buildSubMenu(for: device) menuItem.state = device.booted ? .on : .off return menuItem @@ -210,7 +242,8 @@ class Menu: NSMenu { if item is SubMenuItems.Separator { return NSMenuItem.separator() } - else if let item = item as? SubMenuActionItem { + + if let item = item as? SubMenuActionItem { if item.needBootedDevice && !isDeviceBooted { return nil } @@ -221,6 +254,7 @@ class Menu: NSMenu { return NSMenuItem(menuItem: item, target: self, action: callback) } + return nil } } diff --git a/MiniSim/MenuItems/SubMenuItem.swift b/MiniSim/MenuItems/SubMenuItem.swift index b5114bc..090e3ac 100644 --- a/MiniSim/MenuItems/SubMenuItem.swift +++ b/MiniSim/MenuItems/SubMenuItem.swift @@ -33,10 +33,10 @@ enum SubMenuItems { struct Separator: SubMenuItem { } struct CopyName: SubMenuActionItem { - let title: String = NSLocalizedString("Copy name", comment: "") - let tag: Int = Tags.copyName.rawValue - let bootsDevice: Bool = false - let needBootedDevice: Bool = false + let title = NSLocalizedString("Copy name", comment: "") + let tag = Tags.copyName.rawValue + let bootsDevice = false + let needBootedDevice = false let image = NSImage( systemSymbolName: "square.and.arrow.up", accessibilityDescription: "Copy name" @@ -44,10 +44,10 @@ enum SubMenuItems { } struct CopyID: SubMenuActionItem { - let title: String = NSLocalizedString("Copy ID", comment: "") - let tag: Int = Tags.copyID.rawValue - let bootsDevice: Bool = false - let needBootedDevice: Bool = true + let title = NSLocalizedString("Copy ID", comment: "") + let tag = Tags.copyID.rawValue + let bootsDevice = false + let needBootedDevice = true let image = NSImage( systemSymbolName: "doc.on.doc", accessibilityDescription: "Copy ID" @@ -55,10 +55,10 @@ enum SubMenuItems { } struct CopyUDID: SubMenuActionItem { - let title: String = NSLocalizedString("Copy UDID", comment: "") - let tag: Int = Tags.copyID.rawValue - let bootsDevice: Bool = false - let needBootedDevice: Bool = false + let title = NSLocalizedString("Copy UDID", comment: "") + let tag = Tags.copyID.rawValue + let bootsDevice = false + let needBootedDevice = false let image = NSImage( systemSymbolName: "doc.on.doc", accessibilityDescription: "Copy UDID" @@ -66,10 +66,10 @@ enum SubMenuItems { } struct ColdBoot: SubMenuActionItem { - let title: String = NSLocalizedString("Cold boot", comment: "") - let tag: Int = Tags.coldBoot.rawValue - let bootsDevice: Bool = true - let needBootedDevice: Bool = false + let title = NSLocalizedString("Cold boot", comment: "") + let tag = Tags.coldBoot.rawValue + let bootsDevice = true + let needBootedDevice = false let image = NSImage( systemSymbolName: "sunrise.fill", accessibilityDescription: "Cold boot" @@ -77,10 +77,10 @@ enum SubMenuItems { } struct NoAudio: SubMenuActionItem { - let title: String = NSLocalizedString("Run without audio", comment: "") - let tag: Int = Tags.noAudio.rawValue - let bootsDevice: Bool = true - let needBootedDevice: Bool = false + let title = NSLocalizedString("Run without audio", comment: "") + let tag = Tags.noAudio.rawValue + let bootsDevice = true + let needBootedDevice = false let image = NSImage( systemSymbolName: "speaker.slash.fill", accessibilityDescription: "Run without audio" @@ -88,10 +88,10 @@ enum SubMenuItems { } struct ToggleA11y: SubMenuActionItem { - let title: String = NSLocalizedString("Toggle accessibility", comment: "") - let tag: Int = Tags.toggleA11y.rawValue - let bootsDevice: Bool = false - let needBootedDevice: Bool = true + let title = NSLocalizedString("Toggle accessibility", comment: "") + let tag = Tags.toggleA11y.rawValue + let bootsDevice = false + let needBootedDevice = true let image = NSImage( systemSymbolName: "figure.walk.circle.fill", accessibilityDescription: "Toggle accessibility" @@ -99,10 +99,10 @@ enum SubMenuItems { } struct Paste: SubMenuActionItem { - let title: String = NSLocalizedString("Paste clipboard to device", comment: "") - let tag: Int = Tags.paste.rawValue - let bootsDevice: Bool = false - let needBootedDevice: Bool = true + let title = NSLocalizedString("Paste clipboard to device", comment: "") + let tag = Tags.paste.rawValue + let bootsDevice = false + let needBootedDevice = true let image = NSImage( systemSymbolName: "keyboard", accessibilityDescription: "Keyboard" @@ -110,10 +110,10 @@ enum SubMenuItems { } struct Delete: SubMenuActionItem { - let title: String = NSLocalizedString("Delete simulator", comment: "") - let tag: Int = Tags.paste.rawValue - let bootsDevice: Bool = false - let needBootedDevice: Bool = false + let title = NSLocalizedString("Delete simulator", comment: "") + let tag = Tags.paste.rawValue + let bootsDevice = false + let needBootedDevice = false let image = NSImage( systemSymbolName: "trash", accessibilityDescription: "Delete simulator" diff --git a/MiniSim/MiniSim.swift b/MiniSim/MiniSim.swift index a5daa81..d4dfb2e 100644 --- a/MiniSim/MiniSim.swift +++ b/MiniSim/MiniSim.swift @@ -85,12 +85,10 @@ class MiniSim: NSObject { statusItem.menu = menu setMenuImage() - guard menu.items.isEmpty else { - menu.updateDevicesList() - return + if menu.items.isEmpty { + menu.populateDefaultMenu() + menu.items += mainMenu } - - (devicesListHeaders + mainMenu).forEach { menu.addItem($0) } menu.updateDevicesList() } @@ -166,39 +164,6 @@ class MiniSim: NSObject { } } - private var devicesListHeaders: [NSMenuItem] { - var sections: [DeviceListSection] = [] - if UserDefaults.standard.enableiOSSimulators { - sections.append(.iOS) - } - - if UserDefaults.standard.enableAndroidEmulators { - sections.append(.android) - } - - guard sections.count > 1 else { - return [] - } - - var menuItems: [NSMenuItem] = [] - - sections.forEach { section in - var menuItem: NSMenuItem - if #available(macOS 14.0, *) { - menuItem = NSMenuItem.sectionHeader(title: "") - } else { - menuItem = NSMenuItem() - } - menuItem.tag = section.rawValue - menuItem.title = section.title - menuItem.toolTip = section.title - - menuItems.append(menuItem) - menuItems.append(NSMenuItem.separator()) - } - return menuItems - } - private var mainMenu: [NSMenuItem] { MainMenuActions.allCases.map { item in NSMenuItem(