Skip to content

Commit

Permalink
Merge pull request #823 from ianyh/0.13.0
Browse files Browse the repository at this point in the history
Amethyst 0.13.0
  • Loading branch information
ianyh authored Apr 11, 2019
2 parents 7881b68 + 82a7083 commit b3f29cd
Show file tree
Hide file tree
Showing 34 changed files with 610 additions and 331 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ language: objective-c
osx_image: xcode10.1
xcode_workspace: Amethyst.xcworkspace
xcode_scheme: Amethyst
before_install:
- bundle install
- pod repo update
script: set -o pipefail && xcodebuild -workspace Amethyst.xcworkspace -scheme Amethyst clean test | bundle exec xcpretty
25 changes: 23 additions & 2 deletions Amethyst.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
4006CF8C1CDFF743004CA512 /* NSScreen+Amethyst.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4006CF8B1CDFF743004CA512 /* NSScreen+Amethyst.swift */; };
4006CF8E1CDFFE90004CA512 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4006CF8D1CDFFE90004CA512 /* AppDelegate.swift */; };
4006CF901CE017BA004CA512 /* UserConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4006CF8F1CE017BA004CA512 /* UserConfiguration.swift */; };
40111CC9223370FD003D20BD /* SIWindow+AmethystTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40111CC8223370FD003D20BD /* SIWindow+AmethystTests.swift */; };
40111CCB22342CC4003D20BD /* DebugPreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40111CCA22342CC4003D20BD /* DebugPreferencesViewController.swift */; };
40111CCD22342CF3003D20BD /* DebugPreferencesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 40111CCC22342CF3003D20BD /* DebugPreferencesViewController.xib */; };
401BC8981CE7E45300F89B3F /* WindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401BC8971CE7E45300F89B3F /* WindowManager.swift */; };
401BC89A1CE8C6AE00F89B3F /* HotKeyManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401BC8991CE8C6AE00F89B3F /* HotKeyManager.swift */; };
401BC89C1CE8D58A00F89B3F /* ShortcutsPreferencesListItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 401BC89B1CE8D58A00F89B3F /* ShortcutsPreferencesListItemView.swift */; };
Expand Down Expand Up @@ -96,6 +99,9 @@
4006CF8B1CDFF743004CA512 /* NSScreen+Amethyst.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSScreen+Amethyst.swift"; sourceTree = "<group>"; };
4006CF8D1CDFFE90004CA512 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
4006CF8F1CE017BA004CA512 /* UserConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserConfiguration.swift; sourceTree = "<group>"; };
40111CC8223370FD003D20BD /* SIWindow+AmethystTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SIWindow+AmethystTests.swift"; sourceTree = "<group>"; };
40111CCA22342CC4003D20BD /* DebugPreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebugPreferencesViewController.swift; sourceTree = "<group>"; };
40111CCC22342CF3003D20BD /* DebugPreferencesViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DebugPreferencesViewController.xib; sourceTree = "<group>"; };
401BC8971CE7E45300F89B3F /* WindowManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WindowManager.swift; sourceTree = "<group>"; };
401BC8991CE8C6AE00F89B3F /* HotKeyManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HotKeyManager.swift; path = ../Events/HotKeyManager.swift; sourceTree = "<group>"; };
401BC89B1CE8D58A00F89B3F /* ShortcutsPreferencesListItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShortcutsPreferencesListItemView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -184,6 +190,8 @@
4008E724190C4D9D0049E2F6 /* Preferences */ = {
isa = PBXGroup;
children = (
40111CCA22342CC4003D20BD /* DebugPreferencesViewController.swift */,
40111CCC22342CF3003D20BD /* DebugPreferencesViewController.xib */,
40AF71DB20BB401400F58EA9 /* FloatingPreferencesViewController.swift */,
40AF71DC20BB401400F58EA9 /* FloatingPreferencesViewController.xib */,
401BC8A31CE8DB0800F89B3F /* GeneralPreferencesViewController.swift */,
Expand All @@ -196,6 +204,14 @@
path = Preferences;
sourceTree = "<group>";
};
40111CC7223370E1003D20BD /* Categories */ = {
isa = PBXGroup;
children = (
40111CC8223370FD003D20BD /* SIWindow+AmethystTests.swift */,
);
path = Categories;
sourceTree = "<group>";
};
401BC8AA1CE8F82700F89B3F /* Managers */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -355,6 +371,7 @@
40D95B481C6E2ED800AAF433 /* AmethystTests */ = {
isa = PBXGroup;
children = (
40111CC7223370E1003D20BD /* Categories */,
4085824A1EA673950075A2C3 /* Managers */,
404BE9CF1CFBDEFD00D6C537 /* Layout */,
401BC8AB1CE8F84500F89B3F /* Preferences */,
Expand Down Expand Up @@ -451,6 +468,7 @@
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
);
mainGroup = 402DB6D51742E41A00D1C936;
Expand All @@ -470,6 +488,7 @@
buildActionMask = 2147483647;
files = (
4058C47A1C54113D00B19D26 /* GeneralPreferencesViewController.xib in Resources */,
40111CCD22342CF3003D20BD /* DebugPreferencesViewController.xib in Resources */,
402DB6EC1742E41A00D1C936 /* InfoPlist.strings in Resources */,
402DB6F21742E41A00D1C936 /* Credits.rtf in Resources */,
40AF71DA20BB348300F58EA9 /* Images.xcassets in Resources */,
Expand Down Expand Up @@ -589,29 +608,29 @@
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Amethyst/Pods-Amethyst-frameworks.sh",
"${BUILT_PRODUCTS_DIR}/Cartography/Cartography.framework",
"${BUILT_PRODUCTS_DIR}/Log/Log.framework",
"${BUILT_PRODUCTS_DIR}/LoginServiceKit/LoginServiceKit.framework",
"${BUILT_PRODUCTS_DIR}/MASShortcut/MASShortcut.framework",
"${BUILT_PRODUCTS_DIR}/RxCocoa/RxCocoa.framework",
"${BUILT_PRODUCTS_DIR}/RxSwift/RxSwift.framework",
"${BUILT_PRODUCTS_DIR}/RxSwiftExt/RxSwiftExt.framework",
"${BUILT_PRODUCTS_DIR}/Silica/Silica.framework",
"${PODS_ROOT}/Sparkle/Sparkle.framework",
"${BUILT_PRODUCTS_DIR}/SwiftyBeaver/SwiftyBeaver.framework",
"${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework",
);
name = "[CP] Embed Pods Frameworks";
outputFileListPaths = (
);
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cartography.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Log.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/LoginServiceKit.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MASShortcut.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxCocoa.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwift.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/RxSwiftExt.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Silica.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Sparkle.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyBeaver.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework",
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down Expand Up @@ -679,6 +698,7 @@
401BC8BA1CE9319500F89B3F /* FocusFollowsMouseManager.swift in Sources */,
40C1357C1F202AEE00FF9FA7 /* PreferencesWindow.swift in Sources */,
4062AD351C1FA62500DB612B /* WideLayout.swift in Sources */,
40111CCB22342CC4003D20BD /* DebugPreferencesViewController.swift in Sources */,
401BC8B81CE9279E00F89B3F /* WindowModifier.swift in Sources */,
4062AD2D1C1F9B8B00DB612B /* FullscreenLayout.swift in Sources */,
1A4B46EB20AA7717003D5110 /* NSTableView+Amethyst.swift in Sources */,
Expand All @@ -689,6 +709,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
40111CC9223370FD003D20BD /* SIWindow+AmethystTests.swift in Sources */,
401BC8AE1CE8FD4700F89B3F /* UserConfigurationTests.swift in Sources */,
404BE9D11CFBDF1900D6C537 /* BinarySpacePartitioningLayoutTests.swift in Sources */,
4085824C1EA673AE0075A2C3 /* HotKeyManagerTests.swift in Sources */,
Expand Down
4 changes: 2 additions & 2 deletions Amethyst/Amethyst-Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>0.12.3</string>
<string>0.13.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>68</string>
<string>70</string>
<key>Fabric</key>
<dict>
<key>Kits</key>
Expand Down
10 changes: 3 additions & 7 deletions Amethyst/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import LoginServiceKit
import RxCocoa
import RxSwift
import Sparkle
import SwiftyBeaver

final class AppDelegate: NSObject, NSApplicationDelegate {
@IBOutlet var preferencesWindowController: PreferencesWindowController?
Expand All @@ -28,17 +29,12 @@ final class AppDelegate: NSObject, NSApplicationDelegate {
private var isFirstLaunch = true

func applicationDidFinishLaunching(_ notification: Notification) {
if ProcessInfo.processInfo.arguments.index(of: "--log") == nil {
log.minLevel = .warning
} else {
log.minLevel = .trace
}

#if DEBUG
log.minLevel = .trace
log.addDestination(ConsoleDestination())
#endif

log.info("Logging is enabled")
log.debug("Debug logging is enabled")

UserConfiguration.shared.delegate = self
UserConfiguration.shared.load()
Expand Down
5 changes: 4 additions & 1 deletion Amethyst/Categories/SIApplication+Amethyst.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import Foundation
import Silica

extension SIApplication {

func windowWithTitleShouldFloat(_ windowTitle: String) -> Bool {
guard let runningApplication = NSRunningApplication(processIdentifier: processIdentifier()) else {
return true
}

return UserConfiguration.shared.runningApplication(runningApplication, shouldFloatWindowWithTitle: windowTitle)
}

func observe(notification: String, with accessibilityElement: SIAccessibilityElement, handler: @escaping SIAXNotificationHandler) -> Bool {
return observeNotification(notification as CFString, with: accessibilityElement, handler: handler)
}
}
47 changes: 29 additions & 18 deletions Amethyst/Categories/SIWindow+Amethyst.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ import ApplicationServices
import Foundation
import Silica

extension CGRect {
func approximatelyEqual(to otherRect: CGRect, within tolerance: CGRect) -> Bool {
return abs(origin.x - otherRect.origin.x) < tolerance.origin.x &&
abs(origin.y - otherRect.origin.y) < tolerance.origin.y &&
abs(width - otherRect.width) < tolerance.width &&
abs(height - otherRect.height) < tolerance.height
}
}

extension SIWindow {
// convert SIWindow objects to CGWindowIDs.
// additionally, return the full set of window descriptions (which is unsorted and may contain extra windows)
Expand Down Expand Up @@ -50,14 +59,12 @@ extension SIWindow {
static func topWindowForScreenAtPoint(_ point: CGPoint, withWindows windows: [SIWindow]) -> SIWindow? {
let (ids, maybeWindowDescriptions) = windowInformation(windows)
guard let windowDescriptions = maybeWindowDescriptions, !windowDescriptions.isEmpty else {
log.debug("nothing")
return nil
}

let windowsAtPoint = onScreenWindowsAtPoint(point, withIDs: ids, withDescriptions: windowDescriptions)

guard !windowsAtPoint.isEmpty else {
log.debug("no windows at point")
return nil
}

Expand Down Expand Up @@ -112,38 +119,42 @@ extension SIWindow {

// find a window based on its window description within an array of SIWindow objects
static func windowInWindows(_ windows: [SIWindow], withCGWindowDescription windowDescription: [String: AnyObject]) -> SIWindow? {
for window in windows {
guard
let windowOwnerProcessIdentifier = windowDescription[kCGWindowOwnerPID as String] as? NSNumber, windowOwnerProcessIdentifier.int32Value == window.processIdentifier()
else {
continue
let potentialWindows = windows.filter {
guard let windowOwnerProcessIdentifier = windowDescription[kCGWindowOwnerPID as String] as? NSNumber else {
return false
}

guard windowOwnerProcessIdentifier.int32Value == $0.processIdentifier() else {
return false
}

guard let boundsDictionary = windowDescription[kCGWindowBounds as String] as? [String: Any] else {
continue
return false
}

let windowFrame = CGRect(dictionaryRepresentation: boundsDictionary as CFDictionary)!

guard windowFrame.equalTo(window.frame()) else {
continue
guard windowFrame.equalTo($0.frame()) else {
return false
}

return true
}

guard potentialWindows.count > 1 else {
return potentialWindows.first
}

return potentialWindows.first {
guard let describedTitle = windowDescription[kCGWindowName as String] as? String else {
continue
return false
}

let describedOwner = windowDescription[kCGWindowOwnerName as String] as? String
let describedOwnedTitle = describedOwner.flatMap { "\(describedTitle) - \($0)" }

guard describedTitle == window.title() || describedOwnedTitle == window.title() else {
continue
}

return window
return describedTitle == $0.title() || describedOwnedTitle == $0.title()
}

return nil
}

// return an array of dictionaries of window information for all windows relative to windowID
Expand Down
2 changes: 2 additions & 0 deletions Amethyst/Layout/BinarySpacePartitioningLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,8 @@ final class BinarySpacePartitioningLayout: Layout {
static var layoutName: String { return "Binary Space Partitioning" }
static var layoutKey: String { return "bsp" }

var layoutDescription: String { return "\(lastKnownFocusedWindowID.debugDescription)" }

let windowActivityCache: WindowActivityCache

fileprivate var rootNode = TreeNode()
Expand Down
8 changes: 3 additions & 5 deletions Amethyst/Layout/ColumnLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,13 @@ final class ColumnReflowOperation: ReflowOperation {
}
}

final class ColumnLayout: Layout {
final class ColumnLayout: PanedLayout {
static var layoutName: String { return "Column" }
static var layoutKey: String { return "column" }

let windowActivityCache: WindowActivityCache
fileprivate var mainPaneCount: Int = 1
fileprivate(set) var mainPaneRatio: CGFloat = 0.5
private(set) var mainPaneCount: Int = 1
private(set) var mainPaneRatio: CGFloat = 0.5

init(windowActivityCache: WindowActivityCache) {
self.windowActivityCache = windowActivityCache
Expand All @@ -76,9 +76,7 @@ final class ColumnLayout: Layout {
func reflow(_ windows: [SIWindow], on screen: NSScreen) -> ReflowOperation? {
return ColumnReflowOperation(screen: screen, windows: windows, layout: self, frameAssigner: self)
}
}

extension ColumnLayout: PanedLayout {
func recommendMainPaneRawRatio(rawRatio: CGFloat) {
mainPaneRatio = rawRatio
}
Expand Down
2 changes: 2 additions & 0 deletions Amethyst/Layout/FloatingLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ final class FloatingLayout: Layout {
static var layoutName: String { return "Floating" }
static var layoutKey: String { return "floating" }

var layoutDescription: String { return "" }

let windowActivityCache: WindowActivityCache

init(windowActivityCache: WindowActivityCache) {
Expand Down
2 changes: 2 additions & 0 deletions Amethyst/Layout/FullscreenLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ final class FullscreenLayout: Layout {
static var layoutName: String { return "Fullscreen" }
static var layoutKey: String { return "fullscreen" }

var layoutDescription: String { return "" }

let windowActivityCache: WindowActivityCache

init(windowActivityCache: WindowActivityCache) {
Expand Down
13 changes: 10 additions & 3 deletions Amethyst/Layout/Layout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ extension FrameAssigner {
}

for frameAssignment in frameAssignments {
log.debug("Frame Assignment: \(frameAssignment)")
// log.debug("Frame Assignment: \(frameAssignment)")
frameAssignment.perform()
}
}
Expand Down Expand Up @@ -237,6 +237,8 @@ protocol Layout {
static var layoutName: String { get }
static var layoutKey: String { get }

var layoutDescription: String { get }

var windowActivityCache: WindowActivityCache { get }

init(windowActivityCache: WindowActivityCache)
Expand All @@ -258,8 +260,9 @@ extension Layout {
}
}

protocol PanedLayout {
protocol PanedLayout: Layout {
var mainPaneRatio: CGFloat { get }
var mainPaneCount: Int { get }
func recommendMainPaneRawRatio(rawRatio: CGFloat)
func shrinkMainPane()
func expandMainPane()
Expand All @@ -268,6 +271,10 @@ protocol PanedLayout {
}

extension PanedLayout {
var layoutDescription: String {
return "(\(mainPaneRatio), \(mainPaneCount))"
}

func recommendMainPaneRatio(_ ratio: CGFloat) {
guard 0 <= ratio && ratio <= 1 else {
log.warning("tried to setMainPaneRatio out of range [0-1]: \(ratio)")
Expand All @@ -285,7 +292,7 @@ extension PanedLayout {
}
}

protocol StatefulLayout {
protocol StatefulLayout: Layout {
func updateWithChange(_ windowChange: WindowChange)
func nextWindowIDCounterClockwise() -> CGWindowID?
func nextWindowIDClockwise() -> CGWindowID?
Expand Down
Loading

0 comments on commit b3f29cd

Please sign in to comment.