diff options
Diffstat (limited to 'mut/dmenu-mac/src/AppListProvider.swift')
| -rw-r--r-- | mut/dmenu-mac/src/AppListProvider.swift | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/mut/dmenu-mac/src/AppListProvider.swift b/mut/dmenu-mac/src/AppListProvider.swift new file mode 100644 index 0000000..7aa3ad8 --- /dev/null +++ b/mut/dmenu-mac/src/AppListProvider.swift @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2020 Jose Pereira <onaips@gmail.com>. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +import Foundation +import FileWatcher +import Fuse + +/** + * Provide a list of launcheable apps for the OS + */ +class AppListProvider: ListProvider { + + var appDirDict = [String: Bool]() + + var appList = [URL]() + + init() { + let applicationDir = NSSearchPathForDirectoriesInDomains( + .applicationDirectory, .localDomainMask, true)[0] + + // Catalina moved default applications under a different mask. + let systemApplicationDir = NSSearchPathForDirectoriesInDomains( + .applicationDirectory, .systemDomainMask, true)[0] + + // appName to dir recursivity key/valye dict + appDirDict[applicationDir] = true + appDirDict[systemApplicationDir] = true + appDirDict["/System/Library/CoreServices/"] = false + + initFileWatch(Array(appDirDict.keys)) + updateAppList() + } + + func initFileWatch(_ dirs: [String]) { + let filewatcher = FileWatcher(dirs) + filewatcher.callback = {_ in + self.updateAppList() + } + filewatcher.start() + } + + func updateAppList() { + var newAppList = [URL]() + appDirDict.keys.forEach { path in + let urlPath = URL(fileURLWithPath: path, isDirectory: true) + let list = getAppList(urlPath, recursive: appDirDict[path]!) + newAppList.append(contentsOf: list) + } + appList = newAppList + } + + func getAppList(_ appDir: URL, recursive: Bool = true) -> [URL] { + var list = [URL]() + let fileManager = FileManager.default + + do { + let subs = try fileManager.contentsOfDirectory(atPath: appDir.path) + + for sub in subs { + let dir = appDir.appendingPathComponent(sub) + + if dir.pathExtension == "app" { + list.append(dir) + } else if dir.hasDirectoryPath && recursive { + list.append(contentsOf: self.getAppList(dir)) + } + } + } catch { + NSLog("Error on getAppList: %@", error.localizedDescription) + } + return list + } + + func get() -> [ListItem] { + return appList.map({ListItem(name: $0.deletingPathExtension().lastPathComponent, data: $0)}) + } + + func doAction(item: ListItem) { + guard let app: URL = item.data as? URL else { + NSLog("Cannot do action on item \(item.name)") + return + } + DispatchQueue.main.async { + NSWorkspace.shared.open(app) + } + } +} |
