From a14f96550bb7ac97ab2024f8ffebf7c26dae0dc5 Mon Sep 17 00:00:00 2001 From: "louis.pontoise" Date: Thu, 6 Feb 2020 21:33:49 +0900 Subject: [PATCH] feat: add debug profile to feedback message --- alt-tab-macos.xcodeproj/project.pbxproj | 8 +++ alt-tab-macos/api-wrappers/AXUIElement.swift | 1 - alt-tab-macos/api-wrappers/CGWindow.swift | 1 - alt-tab-macos/api-wrappers/CGWindowID.swift | 1 - .../api-wrappers/HelperExtensions.swift | 2 +- alt-tab-macos/api-wrappers/PrivateApis.swift | 5 +- alt-tab-macos/api-wrappers/Sysctl.swift | 47 +++++++++++++ alt-tab-macos/logic/Application.swift | 1 - alt-tab-macos/logic/Applications.swift | 1 - alt-tab-macos/logic/DebugProfile.swift | 70 +++++++++++++++++++ alt-tab-macos/logic/Preferences.swift | 1 - alt-tab-macos/logic/Screen.swift | 1 - alt-tab-macos/logic/Spaces.swift | 3 +- alt-tab-macos/logic/SystemPermissions.swift | 1 - alt-tab-macos/logic/Window.swift | 1 - alt-tab-macos/logic/Windows.swift | 1 - alt-tab-macos/ui/App.swift | 2 +- alt-tab-macos/ui/FeedbackWindow.swift | 50 ++++++++----- .../ui/generic-components/GridView.swift | 1 - .../ui/generic-components/text/TextArea.swift | 1 - .../preferences-window/LabelAndControl.swift | 1 - .../PreferencesWindow.swift | 1 - .../TabViewController.swift | 1 - .../ui/preferences-window/TabViewItem.swift | 1 - .../ui/preferences-window/tabs/AboutTab.swift | 1 - .../tabs/AppearanceTab.swift | 1 - .../tabs/ShortcutsTab.swift | 1 - 27 files changed, 164 insertions(+), 42 deletions(-) create mode 100644 alt-tab-macos/api-wrappers/Sysctl.swift create mode 100644 alt-tab-macos/logic/DebugProfile.swift diff --git a/alt-tab-macos.xcodeproj/project.pbxproj b/alt-tab-macos.xcodeproj/project.pbxproj index af51d00aa..ebf4d7b83 100644 --- a/alt-tab-macos.xcodeproj/project.pbxproj +++ b/alt-tab-macos.xcodeproj/project.pbxproj @@ -35,10 +35,12 @@ D04BA84074E5FD6221720BC7 /* CollectionViewFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAACB6648E7C2A4E0339D /* CollectionViewFlowLayout.swift */; }; D04BA8EBC0365A019A27C7EA /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3F15EAE8D8C39B6F2CF /* Screen.swift */; }; D04BA9CCE02D30C8164A552A /* SystemPermissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA2D2AD6B1CCA3F3A4DD7 /* SystemPermissions.swift */; }; + D04BA9EE5D34A2789DCB0EE2 /* Sysctl.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA896E37EFD27CAB61DF0 /* Sysctl.swift */; }; D04BAAD43731608067734ED3 /* DispatchQueues.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA56E285C3FCDA52ED262 /* DispatchQueues.swift */; }; D04BAB5E802C938E78839011 /* TextArea.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA8011143819B48F204C2 /* TextArea.swift */; }; D04BABF88726DA42B2CBA68B /* ThumbnailsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAF40D5E54AD1044B3FF7 /* ThumbnailsPanel.swift */; }; D04BAC0BF53A80D4F1EE22ED /* AboutTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAE23C37E0F3B07EEE7B1 /* AboutTab.swift */; }; + D04BAC4F69FE9563BC1C5E9C /* DebugProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA3915020FB9B34555D74 /* DebugProfile.swift */; }; D04BAC9C031D482119F6DEB8 /* FeedbackWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BAFA84FD0B02215718F94 /* FeedbackWindow.swift */; }; D04BACD398A35D82D514A9F7 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BABC180117F8785D250E1 /* TextField.swift */; }; D04BAD5A6B2F9EEE6FD4185F /* CollectionViewItemTitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04BA4BABBA0312E0EDBA647 /* CollectionViewItemTitle.swift */; }; @@ -63,6 +65,7 @@ D04BA2D2BCBA4C47E25315AF /* HyperlinkLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HyperlinkLabel.swift; sourceTree = ""; }; D04BA32F25860B686DFE818A /* 3 windows - 1 line.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = "3 windows - 1 line.jpg"; sourceTree = ""; }; D04BA35456DA0DDA74F9687E /* Keyboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Keyboard.swift; sourceTree = ""; }; + D04BA3915020FB9B34555D74 /* DebugProfile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugProfile.swift; sourceTree = ""; }; D04BA3D65E7CA78D699EDAB0 /* LabelAndControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelAndControl.swift; sourceTree = ""; }; D04BA3F15EAE8D8C39B6F2CF /* Screen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Screen.swift; sourceTree = ""; }; D04BA40A4291E4F310527DBF /* AXUIElement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AXUIElement.swift; sourceTree = ""; }; @@ -86,6 +89,7 @@ D04BA7ECCE728582D9ECA613 /* determine_version.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = determine_version.sh; sourceTree = ""; }; D04BA8011143819B48F204C2 /* TextArea.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextArea.swift; sourceTree = ""; }; D04BA82F792DF53958D92572 /* alt-tab-macos.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "alt-tab-macos.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + D04BA896E37EFD27CAB61DF0 /* Sysctl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sysctl.swift; sourceTree = ""; }; D04BA89FAEC4A5734D892C4B /* build_release.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = build_release.sh; sourceTree = ""; }; D04BA8BEE821E2062F23AA97 /* CollectionViewItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewItem.swift; sourceTree = ""; }; D04BA8F1AA48A323EE5638DC /* HelperExtensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HelperExtensions.swift; sourceTree = ""; }; @@ -196,6 +200,7 @@ D04BA8F1AA48A323EE5638DC /* HelperExtensions.swift */, D04BAF0DFC1F44322973CE1E /* PrivateApis.swift */, D04BAEA3EDC4F80FA23DBEC4 /* CGWindowID.swift */, + D04BA896E37EFD27CAB61DF0 /* Sysctl.swift */, ); path = "api-wrappers"; sourceTree = ""; @@ -293,6 +298,7 @@ D04BAF13DFAA6930676D0492 /* Application.swift */, D04BA66B5B4143D2238F50B9 /* Applications.swift */, D04BA56E285C3FCDA52ED262 /* DispatchQueues.swift */, + D04BA3915020FB9B34555D74 /* DebugProfile.swift */, ); path = logic; sourceTree = ""; @@ -472,6 +478,8 @@ D04BA40A1C8B02448D720EA3 /* BaseLabel.swift in Sources */, D04BAD5A6B2F9EEE6FD4185F /* CollectionViewItemTitle.swift in Sources */, D04BA6D9DA2A8BCD93347F0E /* CollectionViewItemFontIcon.swift in Sources */, + D04BA9EE5D34A2789DCB0EE2 /* Sysctl.swift in Sources */, + D04BAC4F69FE9563BC1C5E9C /* DebugProfile.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/alt-tab-macos/api-wrappers/AXUIElement.swift b/alt-tab-macos/api-wrappers/AXUIElement.swift index 13c1f696b..814fade5e 100644 --- a/alt-tab-macos/api-wrappers/AXUIElement.swift +++ b/alt-tab-macos/api-wrappers/AXUIElement.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation extension AXUIElement { func cgWindowId() -> CGWindowID { diff --git a/alt-tab-macos/api-wrappers/CGWindow.swift b/alt-tab-macos/api-wrappers/CGWindow.swift index 5db9eed62..202443218 100644 --- a/alt-tab-macos/api-wrappers/CGWindow.swift +++ b/alt-tab-macos/api-wrappers/CGWindow.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation typealias CGWindow = [CFString: Any] diff --git a/alt-tab-macos/api-wrappers/CGWindowID.swift b/alt-tab-macos/api-wrappers/CGWindowID.swift index 0775978a1..e7a94fb95 100644 --- a/alt-tab-macos/api-wrappers/CGWindowID.swift +++ b/alt-tab-macos/api-wrappers/CGWindowID.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation extension CGWindowID { func title() -> String? { diff --git a/alt-tab-macos/api-wrappers/HelperExtensions.swift b/alt-tab-macos/api-wrappers/HelperExtensions.swift index b8ddaea9d..db2bc0b10 100644 --- a/alt-tab-macos/api-wrappers/HelperExtensions.swift +++ b/alt-tab-macos/api-wrappers/HelperExtensions.swift @@ -1,4 +1,3 @@ -import Foundation import Cocoa extension CGFloat { @@ -101,6 +100,7 @@ extension NSView { } extension NSGridView { + // set height for all rows func setRowsHeight(_ height: CGFloat) { for i in 0.. UInt8 //func CGSProcessAssignToAllSpaces(_ cid: CGSConnectionID, _ pid: pid_t) -> CGError // //enum SpaceManagementMode: Int { -// case separate = 1 -// case notSeparate = 0 +// case checked = 1 +// case unchecked = 0 //} // //// returns the status of the "Displays have separate Spaces" system Preference diff --git a/alt-tab-macos/api-wrappers/Sysctl.swift b/alt-tab-macos/api-wrappers/Sysctl.swift new file mode 100644 index 000000000..a3732db31 --- /dev/null +++ b/alt-tab-macos/api-wrappers/Sysctl.swift @@ -0,0 +1,47 @@ +import Foundation + +public struct Sysctl { + static func run(_ name: String) -> String { + return run(name, { $0.baseAddress.flatMap { String(validatingUTF8: $0) } }) ?? "" + } + + static func run(_ name: String, _ type: T.Type) -> T? { + return run(name, { $0.baseAddress?.withMemoryRebound(to: T.self, capacity: 1) { $0.pointee } }) + } + + private static func run(_ name: String, _ fn: (UnsafeBufferPointer) -> R?) -> R? { + return keys(name).flatMap { keys in data(keys)?.withUnsafeBufferPointer() { fn($0) } } + } + + private static func data(_ keys: [Int32]) -> [Int8]? { + return keys.withUnsafeBufferPointer() { keysPointer in + var requiredSize = 0 + let preFlightResult = Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), nil, &requiredSize, nil, 0) + if preFlightResult != 0 { + return nil + } + let data = Array(repeating: 0, count: requiredSize) + let result = data.withUnsafeBufferPointer() { dataBuffer -> Int32 in + return Darwin.sysctl(UnsafeMutablePointer(mutating: keysPointer.baseAddress), UInt32(keys.count), UnsafeMutableRawPointer(mutating: dataBuffer.baseAddress), &requiredSize, nil, 0) + } + if result != 0 { + return nil + } + return data + } + } + + private static func keys(_ name: String) -> [Int32]? { + var keysBufferSize = Int(CTL_MAXNAME) + var keysBuffer = Array(repeating: 0, count: keysBufferSize) + _ = keysBuffer.withUnsafeMutableBufferPointer { (lbp: inout UnsafeMutableBufferPointer) in + name.withCString { (nbp: UnsafePointer) in + sysctlnametomib(nbp, lbp.baseAddress, &keysBufferSize) + } + } + if keysBuffer.count > keysBufferSize { + keysBuffer.removeSubrange(keysBufferSize.. String { + ([ + // app + ("App version", App.version), + ("App preferences", appPreferences()), + ("Applications count", String(Applications.list.count)), + ("Windows", appWindows()), + // os + ("OS version", ProcessInfo.processInfo.operatingSystemVersionString), + ("OS architecture", Sysctl.run("hw.machine")), + ("Locale", Locale.current.debugDescription), + ("Spaces count", String((CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary]).map { $0["Spaces"] }.count)), + // hardware + ("Hardware model", Sysctl.run("hw.model")), + ("Displays count", String(NSScreen.screens.count)), + ("CPU model", Sysctl.run("machdep.cpu.brand_string")), + ("Memory size", ByteCountFormatter.string(fromByteCount: Int64(ProcessInfo.processInfo.physicalMemory), countStyle: .file)), + // TODO: add gpu model(s) + // hardware utilization + ("Active CPU count", Sysctl.run("hw.activecpu", UInt.self).flatMap { String($0) } ?? ""), + ("Current CPU frequency", Sysctl.run("hw.cpufrequency", Int.self).map { String(format: "%.1f", Double($0) / Double(1_000_000_000)) + " Ghz" } ?? ""), + // TODO: CPU utilization + // TODO: Active GPU + // TODO: GPU utilization + // TODO: Memory utilization + // TODO: disk space to detect disk pressure + // TODO: thermals to check if overheating + // TODO: battery to check if low-energy mode / throttling + + ] as [(String, String)]) + .map { bulletPoint + $0.0 + intraSeparator + $0.1 } + .joined(separator: "\n") + } + + private static func appPreferences() -> String { + return nestedSeparator + Preferences.rawValues + .sorted { $0.0 < $1.0 } + .map { $0 + intraSeparator + $1 } + .joined(separator: nestedSeparator) + } + + private static func appWindows() -> String { + return nestedSeparator + Windows.list + .sorted { $0.cgWindowId < $1.cgWindowId } + .map { appWindow($0) } + .joined(separator: nestedSeparator) + } + + private static func appWindow(_ window: Window) -> String { + return "{" + ([ + ("isMinimized", String(window.isMinimized)), + ("isHidden", String(window.isHidden)), + ("isOnAllSpaces", String(window.isOnAllSpaces)), + ("spaceId", window.spaceId.flatMap { String($0) } ?? ""), + ("spaceIndex", window.spaceIndex.flatMap { String($0) } ?? ""), + ] as [(String, String)]) + .map { $0.0 + intraSeparator + $0.1 } + .joined(separator: interSeparator) + + "}" + } +} diff --git a/alt-tab-macos/logic/Preferences.swift b/alt-tab-macos/logic/Preferences.swift index ccccd5773..cfdd3a060 100644 --- a/alt-tab-macos/logic/Preferences.swift +++ b/alt-tab-macos/logic/Preferences.swift @@ -1,4 +1,3 @@ -import Foundation import Cocoa import Carbon.HIToolbox.Events diff --git a/alt-tab-macos/logic/Screen.swift b/alt-tab-macos/logic/Screen.swift index cc3b8ee76..ab18bd404 100644 --- a/alt-tab-macos/logic/Screen.swift +++ b/alt-tab-macos/logic/Screen.swift @@ -1,4 +1,3 @@ -import Foundation import Cocoa class Screen { diff --git a/alt-tab-macos/logic/Spaces.swift b/alt-tab-macos/logic/Spaces.swift index e502819b2..86212e147 100644 --- a/alt-tab-macos/logic/Spaces.swift +++ b/alt-tab-macos/logic/Spaces.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class Spaces { static var currentSpaceId = CGSSpaceID(1) @@ -31,7 +30,7 @@ class Spaces { static func allIdsAndIndexes() -> [(CGSSpaceID, SpaceIndex)] { return (CGSCopyManagedDisplaySpaces(cgsMainConnectionId) as! [NSDictionary]) - .map { return $0["Spaces"] }.joined().enumerated() + .map { $0["Spaces"] }.joined().enumerated() .map { (($0.element as! NSDictionary)["id64"]! as! CGSSpaceID, $0.offset + 1) } } diff --git a/alt-tab-macos/logic/SystemPermissions.swift b/alt-tab-macos/logic/SystemPermissions.swift index f5c8ebd9a..e82280262 100644 --- a/alt-tab-macos/logic/SystemPermissions.swift +++ b/alt-tab-macos/logic/SystemPermissions.swift @@ -1,4 +1,3 @@ -import Foundation import Cocoa // macOS has some privacy restrictions. The user needs to grant certain permissions, app by app, in System Preferences > Security & Privacy diff --git a/alt-tab-macos/logic/Window.swift b/alt-tab-macos/logic/Window.swift index 66bb9fa15..fc6894046 100644 --- a/alt-tab-macos/logic/Window.swift +++ b/alt-tab-macos/logic/Window.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class Window { var cgWindowId: CGWindowID diff --git a/alt-tab-macos/logic/Windows.swift b/alt-tab-macos/logic/Windows.swift index ab56832f3..7192ed7db 100644 --- a/alt-tab-macos/logic/Windows.swift +++ b/alt-tab-macos/logic/Windows.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class Windows { // order in the array is important: most-recently-used elements are first diff --git a/alt-tab-macos/ui/App.swift b/alt-tab-macos/ui/App.swift index 31fe84e3c..932f3d9ad 100644 --- a/alt-tab-macos/ui/App.swift +++ b/alt-tab-macos/ui/App.swift @@ -1,5 +1,5 @@ -import Foundation import Cocoa +import Darwin let cgsMainConnectionId = CGSMainConnectionID() diff --git a/alt-tab-macos/ui/FeedbackWindow.swift b/alt-tab-macos/ui/FeedbackWindow.swift index 77051b934..a352c1b0b 100644 --- a/alt-tab-macos/ui/FeedbackWindow.swift +++ b/alt-tab-macos/ui/FeedbackWindow.swift @@ -1,10 +1,10 @@ import Cocoa -import Foundation class FeedbackWindow: NSWindow, NSTextViewDelegate { var body: TextArea! var email: TextArea! var sendButton: NSButton! + var debugProfile: NSButton! override init(contentRect: NSRect, styleMask style: StyleMask, backing backingStoreType: BackingStoreType, defer flag: Bool) { super.init(contentRect: .zero, styleMask: style, backing: backingStoreType, defer: flag) @@ -47,14 +47,16 @@ class FeedbackWindow: NSWindow, NSTextViewDelegate { body = TextArea(80, 20, "I think the app could be improved with…") body.delegate = self email = TextArea(80, 1.1, "Optional: email (if you want a reply)") + debugProfile = NSButton(checkboxWithTitle: "Send debug profile", target: nil, action: nil) + debugProfile.state = .on let view = GridView.make([ [header], [body], [email], + [debugProfile], [buttons], ]) - view.cell(atColumnIndex: 0, rowIndex: 3).xPlacement = .trailing - view.fit() + view.cell(atColumnIndex: 0, rowIndex: 4).xPlacement = .trailing setContentSize(view.fittingSize) contentView = view } @@ -70,24 +72,40 @@ class FeedbackWindow: NSWindow, NSTextViewDelegate { @objc private func sendCallback(senderControl: NSControl) { + URLSession.shared.dataTask(with: prepareRequest(), completionHandler: { data, response, error in + if error != nil || response == nil || (response as! HTTPURLResponse).statusCode != 201 { + debugPrint("HTTP call failed:", response ?? "nil", error ?? "nil") + } + }).resume() + close() + } + + private func prepareRequest() -> URLRequest { var request = URLRequest(url: URL(string: "https://api.github.com/repos/lwouis/alt-tab-macos/issues")!) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") // access token of the alt-tab-macos-bot github account, with scope repo > public_repo - request.addValue("token 6ab65e11bb51e47835fe1f64970b1d7df0341653", forHTTPHeaderField: "Authorization") - let preamble = "_This issue was opened by a bot after a user submitted feedback through the in-app form. Here is what they wrote:_\n\n> " - let emailNote = !email.string.isEmpty ? "\n\nAuthor's email: " + email.string : "" - let parameters: [String: Any] = [ + request.addValue("token 231413d7bf0e6cc533aae851c83dca25afed86bb", forHTTPHeaderField: "Authorization") + request.httpBody = try! JSONSerialization.data(withJSONObject: [ "title": "[In-app feedback]", - "body": preamble + body.string.replacingOccurrences(of: "\n", with: "\n> ") + emailNote - ] - request.httpBody = try! JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted) - URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in - if error != nil || response == nil || (response as! HTTPURLResponse).statusCode != 201 { - debugPrint("HTTP call failed:", response, error) - } - }).resume() - close() + "body": assembleBody() + ]) + return request + } + + private func assembleBody() -> String { + var result = "" + result += "_This issue was opened by a bot after a user submitted feedback through the in-app form._" + if !email.string.isEmpty { + result += "\n\n__From:__ " + email.string + } + result += "\n\n__Message:__" + result += "\n\n> " + body.string.replacingOccurrences(of: "\n", with: "\n> ") + if debugProfile.state == .on { + result += "\n\n__Debug profile:__" + result += "\n\n" + DebugProfile.make() + } + return result } } diff --git a/alt-tab-macos/ui/generic-components/GridView.swift b/alt-tab-macos/ui/generic-components/GridView.swift index 4a5374baf..dc187b569 100644 --- a/alt-tab-macos/ui/generic-components/GridView.swift +++ b/alt-tab-macos/ui/generic-components/GridView.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class GridView { static let padding = CGFloat(20) diff --git a/alt-tab-macos/ui/generic-components/text/TextArea.swift b/alt-tab-macos/ui/generic-components/text/TextArea.swift index ceeb55a7d..568777da7 100644 --- a/alt-tab-macos/ui/generic-components/text/TextArea.swift +++ b/alt-tab-macos/ui/generic-components/text/TextArea.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class TextArea: NSTextView { static let paddingX = CGFloat(5) diff --git a/alt-tab-macos/ui/preferences-window/LabelAndControl.swift b/alt-tab-macos/ui/preferences-window/LabelAndControl.swift index 4c5fc97d8..2cb460750 100644 --- a/alt-tab-macos/ui/preferences-window/LabelAndControl.swift +++ b/alt-tab-macos/ui/preferences-window/LabelAndControl.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class LabelAndControl: NSObject { static var callbackTarget: PreferencesWindow! diff --git a/alt-tab-macos/ui/preferences-window/PreferencesWindow.swift b/alt-tab-macos/ui/preferences-window/PreferencesWindow.swift index b5b3585d1..e9a428627 100644 --- a/alt-tab-macos/ui/preferences-window/PreferencesWindow.swift +++ b/alt-tab-macos/ui/preferences-window/PreferencesWindow.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class PreferencesWindow: NSWindow { var windowCloseRequested = false diff --git a/alt-tab-macos/ui/preferences-window/TabViewController.swift b/alt-tab-macos/ui/preferences-window/TabViewController.swift index c146bb4fb..6e4346248 100644 --- a/alt-tab-macos/ui/preferences-window/TabViewController.swift +++ b/alt-tab-macos/ui/preferences-window/TabViewController.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class TabViewController: NSTabViewController { override func tabView(_ tabView: NSTabView, didSelect tabViewItem: NSTabViewItem?) { diff --git a/alt-tab-macos/ui/preferences-window/TabViewItem.swift b/alt-tab-macos/ui/preferences-window/TabViewItem.swift index 41436804a..b7282c3ba 100644 --- a/alt-tab-macos/ui/preferences-window/TabViewItem.swift +++ b/alt-tab-macos/ui/preferences-window/TabViewItem.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class TabViewItem { static func make(_ label: String, _ imageNAme: NSImage.Name, _ view: NSView) -> NSTabViewItem { diff --git a/alt-tab-macos/ui/preferences-window/tabs/AboutTab.swift b/alt-tab-macos/ui/preferences-window/tabs/AboutTab.swift index 2a6280b09..08f5d8ee0 100644 --- a/alt-tab-macos/ui/preferences-window/tabs/AboutTab.swift +++ b/alt-tab-macos/ui/preferences-window/tabs/AboutTab.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class AboutTab: NSObject { static func make() -> NSTabViewItem { diff --git a/alt-tab-macos/ui/preferences-window/tabs/AppearanceTab.swift b/alt-tab-macos/ui/preferences-window/tabs/AppearanceTab.swift index 6051283a8..41ffaf642 100644 --- a/alt-tab-macos/ui/preferences-window/tabs/AppearanceTab.swift +++ b/alt-tab-macos/ui/preferences-window/tabs/AppearanceTab.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class AppearanceTab { private static let rowHeight = CGFloat(20) diff --git a/alt-tab-macos/ui/preferences-window/tabs/ShortcutsTab.swift b/alt-tab-macos/ui/preferences-window/tabs/ShortcutsTab.swift index 218ac976c..13651d159 100644 --- a/alt-tab-macos/ui/preferences-window/tabs/ShortcutsTab.swift +++ b/alt-tab-macos/ui/preferences-window/tabs/ShortcutsTab.swift @@ -1,5 +1,4 @@ import Cocoa -import Foundation class ShortcutsTab { private static let rowHeight = CGFloat(20)